From 4e41eb515b5e01253ce05f32d732635f8c6015f3 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Wed, 15 Jan 2014 20:55:29 +0100 Subject: [PATCH] Changed the JsonParser template parameter to be the max number of tokens instead of the number of bytes --- JsonParser.h | 34 +++++++++++++++---- README.md | 20 +++++------ .../JsonParserExample/JsonParserExample.ino | 4 +-- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/JsonParser.h b/JsonParser.h index 8b766b53..b977befd 100644 --- a/JsonParser.h +++ b/JsonParser.h @@ -9,16 +9,41 @@ #include "JsonHashTable.h" #include "JsonArray.h" -template // SIZE of the parser in bytes (128, 256 or more are recommended) +/* +* The JSON parser. +* +* You need to specifiy the number of token to be allocated for that parser. +* Values from 16 to 32 are recommended. +* The parser size will be MAX_TOKEN*8 bytes. +* Don't forget that the memory size of standard Arduino board is only 2KB +* +* CAUTION: JsonArray and JsonHashTable contain pointers to tokens of the +* JsonParser, so they need the JsonParser to be in memory to work. +* As a result, you must not create JsonArray and JsonHashTable that have a +* longer life that the JsonParser. +*/ +template class JsonParser { public: + /* + * Parse the JSON string and return a array. + * + * The content of the string may be altered to add '\0' at the + * end of string tokens + */ JsonArray parseArray(char* json) { return JsonArray(json, parse(json)); } + /* + * Parse the JSON string and return a array. + * + * The content of the string may be altered to add '\0' at the + * end of string tokens + */ JsonHashTable parseHashTable(char* json) { return JsonHashTable(json, parse(json)); @@ -31,16 +56,13 @@ private: jsmn_parser parser; jsmn_init(&parser); - jsmntok_t* tokens = (jsmntok_t*) buffer; - int maxTokenCount = SIZE / sizeof(jsmntok_t); - - if (JSMN_SUCCESS != jsmn_parse(&parser, json, tokens, maxTokenCount)) + if (JSMN_SUCCESS != jsmn_parse(&parser, json, tokens, MAX_TOKENS)) return 0; return tokens; } - char buffer[SIZE]; + jsmntok_t tokens[MAX_TOKENS]; }; #endif diff --git a/README.md b/README.md index f0d0ff98..2fb835b7 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ It has been written with Arduino in mind, but it isn't linked to Arduino librari char* json = "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}"; - JsonParser<256> parser; + JsonParser<32> parser; JsonHashTable hashTable = parser.parseHashTable(json); @@ -43,20 +43,20 @@ Just add the following line on the to of your `.ino` file: ### 3. Create a parser -To extract data from the JSON string, you need to instanciate a `JsonParser`, and specify the number of byte your allocate for the parser itself: +To extract data from the JSON string, you need to create a `JsonParser`, and specify the number of token you allocate for the parser itself: - JsonParser<128> parser; + JsonParser<32> parser; -> #### How to choose the size ? +> #### How to choose the number of tokens ? -> The more bytes you give to the parser, the more complex the JSON can be, so if you have free space on your stack you should increase the size of the parser. -> **A size from 128 to 512 bytes is usually good.** +> First you need to know exactly what a token is. A token is an element af the JSON object: either a key, a value, an hash-table or an array. +> As an example the `char* json` on the top of this page contains 12 tokens (don't forget to count 1 for the whole object and 1 more for the array itself). -> Behind the scenes, all these bytes are used to store *jsmn* tokens. -> A token is 8 bytes long, so 128 to 512, allows to parse from 16 to 64 tokens. -> It may seem small but it's very descent for a processor with only 2KB of RAM, you won't get better results with other parsers. +> The more tokens you allocate, the more complex the JSON can be, but also the more memory will be occupied. +> Each token takes 8 bytes, so `sizeof(JsonParser<32>)` is 256 bytes which is quite big in an Arduino with only 2KB of RAM. +> Don't forget that you also have to store the JSON string in memory and it's probably big. -> As an example the `char* json` on the top of this page requires 12 tokens, so 96 bytes would be enough. +> 32 tokens may seem small but it's very descent for an 8-bit processor, you wouldn't get better results with other JSON libraries. ### 4. Extract data diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index b49fb07d..104b68a5 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -9,7 +9,7 @@ void ParseAnObject() { char* json = "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}"; - JsonParser<256> parser; + JsonParser<32> parser; Serial.print("Parse "); Serial.println(json); @@ -49,7 +49,7 @@ void ParseAnArray() { char* json = "[[1.2,3.4],[5.6,7.8]]"; - JsonParser<256> parser; + JsonParser<32> parser; Serial.print("Parse "); Serial.println(json);