diff --git a/JsonParser/JsonArray.cpp b/JsonParser/JsonArray.cpp deleted file mode 100644 index 342f0fb8..00000000 --- a/JsonParser/JsonArray.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "JsonArray.h" -#include "JsonObject.h" - -using namespace ArduinoJson::Parser; - -DEPRECATED JsonObject JsonArray::getHashTable(int index) -{ - return operator[](index); -} \ No newline at end of file diff --git a/JsonParser/JsonArray.h b/JsonParser/JsonArray.h deleted file mode 100644 index ba5bae55..00000000 --- a/JsonParser/JsonArray.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Arduino JSON library - * Benoit Blanchon 2014 - MIT License - */ - -#pragma once - -#include "JsonValue.h" -#include "JsonArrayIterator.h" - -namespace ArduinoJson -{ - namespace Parser - { - class JsonObject; - - // A JSON array - class JsonArray : JsonValue - { - public: - - // Create an invalid array - JsonArray() - { - } - - // Convert a JsonValue into a JsonArray - JsonArray(JsonValue value) - : JsonValue(value) - { - } - - // Tell if the array is valid - bool success() - { - return isArray(); - } - - // Get the JsonValue at specified index - JsonValue operator[](int index) - { - return JsonValue::operator[](index); - } - - // Get the size of the array - int size() - { - return isArray() ? childrenCount() : 0; - } - - // Get an iterator pointing to the beginning of the array - JsonArrayIterator begin() - { - return isArray() ? firstChild() : null(); - } - - // Gets an iterator pointing to the end of the array - JsonArrayIterator end() - { - return isArray() ? nextSibling() : null(); - } - - // Obsolete: Use size() instead - DEPRECATED int getLength() - { - return size(); - } - - // Obsolete: Use operator[] instead - DEPRECATED JsonArray getArray(int index) - { - return operator[](index); - } - - // Obsolete: Use operator[] instead - DEPRECATED bool getBool(int index) - { - return operator[](index); - } - - // Obsolete: Use operator[] instead - DEPRECATED double getDouble(int index) - { - return operator[](index); - } - - // Obsolete: Use operator[] instead - DEPRECATED JsonObject getHashTable(int index); - - // Obsolete: Use operator[] instead - DEPRECATED long getLong(int index) - { - return operator[](index); - } - - // Obsolete: Use operator[] instead - DEPRECATED char* getString(int index) - { - return operator[](index); - } - }; - } -} \ No newline at end of file diff --git a/JsonParser/JsonArrayIterator.h b/JsonParser/JsonArrayIterator.h deleted file mode 100644 index 9eb0725e..00000000 --- a/JsonParser/JsonArrayIterator.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#pragma once - -#include "JsonValue.h" -#include "JsonToken.h" - -namespace ArduinoJson -{ - namespace Parser - { - // An iterator for JsonArray - class JsonArrayIterator : JsonToken - { - public: - - // Create an iterator pointing at the specified JsonToken - JsonArrayIterator(JsonToken token) - : JsonToken(token) - { - - } - - // Move iterator forward - void operator++() - { - *this = JsonArrayIterator(nextSibling()); - } - - // Get the value pointed by the iterator - JsonValue operator*() const - { - return JsonValue(*this); - } - - // Test iterator equality - bool operator!= (const JsonArrayIterator& other) const - { - return JsonToken::operator!=(other); - } - }; - } -} \ No newline at end of file diff --git a/JsonParser/JsonObject.cpp b/JsonParser/JsonObject.cpp deleted file mode 100644 index 22453f32..00000000 --- a/JsonParser/JsonObject.cpp +++ /dev/null @@ -1,15 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "JsonArray.h" -#include "JsonObject.h" -#include "JsonValue.h" - -using namespace ArduinoJson::Parser; - -DEPRECATED JsonArray JsonObject::getArray(const char* key) -{ - return operator[](key); -} \ No newline at end of file diff --git a/JsonParser/JsonObject.h b/JsonParser/JsonObject.h deleted file mode 100644 index c6ab8aec..00000000 --- a/JsonParser/JsonObject.h +++ /dev/null @@ -1,102 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#pragma once - -#include "JsonValue.h" -#include "JsonObjectIterator.h" - -namespace ArduinoJson -{ - namespace Parser - { - class JsonArray; - - // A JSON Object (ie hash-table/dictionary) - class JsonObject : JsonValue - { - public: - - // Create an invalid JsonObject - JsonObject() - { - - } - - // Convert a JsonValue into a JsonObject - JsonObject(JsonValue value) - : JsonValue(value) - { - - } - - // Tell if the object is valid - bool success() - { - return isObject(); - } - - // Get the value associated with the specified key. - JsonValue operator[](const char* key) - { - return JsonValue::operator[](key); - } - - // Tell if the specified key exists in the object. - bool containsKey(const char* key) - { - return operator[](key).success(); - } - - // Get an iterator pointing at the beginning of the object - JsonObjectIterator begin() - { - return isObject() ? firstChild() : null(); - } - - // Get an iterator pointing at the end of the object - JsonObjectIterator end() - { - return isObject() ? nextSibling() : null(); - } - - // Obsolete: Use operator[] instead - DEPRECATED JsonArray getArray(const char* key); - - // Obsolete: Use operator[] instead - DEPRECATED bool getBool(const char* key) - { - return operator[](key); - } - - // Obsolete: Use operator[] instead - DEPRECATED double getDouble(const char* key) - { - return operator[](key); - } - - // Obsolete: Use operator[] instead - DEPRECATED JsonObject getHashTable(const char* key) - { - return operator[](key); - } - - // Obsolete: Use operator[] instead - DEPRECATED long getLong(const char* key) - { - return operator[](key); - } - - // Obsolete: Use operator[] instead - DEPRECATED char* getString(const char* key) - { - return operator[](key); - } - }; - - // Obsolete: Use JsonObject instead - DEPRECATED typedef JsonObject JsonHashTable; - } -} \ No newline at end of file diff --git a/JsonParser/JsonObjectIterator.h b/JsonParser/JsonObjectIterator.h deleted file mode 100644 index d3c1367b..00000000 --- a/JsonParser/JsonObjectIterator.h +++ /dev/null @@ -1,58 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#pragma once - -#include "JsonValue.h" -#include "JsonPair.h" -#include "JsonToken.h" - -namespace ArduinoJson -{ - namespace Parser - { - // An iterator for JsonObject - class JsonObjectIterator : JsonToken - { - public: - - // Create an iterator pointing at the specified token - JsonObjectIterator(JsonToken token) - : JsonToken(token) - { - } - - // Move to the next JsonPair - void operator++() - { - *this = JsonObjectIterator(nextSibling().nextSibling()); - } - - // Get the JsonPair pointed by the iterator - JsonPair operator*() const - { - return JsonPair(*this); - } - - // Test iterator equality - bool operator!= (const JsonObjectIterator& other) const - { - return JsonToken::operator!=(other); - } - - // Get the key of the JsonPair pointed by the iterator - const char* key() const - { - return operator*().key(); - } - - // Get the key of the JsonPair pointed by the iterator - JsonValue value() const - { - return operator*().value(); - } - }; - } -} \ No newline at end of file diff --git a/JsonParser/JsonPair.h b/JsonParser/JsonPair.h deleted file mode 100644 index 2f8d8732..00000000 --- a/JsonParser/JsonPair.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#pragma once - -#include "JsonValue.h" - -namespace ArduinoJson -{ - namespace Parser - { - // A JSON key-value pair, as a part of a JSON object - class JsonPair : JsonToken - { - public: - // Convert a JsonToken to a JsonPair - JsonPair(JsonToken token) - : JsonToken(token) - { - } - - // Get the key - const char* key() - { - return getText(); - } - - // Get the value - JsonValue value() - { - return nextSibling(); - } - }; - } -} \ No newline at end of file diff --git a/JsonParser/JsonParser.h b/JsonParser/JsonParser.h deleted file mode 100644 index d2c0ffe3..00000000 --- a/JsonParser/JsonParser.h +++ /dev/null @@ -1,35 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#pragma once - -#include "JsonParserBase.h" - -namespace ArduinoJson -{ - namespace Parser - { - // The JSON parser. - // - // You need to specifiy the number of token to be allocated for that parser. - // - // CAUTION: JsonArray, JsonObject and JsonValue 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, JsonObject or JsonValue that have a - // longer life that the JsonParser. - template - class JsonParser : public JsonParserBase - { - public: - JsonParser() - : JsonParserBase(tokens, MAX_TOKENS) - { - } - - private: - jsmntok_t tokens[MAX_TOKENS]; - }; - } -} \ No newline at end of file diff --git a/JsonParser/JsonParserBase.cpp b/JsonParser/JsonParserBase.cpp deleted file mode 100644 index 8263d8cc..00000000 --- a/JsonParser/JsonParserBase.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "JsonParserBase.h" -#include "JsonToken.h" - -using namespace ArduinoJson::Parser; - -JsonValue JsonParserBase::parse(char* json) -{ - jsmn_parser parser; - jsmn_init(&parser); - - if (JSMN_SUCCESS != jsmn_parse(&parser, json, tokens, maxTokens)) - return JsonToken::null(); - - return JsonToken(json, tokens); -} diff --git a/JsonParser/JsonParserBase.h b/JsonParser/JsonParserBase.h deleted file mode 100644 index 8f6418af..00000000 --- a/JsonParser/JsonParserBase.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#pragma once - -#include "JsonArray.h" -#include "JsonObject.h" - -namespace ArduinoJson -{ - namespace Parser - { - // Base class for the JSON parser, in case you want to provide your own buffer - class JsonParserBase - { - public: - - // Create a JSON parser using the provided buffer - JsonParserBase(jsmntok_t* tokens, int maxTokens) - : tokens(tokens), maxTokens(maxTokens) - { - } - - // 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 - JsonValue parse(char* json); - - // Obsolete: use parse() instead - DEPRECATED JsonArray parseArray(char* json) - { - return parse(json); - } - - // Obsolete: use parse() instead - DEPRECATED JsonObject parseHashTable(char* json) - { - return parse(json); - } - - private: - jsmntok_t* tokens; - int maxTokens; - }; - } -} \ No newline at end of file diff --git a/JsonParser/JsonToken.cpp b/JsonParser/JsonToken.cpp deleted file mode 100644 index 27685e3f..00000000 --- a/JsonParser/JsonToken.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "JsonToken.h" - -using namespace ArduinoJson::Parser; - -char* JsonToken::getText() -{ - char* s = json + token->start; - json[token->end] = 0; - - unescapeString(s); - - return s; -} - -inline void JsonToken::unescapeString(char* s) -{ - char* readPtr = s; - char* writePtr = s; - char c; - - do - { - c = *readPtr++; - - if (c == '\\') - { - c = unescapeChar(*readPtr++); - } - - *writePtr++ = c; - - } while (c != 0); -} - -inline char JsonToken::unescapeChar(char c) -{ - // Optimized for code size on a 8-bit AVR - - const char* p = "b\bf\fn\nr\rt\t"; - - while (true) - { - if (p[0] == 0) return c; - if (p[0] == c) return p[1]; - p += 2; - } -} - -JsonToken JsonToken::nextSibling() const -{ - // start with current token - jsmntok_t* t = token; - - // count the number of token to skip - int yetToVisit = 1; - - // skip all nested tokens - while (yetToVisit) - { - yetToVisit += t->size - 1; - t++; - } - - // build a JsonToken at the new location - return JsonToken(json, t); -} \ No newline at end of file diff --git a/JsonParser/JsonToken.h b/JsonParser/JsonToken.h deleted file mode 100644 index 3733a7cb..00000000 --- a/JsonParser/JsonToken.h +++ /dev/null @@ -1,99 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#pragma once - -#include "jsmn.h" - -namespace ArduinoJson -{ - namespace Parser - { - // A pointer to a JSON token - class JsonToken - { - public: - - // Create a "null" pointer - JsonToken() - : token(0) - { - } - - // Create a pointer to the specified JSON token - JsonToken(char* json, jsmntok_t* token) - : json(json), token(token) - { - } - - // Get content of the JSON token - char* getText(); - - // Get the number of children tokens - int childrenCount() - { - return token->size; - } - - // Get a pointer to the first child of the current token - JsonToken firstChild() const - { - return JsonToken(json, token + 1); - } - - // Get a pointer to the next sibling token (ie skiping the children tokens) - JsonToken nextSibling() const; - - // Test equality - bool operator!=(const JsonToken& other) const - { - return token != other.token; - } - - // Tell if the pointer is "null" - bool isValid() - { - return token != 0; - } - - // Tell if the JSON token is a JSON object - bool isObject() - { - return token != 0 && token->type == JSMN_OBJECT; - } - - // Tell if the JSON token is a JSON array - bool isArray() - { - return token != 0 && token->type == JSMN_ARRAY; - } - - // Tell if the JSON token is a primitive - bool isPrimitive() - { - return token != 0 && token->type == JSMN_PRIMITIVE; - } - - // Tell if the JSON token is a string - bool isString() - { - return token != 0 && token->type == JSMN_STRING; - } - - // Explicit wait to create a "null" JsonToken - static JsonToken null() - { - return JsonToken(); - } - - private: - char* json; - jsmntok_t* token; - - static char unescapeChar(char c); - static void unescapeString(char* s); - }; - } -} \ No newline at end of file diff --git a/JsonParser/JsonValue.cpp b/JsonParser/JsonValue.cpp deleted file mode 100644 index b21ac93d..00000000 --- a/JsonParser/JsonValue.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Arduino JSON library - * Benoit Blanchon 2014 - MIT License - */ - -#include // for strtol, strtod -#include // for strcmp() -#include "JsonArray.h" -#include "JsonObject.h" -#include "JsonValue.h" - -using namespace ArduinoJson::Parser; - -// Convert the JsonValue to a bool. -// Returns false if the JsonValue is not a primitve. -JsonValue::operator bool() -{ - if (!isPrimitive()) return 0; - - char *text = getText(); - - // "true" - if (text[0] == 't') return true; - - // "false" - if (text[0] == 'f') return false; - - // "null" - if (text[0] == 'n') return false; - - // number - return strtol(text, 0, 0) != 0; -} - -// Convert the JsonValue to a floating point value. -// Returns false if the JsonValue is not a number. -JsonValue::operator double() -{ - return isPrimitive() ? strtod(getText(), 0) : 0; -} - -// Convert the JsonValue to a floating point value. -// Returns false if the JsonValue is not a number. -JsonValue::operator long() -{ - return isPrimitive() ? strtol(getText(), 0, 0) : 0; -} - -// Convert the JsonValue to a string. -// Returns 0 if the JsonValue is not a string. -JsonValue::operator char*() -{ - return isString() || isPrimitive() ? getText() : 0; -} - -// Get the nested value at the specified index. -// Returns an invalid JsonValue if the current value is not an array. -JsonValue JsonValue::operator[](int index) -{ - // sanity check - if (index < 0 || !isArray() || index >= childrenCount()) - return null(); - - // skip first token, it's the whole object - JsonToken runningToken = firstChild(); - - // skip all tokens before the specified index - for (int i = 0; i < index; i++) - { - // move forward: current + nested tokens - runningToken = runningToken.nextSibling(); - } - - return runningToken; -} - -// Get the nested value matching the specified index. -// Returns an invalid JsonValue if the current value is not an object. -JsonValue JsonValue::operator[](const char* desiredKey) -{ - // sanity check - if (desiredKey == 0 || !isObject()) - return null(); - - // skip first token, it's the whole object - JsonToken runningToken = firstChild(); - - // scan each keys - for (int i = 0; i < childrenCount() / 2; i++) - { - // get 'key' token string - char* key = runningToken.getText(); - - // move to the 'value' token - runningToken = runningToken.nextSibling(); - - // compare with desired name - if (strcmp(desiredKey, key) == 0) - { - // return the value token that follows the key token - return runningToken; - } - - // skip nested tokens - runningToken = runningToken.nextSibling(); - } - - // nothing found, return NULL - return null(); -} diff --git a/JsonParser/JsonValue.h b/JsonParser/JsonValue.h deleted file mode 100644 index 1a49dfaa..00000000 --- a/JsonParser/JsonValue.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Arduino JSON library - * Benoit Blanchon 2014 - MIT License - */ - -#pragma once - -#include "JsonToken.h" - -#ifndef ARDUINO_JSON_NO_DEPRECATION_WARNING -#ifdef __GNUC__ -#define DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define DEPRECATED __declspec(deprecated) -#endif -#else -#define DEPRECATED -#endif - -namespace ArduinoJson -{ - namespace Parser - { - // A JSON value - // Can be converted to string, double, bool, array or object. - class JsonValue : protected JsonToken - { - public: - - // Create a invalid value - JsonValue() - { - } - - // Convert a JsonToken to a JsonValue - JsonValue(JsonToken token) - : JsonToken(token) - { - } - - // Tell is the JsonValue is valid - bool success() - { - return isValid(); - } - - // Convert the JsonValue to a bool. - // Returns false if the JsonValue is not a primitve. - operator bool(); - - // Convert the JsonValue to a floating point value. - // Returns false if the JsonValue is not a number. - operator double(); - - // Convert the JsonValue to a long integer. - // Returns 0 if the JsonValue is not a number. - operator long(); - - // Convert the JsonValue to a string. - // Returns 0 if the JsonValue is not a string. - operator char*(); - - // Get the nested value at the specified index. - // Returns an invalid JsonValue if the current value is not an array. - JsonValue operator[](int index); - - // Get the nested value matching the specified index. - // Returns an invalid JsonValue if the current value is not an object. - JsonValue operator[](const char* key); - }; - } -} \ No newline at end of file diff --git a/JsonParser/README.md b/JsonParser/README.md deleted file mode 100644 index 0b652800..00000000 --- a/JsonParser/README.md +++ /dev/null @@ -1,250 +0,0 @@ -Arduino JSON library - Parser -============================= - -This library is an thin C++ wrapper around the *jsmn* tokenizer: http://zserge.com/jsmn.html - -It's design to be very lightweight, works without any allocation on the heap (no malloc) and supports nested objects. - -It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project. - - -Features --------- - -* Based on the well-proven [jsmn](http://zserge.com/jsmn.html) tokenizer -* Supports nested objects -* Elegant API, very easy to use -* Fixed memory allocation (no malloc) -* Small footprint -* MIT License - - -Example -------- - - JsonParser<32> parser; - char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; - - JsonObject root = parser.parse(json); - - char* sensor = root["sensor"]; - long time = root["time"]; - double latitude = root["data"][0]; - double longitude = root["data"][1]; - - -How to use ? -------------- - -### 1. Install the library - -Download the library and extract it to: - - /libraries/ArduinoJson - -### 2. Import in your sketch - -Just add the following lines at the top of your `.ino` file: - - #include - - using namespace ArduinoJson::Parser; - -> ##### Having a namespace conflict? -> To be able to use both `ArduinoJson::Generator` and `ArduinoJson::Parser` in the same file, you need to do one of the followings: -> -> * Put the `using` statements into different functions -> * `using namespace ArduinoJson`, then prefix the type names by `Generator::` or `Parser::` -> * Create aliases for the namespaces or the types (C++11 only) - -### 3. Create a parser - -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<32> parser; - -> #### How to choose the number of tokens ? - -> A token is an element of the JSON object: either a key, a value, an object 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). - -> The more tokens you allocate, the more complex the JSON can be, but also the more memory is 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 RAM and it's probably big. - -> 32 tokens may seem small, but it's very decent for an 8-bit processor, you wouldn't get better results with other JSON libraries. - -### 4. Extract data - -To use this library, you need to know beforehand what is the type of data contained in the JSON string, which is very likely. - -The root object has to be either an object (like `{"key":"value"}`) or an array (like `[1,2]`). - -The nested objects can be either arrays, booleans, objects, numbers or strings. -If you need other type, you can get the string value and parse it yourself. - -#### Object - -Consider we have a `char json[]` containing to the following JSON string: - - { - "sensor":"gps", - "time":1351824120, - "data":[48.756080,2.302038] - } - -In this case the string contains a JSON object, so you need to extract a `JsonObject`: - - JsonObject root = parser.parse(json); - -To check if the parsing was successful, you must check: - - if (!root.success()) - { - // Parsing fail: could be an invalid JSON, or too many tokens - } - -And then extract the member you need: - - char* sensor = root["sensor"]; - long time = root["time"]; - double latitude = root["data"][0]; - double longitude = root["data"][1]; - -You can also iterate through the key-value pairs of the object: - - for (JsonObjectIterator i=root.begin(); i!=root.end(); ++i) - { - Serial.println(i.key()); - Serial.println((char*)i.value()); - } - -#### Array - -Consider we have a `char json[]` containing to the following JSON string: - - [ - [ 1.2, 3.4 ], - [ 5.6, 7.8 ] - ] - -In this case the root object of the JSON string is an array, so you need to extract a `JsonArray`: - - JsonArray root = parser.parse(json); - -To check if the parsing was successful, you must check: - - if (!root.success()) - { - // Parsing fail: could be an invalid JSON, or too many tokens - } - -And then extract the content by its index in the array: - - double a = root[0][0]; - double b = root[0][1]; - double c = root[1][0]; - double d = root[1][1]; - -You can also iterate through the key-value pairs of the object: - - for (JsonArrayIterator i=array.begin(); i!=array.end(); ++i) - { - Serial.println((char*)*i); - } - -Common pitfalls ---------------- - -### 1. Not enough tokens - -By design, the library has no way to tell you why `JsonParser::parse()` failed. - -There are basically two reasons why they may fail: - -1. the JSON string is invalid -2. the JSON string contains more tokens that the parser can store - -So, if you are sure the JSON string is correct and you still can't parse it, you should slightly increase the number of token of the parser. - -### 2. Not enough memory - -You may go into unpredictable trouble if you allocate more memory than your processor really has. -It's a very common issue in embedded development. - -To diagnose this, look at every big objects in you code and sum their size to check that they fit in RAM. - -For example, don't do this: - - char json[1024]; // 1 KB - JsonParser<64> parser; // 512 B - -because it may be too big for a processor with only 2 KB: you need free memory to store other variables and the call stack. - -That is why an 8-bit processor is not able to parse long and complex JSON strings. - -### 3. JsonParser not in memory - -To reduce the memory consumption, `JsonValue`, `JsonArray` and `JsonObject` contains pointer to the token that are inside the `JsonParser`. This can only work if the `JsonParser` is still in memory. - -For example, don't do this: - - JsonArray getArray(char* json) - { - JsonParser<16> parser; - return parser.parseArray(parser); - } - -because the local variable `parser` will be *removed* from memory when the function `getArray()` returns, and the pointer inside `JsonArray` will point to an invalid location. - -### 4. JSON string is altered - -This will probably never be an issue, but you need to be aware of this feature. - -When you pass a `char[]` to `JsonParser::parse()`, the content of the string will be altered to add `\0` at the end of the tokens. - -This is because we want functions like `JsonArray::getString()` to return a null-terminating string without any memory allocation. - - -Memory usage ------------- - -Here are the size of the main classes of the library. - -This table is for an 8-bit Arduino, types would be bigger on a 32-bit processor. - -| Type | Size in bytes | -| ------------ | ------------- | -| `Parser` | 4 + 8 x N | -| `JsonArray` | 4 | -| `JsonObject` | 4 | -| `JsonValue` | 4 | - -Code size ---------- - -The sizes have been obtained with Arduino IDE 1.0.5 for a Duemilanove. - -### Minimum setup - -| Function | Size | -| ------------------------------------ | ---- | -| `jsmn_parse()` | 962 | -| `JsonValue::operator[](char const*)` | 218 | -| `JsonParserBase::parse()` | 116 | -| `JsonValue::operator[](int)` | 108 | -| `strcmp()` | 18 | - -### Additional space for integers - -| Function | Size | -| ---------------------------- | ---- | -| `strtol()` | 606 | -| `JsonValue::operator long()` | 94 | - -### Additional space for floating points - -| Function | Size | -| -------------------------------- | ----- | -| `strtod()` | 1369 | -| `JsonValue::operator double()` | 82 | diff --git a/JsonParser/jsmn.cpp b/JsonParser/jsmn.cpp deleted file mode 100644 index 1b918f53..00000000 --- a/JsonParser/jsmn.cpp +++ /dev/null @@ -1,255 +0,0 @@ -#include - -#include "jsmn.h" - -/** - * Allocates a fresh unused token from the token pull. - */ -static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, - jsmntok_t *tokens, size_t num_tokens) { - jsmntok_t *tok; - if (parser->toknext >= num_tokens) { - return NULL; - } - tok = &tokens[parser->toknext++]; - tok->start = tok->end = -1; - tok->size = 0; -#ifdef JSMN_PARENT_LINKS - tok->parent = -1; -#endif - return tok; -} - -/** - * Fills token type and boundaries. - */ -static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type, - int start, int end) { - token->type = type; - token->start = start; - token->end = end; - token->size = 0; -} - -/** - * Fills next available token with JSON primitive. - */ -static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js, - jsmntok_t *tokens, size_t num_tokens) { - jsmntok_t *token; - int start; - - start = parser->pos; - - for (; js[parser->pos] != '\0'; parser->pos++) { - switch (js[parser->pos]) { -#ifndef JSMN_STRICT - /* In strict mode primitive must be followed by "," or "}" or "]" */ - case ':': -#endif - case '\t' : case '\r' : case '\n' : case ' ' : - case ',' : case ']' : case '}' : - goto found; - } - if (js[parser->pos] < 32 || js[parser->pos] >= 127) { - parser->pos = start; - return JSMN_ERROR_INVAL; - } - } -#ifdef JSMN_STRICT - /* In strict mode primitive must be followed by a comma/object/array */ - parser->pos = start; - return JSMN_ERROR_PART; -#endif - -found: - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - parser->pos = start; - return JSMN_ERROR_NOMEM; - } - jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - parser->pos--; - return JSMN_SUCCESS; -} - -/** - * Filsl next token with JSON string. - */ -static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js, - jsmntok_t *tokens, size_t num_tokens) { - jsmntok_t *token; - - int start = parser->pos; - - parser->pos++; - - /* Skip starting quote */ - for (; js[parser->pos] != '\0'; parser->pos++) { - char c = js[parser->pos]; - - /* Quote: end of string */ - if (c == '\"') { - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) { - parser->pos = start; - return JSMN_ERROR_NOMEM; - } - jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - return JSMN_SUCCESS; - } - - /* Backslash: Quoted symbol expected */ - if (c == '\\') { - parser->pos++; - switch (js[parser->pos]) { - /* Allowed escaped symbols */ - case '\"': case '/' : case '\\' : case 'b' : - case 'f' : case 'r' : case 'n' : case 't' : - break; - /* Allows escaped symbol \uXXXX */ - case 'u': - /* TODO */ - break; - /* Unexpected symbol */ - default: - parser->pos = start; - return JSMN_ERROR_INVAL; - } - } - } - parser->pos = start; - return JSMN_ERROR_PART; -} - -/** - * Parse JSON string and fill tokens. - */ -jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens, - unsigned int num_tokens) { - jsmnerr_t r; - int i; - jsmntok_t *token; - - for (; js[parser->pos] != '\0'; parser->pos++) { - char c; - jsmntype_t type; - - c = js[parser->pos]; - switch (c) { - case '{': case '[': - token = jsmn_alloc_token(parser, tokens, num_tokens); - if (token == NULL) - return JSMN_ERROR_NOMEM; - if (parser->toksuper != -1) { - tokens[parser->toksuper].size++; -#ifdef JSMN_PARENT_LINKS - token->parent = parser->toksuper; -#endif - } - token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); - token->start = parser->pos; - parser->toksuper = parser->toknext - 1; - break; - case '}': case ']': - type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); -#ifdef JSMN_PARENT_LINKS - if (parser->toknext < 1) { - return JSMN_ERROR_INVAL; - } - token = &tokens[parser->toknext - 1]; - for (;;) { - if (token->start != -1 && token->end == -1) { - if (token->type != type) { - return JSMN_ERROR_INVAL; - } - token->end = parser->pos + 1; - parser->toksuper = token->parent; - break; - } - if (token->parent == -1) { - break; - } - token = &tokens[token->parent]; - } -#else - for (i = parser->toknext - 1; i >= 0; i--) { - token = &tokens[i]; - if (token->start != -1 && token->end == -1) { - if (token->type != type) { - return JSMN_ERROR_INVAL; - } - parser->toksuper = -1; - token->end = parser->pos + 1; - break; - } - } - /* Error if unmatched closing bracket */ - if (i == -1) return JSMN_ERROR_INVAL; - for (; i >= 0; i--) { - token = &tokens[i]; - if (token->start != -1 && token->end == -1) { - parser->toksuper = i; - break; - } - } -#endif - break; - case '\"': - r = jsmn_parse_string(parser, js, tokens, num_tokens); - if (r < 0) return r; - if (parser->toksuper != -1) - tokens[parser->toksuper].size++; - break; - case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ': - break; -#ifdef JSMN_STRICT - /* In strict mode primitives are: numbers and booleans */ - case '-': case '0': case '1' : case '2': case '3' : case '4': - case '5': case '6': case '7' : case '8': case '9': - case 't': case 'f': case 'n' : -#else - /* In non-strict mode every unquoted value is a primitive */ - default: -#endif - r = jsmn_parse_primitive(parser, js, tokens, num_tokens); - if (r < 0) return r; - if (parser->toksuper != -1) - tokens[parser->toksuper].size++; - break; - -#ifdef JSMN_STRICT - /* Unexpected char in strict mode */ - default: - return JSMN_ERROR_INVAL; -#endif - - } - } - - for (i = parser->toknext - 1; i >= 0; i--) { - /* Unmatched opened object or array */ - if (tokens[i].start != -1 && tokens[i].end == -1) { - return JSMN_ERROR_PART; - } - } - - return JSMN_SUCCESS; -} - -/** - * Creates a new parser based over a given buffer with an array of tokens - * available. - */ -void jsmn_init(jsmn_parser *parser) { - parser->pos = 0; - parser->toknext = 0; - parser->toksuper = -1; -} - diff --git a/JsonParser/jsmn.h b/JsonParser/jsmn.h deleted file mode 100644 index 03b2c1aa..00000000 --- a/JsonParser/jsmn.h +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef __JSMN_H_ -#define __JSMN_H_ - -/** - * JSON type identifier. Basic types are: - * o Object - * o Array - * o String - * o Other primitive: number, boolean (true/false) or null - */ -typedef enum { - JSMN_PRIMITIVE = 0, - JSMN_OBJECT = 1, - JSMN_ARRAY = 2, - JSMN_STRING = 3 -} jsmntype_t; - -typedef enum { - /* Not enough tokens were provided */ - JSMN_ERROR_NOMEM = -1, - /* Invalid character inside JSON string */ - JSMN_ERROR_INVAL = -2, - /* The string is not a full JSON packet, more bytes expected */ - JSMN_ERROR_PART = -3, - /* Everything was fine */ - JSMN_SUCCESS = 0 -} jsmnerr_t; - -/** - * JSON token description. - * @param type type (object, array, string etc.) - * @param start start position in JSON data string - * @param end end position in JSON data string - */ -typedef struct { - jsmntype_t type; - int start; - int end; - int size; -#ifdef JSMN_PARENT_LINKS - int parent; -#endif -} jsmntok_t; - -/** - * JSON parser. Contains an array of token blocks available. Also stores - * the string being parsed now and current position in that string - */ -typedef struct { - unsigned int pos; /* offset in the JSON string */ - int toknext; /* next token to allocate */ - int toksuper; /* superior token node, e.g parent object or array */ -} jsmn_parser; - -/** - * Create JSON parser over an array of tokens - */ -void jsmn_init(jsmn_parser *parser); - -/** - * Run JSON parser. It parses a JSON data string into and array of tokens, each describing - * a single JSON object. - */ -jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, - jsmntok_t *tokens, unsigned int num_tokens); - -#endif /* __JSMN_H_ */ diff --git a/JsonParserTests/GbathreeBug.cpp b/JsonParserTests/GbathreeBug.cpp deleted file mode 100644 index 8499f576..00000000 --- a/JsonParserTests/GbathreeBug.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "CppUnitTest.h" -#include "JsonParser.h" -#include - -using namespace std; -using namespace Microsoft::VisualStudio::CppUnitTestFramework; -using namespace ArduinoJson::Parser; - -namespace ArduinoJsonParserTests -{ - TEST_CLASS(GbathreeBug) - { - char json[1024]; - JsonParser<200> parser; - JsonHashTable root; - - - public: - - TEST_METHOD_INITIALIZE(Initialize) - { - // BUG described here: - // http://forum.arduino.cc/index.php?topic=172578.msg1608219#msg1608219 - strcpy(json, "{ \"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":10000,\"actintensity1\":50,\"actintensity2\":255,\"measintensity\":255,\"calintensity\":255,\"pulses\":[50,50,50],\"act\":[2,1,2,2],\"red\":[2,2,2,2],\"detectors\":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]],\"alta\":[2,2,2,2],\"altb\":[2,2,2,2],\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); - root = parser.parseHashTable(json); - } - - TEST_METHOD(Root) - { - Assert::IsTrue(root.success()); - } - - TEST_METHOD(ProtocolName) - { - string protocol_name = root.getString("protocol_name"); - Assert::AreEqual(string("fluorescence"), protocol_name); - } - - TEST_METHOD(Repeats) - { - Assert::AreEqual(1L, root.getLong("repeats")); - } - - TEST_METHOD(Wait) - { - Assert::AreEqual(0L, root.getLong("wait")); - } - - TEST_METHOD(Measurements) - { - Assert::AreEqual(3L, root.getLong("measurements")); - } - - TEST_METHOD(Meas2_Light) - { - Assert::AreEqual(15L, root.getLong("meas2_light")); - } - - TEST_METHOD(Meas1_Baseline) - { - Assert::AreEqual(0L, root.getLong("meas1_baseline")); - } - - TEST_METHOD(Act_Light) - { - Assert::AreEqual(20L, root.getLong("act_light")); - } - - TEST_METHOD(Pulsesize) - { - Assert::AreEqual(25L, root.getLong("pulsesize")); - } - - TEST_METHOD(Pulsedistance) - { - Assert::AreEqual(10000L, root.getLong("pulsedistance")); - } - - TEST_METHOD(Actintensity1) - { - Assert::AreEqual(50L, root.getLong("actintensity1")); - } - - TEST_METHOD(Actintensity2) - { - Assert::AreEqual(255L, root.getLong("actintensity2")); - } - - TEST_METHOD(Measintensity) - { - Assert::AreEqual(255L, root.getLong("measintensity")); - } - - TEST_METHOD(Calintensity) - { - Assert::AreEqual(255L, root.getLong("calintensity")); - } - - TEST_METHOD(Pulses) - { - // "pulses":[50,50,50] - - JsonArray array = root.getArray("pulses"); - Assert::IsTrue(array.success()); - - Assert::AreEqual(3, array.getLength()); - - for (int i = 0; i < 3; i++) - { - Assert::AreEqual(50L, array.getLong(i)); - } - } - - TEST_METHOD(Act) - { - // "act":[2,1,2,2] - - JsonArray array = root.getArray("act"); - Assert::IsTrue(array.success()); - - Assert::AreEqual(4, array.getLength()); - Assert::AreEqual(2L, array.getLong(0)); - Assert::AreEqual(1L, array.getLong(1)); - Assert::AreEqual(2L, array.getLong(2)); - Assert::AreEqual(2L, array.getLong(3)); - } - - TEST_METHOD(Detectors) - { - // "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]] - - JsonArray array = root.getArray("detectors"); - Assert::IsTrue(array.success()); - Assert::AreEqual(4, array.getLength()); - - for (int i = 0; i < 4; i++) - { - Assert::AreEqual(4, array.getArray(i).getLength()); - - for (int j = 0; j < 4; j++) - Assert::AreEqual(34L, array.getArray(i).getLong(j)); - } - } - - TEST_METHOD(Alta) - { - // alta:[2,2,2,2] - - JsonArray array = root.getArray("alta"); - Assert::IsTrue(array.success()); - - Assert::AreEqual(4, array.getLength()); - - for (int i = 0; i < 4; i++) - { - Assert::AreEqual(2L, array.getLong(i)); - } - } - - TEST_METHOD(Altb) - { - // altb:[2,2,2,2] - - JsonArray array = root.getArray("altb"); - Assert::IsTrue(array.success()); - - Assert::AreEqual(4, array.getLength()); - - for (int i = 0; i < 4; i++) - { - Assert::AreEqual(2L, array.getLong(i)); - } - } - - TEST_METHOD(Measlights) - { - // "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] - - JsonArray array = root.getArray("measlights"); - Assert::IsTrue(array.success()); - Assert::AreEqual(4, array.getLength()); - - for (int i = 0; i < 4; i++) - { - Assert::AreEqual(4, array.getArray(i).getLength()); - - for (int j = 0; j < 4; j++) - Assert::AreEqual(15L, array.getArray(i).getLong(j)); - } - } - - TEST_METHOD(Measlights2) - { - // "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] - - JsonArray array = root.getArray("measlights2"); - Assert::IsTrue(array.success()); - Assert::AreEqual(4, array.getLength()); - - for (int i = 0; i < 4; i++) - { - Assert::AreEqual(4, array.getArray(i).getLength()); - - for (int j = 0; j < 4; j++) - Assert::AreEqual(15L, array.getArray(i).getLong(j)); - } - } - - TEST_METHOD(Altc) - { - // altc:[2,2,2,2] - - JsonArray array = root.getArray("altc"); - Assert::IsTrue(array.success()); - - Assert::AreEqual(4, array.getLength()); - - for (int i = 0; i < 4; i++) - { - Assert::AreEqual(2L, array.getLong(i)); - } - } - - TEST_METHOD(Altd) - { - // altd:[2,2,2,2] - - JsonArray array = root.getArray("altd"); - Assert::IsTrue(array.success()); - - Assert::AreEqual(4, array.getLength()); - - for (int i = 0; i < 4; i++) - { - Assert::AreEqual(2L, array.getLong(i)); - } - } - }; -} \ No newline at end of file diff --git a/JsonParserTests/JsonArrayIteratorTests.cpp b/JsonParserTests/JsonArrayIteratorTests.cpp deleted file mode 100644 index 2e8dec4e..00000000 --- a/JsonParserTests/JsonArrayIteratorTests.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "CppUnitTest.h" -#include "JsonParser.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; -using namespace ArduinoJson::Parser; - -namespace JsonParserTests -{ - TEST_CLASS(JsonArrayIteratorTests) - { - public: - - TEST_METHOD(EmptyJson) - { - char json[] = ""; - JsonParser<1> parser; - - JsonArray a = parser.parse(json); - - int loopCount = 0; - - for (long i : a) - { - loopCount++; - } - - Assert::AreEqual(0, loopCount); - } - - TEST_METHOD(ThreeIntegers) - { - char json [] = "[1,2,3]"; - long expected [] = {1, 2, 3}; - JsonParser<4> parser; - - JsonArray a = parser.parse(json); - - int index = 0; - - for (long i : a) - { - Assert::AreEqual(expected[index++], i); - } - } - - TEST_METHOD(ThreeStrings) - { - char json[] = "[\"1\",\"2\",\"3\"]"; - char* expected[] = {"1", "2", "3"}; - JsonParser<4> parser; - - JsonArray a = parser.parse(json); - - int index = 0; - - for (const char* i : a) - { - Assert::AreEqual(expected[index++], i); - } - } - }; -} \ No newline at end of file diff --git a/JsonParserTests/JsonArrayTests.cpp b/JsonParserTests/JsonArrayTests.cpp deleted file mode 100644 index a9c7721f..00000000 --- a/JsonParserTests/JsonArrayTests.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "CppUnitTest.h" -#include "JsonParser.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; -using namespace ArduinoJson::Parser; - -namespace ArduinoJsonParserTests -{ - TEST_CLASS(JsonArrayTests) - { - JsonArray array; - char json[256]; - jsmntok_t tokens[32]; - JsonParserBase parser = JsonParserBase(tokens, 32); - - public: - - TEST_METHOD(TooFewClosingBrackets) - { - whenInputIs("[[]"); - parseMustFail(); - } - - TEST_METHOD(TooManyClosingBrackets) - { - whenInputIs("[]]"); - parseMustFail(); - } - - TEST_METHOD(EmptyArray) - { - whenInputIs("[]"); - parseMustSucceed(); - lengthMustBe(0); - } - - TEST_METHOD(NotEnoughTokens) - { - setTokenCountTo(2); - - whenInputIs("[1,2]"); - - parseMustFail(); - itemMustNotExist(0); - } - - TEST_METHOD(TwoIntegers) - { - setTokenCountTo(3); - - whenInputIs("[1,2]"); - - parseMustSucceed(); - lengthMustBe(2); - itemMustBe(0, 1L); - itemMustBe(1, 2L); - itemMustNotExist(2); - } - - TEST_METHOD(TwoBooleans) - { - setTokenCountTo(3); - - whenInputIs("[true,false]"); - - parseMustSucceed(); - lengthMustBe(2); - itemMustBe(0, true); - itemMustBe(1, false); - itemMustNotExist(2); - } - - TEST_METHOD(TwoStrings) - { - setTokenCountTo(3); - - whenInputIs("[\"hello\",\"world\"]"); - - parseMustSucceed(); - lengthMustBe(2); - itemMustBe(0, "hello"); - itemMustBe(1, "world"); - itemMustNotExist(2); - } - - TEST_METHOD(TwoDimensionsArray) - { - setTokenCountTo(7); - - whenInputIs("[[1,2],[3,4]]"); - - parseMustSucceed(); - lengthMustBe(2); - itemMustBe(0, 0, 1L); - itemMustBe(0, 1, 2L); - itemMustBe(1, 0, 3L); - itemMustBe(1, 1, 4L); - itemMustNotExist(2); - } - - TEST_METHOD(ThreeDimensionsArray) - { - setTokenCountTo(15); - - whenInputIs("[[[1,2],[3,4]],[[5,6],[7,8]]]"); - - parseMustSucceed(); - lengthMustBe(2); - itemMustBe(0, 0, 0, 1L); - itemMustBe(0, 0, 1, 2L); - itemMustBe(0, 1, 0, 3L); - itemMustBe(0, 1, 1, 4L); - itemMustBe(1, 0, 0, 5L); - itemMustBe(1, 0, 1, 6L); - itemMustBe(1, 1, 0, 7L); - itemMustBe(1, 1, 1, 8L); - itemMustNotExist(2); - } - - private: - - void setTokenCountTo(int n) - { - parser = JsonParserBase(tokens, n); - } - - void whenInputIs(const char* input) - { - strcpy(json, input); - array = parser.parseArray(json); - } - - void parseMustFail() - { - Assert::IsFalse(array.success()); - lengthMustBe(0); - } - - void parseMustSucceed() - { - Assert::IsTrue(array.success()); - } - - void lengthMustBe(int expected) - { - Assert::AreEqual(expected, array.getLength()); - } - - void itemMustBe(int index, long expected) - { - Assert::AreEqual(expected, array.getLong(index)); - } - - void itemMustBe(int index, bool expected) - { - Assert::AreEqual(expected, array.getBool(index)); - } - - void itemMustBe(int index, const char* expected) - { - Assert::AreEqual(expected, array.getString(index)); - } - - void itemMustBe(int index0, int index1, long expected) - { - Assert::AreEqual(expected, array.getArray(index0).getLong(index1)); - } - - void itemMustBe(int index0, int index1, int index2, long expected) - { - Assert::AreEqual(expected, array.getArray(index0).getArray(index1).getLong(index2)); - } - - void itemMustNotExist(int index) - { - Assert::IsFalse(array.getHashTable(index).success()); - Assert::IsFalse(array.getArray(index).success()); - Assert::IsFalse(array.getBool(index)); - Assert::AreEqual(0.0, array.getDouble(index)); - Assert::AreEqual(0L, array.getLong(index)); - Assert::IsNull(array.getString(index)); - } - }; -} \ No newline at end of file diff --git a/JsonParserTests/JsonObjectIteratorTests.cpp b/JsonParserTests/JsonObjectIteratorTests.cpp deleted file mode 100644 index 2a88f504..00000000 --- a/JsonParserTests/JsonObjectIteratorTests.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "CppUnitTest.h" -#include "JsonParser.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; -using namespace ArduinoJson::Parser; - -namespace JsonParserTests -{ - TEST_CLASS(JsonObjectIteratorTests) - { - public: - - TEST_METHOD(EmptyObject) - { - char json [] = "{}"; - JsonParser<1> parser; - - JsonHashTable a = parser.parse(json); - - int loopCount = 0; - - for (auto i : a) - { - loopCount++; - } - - Assert::AreEqual(0, loopCount); - } - - TEST_METHOD(EmptyJson) - { - char json[] = ""; - JsonParser<1> parser; - - JsonHashTable a = parser.parse(json); - - int loopCount = 0; - - for (auto i : a) - { - loopCount++; - } - - Assert::AreEqual(0, loopCount); - } - - TEST_METHOD(ThreeStrings) - { - char json[] = "{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}"; - char* expectedKeys[] = {"key1", "key2", "key3"}; - char* expectedValues[] = {"value1", "value2", "value3"}; - JsonParser<7> parser; - - JsonHashTable a = parser.parse(json); - - int index = 0; - - for (auto i : a) - { - Assert::AreEqual(expectedKeys[index], i.key()); - Assert::AreEqual(expectedValues[index], (const char*) i.value()); - index++; - } - } - }; -} \ No newline at end of file diff --git a/JsonParserTests/JsonObjectTests.cpp b/JsonParserTests/JsonObjectTests.cpp deleted file mode 100644 index 6b0e6be8..00000000 --- a/JsonParserTests/JsonObjectTests.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "CppUnitTest.h" -#include "JsonParser.h" -#include - -using namespace std; -using namespace Microsoft::VisualStudio::CppUnitTestFramework; -using namespace ArduinoJson::Parser; - -namespace ArduinoJsonParserTests -{ - TEST_CLASS(JsonHashTableTests) - { - JsonHashTable hashTable; - JsonArray nestedArray; - char json[256]; - jsmntok_t tokens[32]; - JsonParserBase parser = JsonParserBase(tokens, 32); - - public: - - TEST_METHOD(EmptyHashTable) - { - whenInputIs("{}"); - parseMustSucceed(); - } - - TEST_METHOD(NotEnoughTokens) - { - setTokenCountTo(2); - - whenInputIs("{\"key\":0}"); - - parseMustFail(); - itemMustNotExist("key"); - } - - TEST_METHOD(TwoIntegers) - { - setTokenCountTo(5); - - whenInputIs("{\"key1\":1,\"key2\":2}"); - - parseMustSucceed(); - itemMustBe("key1", 1L); - itemMustBe("key2", 2L); - itemMustNotExist("key3"); - } - - TEST_METHOD(TwoBooleans) - { - setTokenCountTo(5); - - whenInputIs("{\"key1\":true,\"key2\":false}"); - - parseMustSucceed(); - itemMustBe("key1", true); - itemMustBe("key2", false); - itemMustNotExist("key3"); - } - - TEST_METHOD(TwoStrings) - { - setTokenCountTo(5); - - whenInputIs("{\"key1\":\"hello\",\"key2\":\"world\"}"); - - parseMustSucceed(); - itemMustBe("key1", "hello"); - itemMustBe("key2", "world"); - itemMustNotExist("key3"); - } - - TEST_METHOD(TwoNestedArrays) - { - setTokenCountTo(9); - - whenInputIs("{\"key1\":[1,2],\"key2\":[3,4]}"); - parseMustSucceed(); - - itemMustBeAnArray("key1"); - arrayLengthMustBe(2); - arrayItemMustBe(0, 1L); - arrayItemMustBe(1, 2L); - arrayItemMustBe(2, 0L); - - itemMustBeAnArray("key2"); - arrayLengthMustBe(2); - arrayItemMustBe(0, 3L); - arrayItemMustBe(1, 4L); - arrayItemMustBe(2, 0L); - - itemMustNotExist("key3"); - } - - private: - - void setTokenCountTo(int n) - { - parser = JsonParserBase(tokens, n); - } - - void whenInputIs(const char* input) - { - strcpy(json, input); - hashTable = parser.parseHashTable(json); - } - - void parseMustFail() - { - Assert::IsFalse(hashTable.success()); - } - - void parseMustSucceed() - { - Assert::IsTrue(hashTable.success()); - } - - void itemMustBe(const char* key, long expected) - { - Assert::AreEqual(expected, hashTable.getLong(key)); - } - - void itemMustBe(const char* key, bool expected) - { - Assert::AreEqual(expected, hashTable.getBool(key)); - } - - void itemMustBe(const char* key, const char* expected) - { - Assert::AreEqual(expected, hashTable.getString(key)); - } - - void itemMustNotExist(const char* key) - { - Assert::IsFalse(hashTable.containsKey(key)); - Assert::IsFalse(hashTable.getHashTable(key).success()); - Assert::IsFalse(hashTable.getArray(key).success()); - Assert::IsFalse(hashTable.getBool(key)); - Assert::AreEqual(0.0, hashTable.getDouble(key)); - Assert::AreEqual(0L, hashTable.getLong(key)); - Assert::IsNull(hashTable.getString(key)); - } - - void itemMustBeAnArray(const char* key) - { - nestedArray = hashTable.getArray(key); - Assert::IsTrue(nestedArray.success()); - } - - void arrayLengthMustBe(int expected) - { - Assert::AreEqual(expected, nestedArray.getLength()); - } - - void arrayItemMustBe(int index, long expected) - { - Assert::AreEqual(expected, nestedArray.getLong(index)); - } - }; -} \ No newline at end of file diff --git a/JsonParserTests/JsonStringTests.cpp b/JsonParserTests/JsonStringTests.cpp deleted file mode 100644 index 1e5e4fe8..00000000 --- a/JsonParserTests/JsonStringTests.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/* -* Arduino JSON library -* Benoit Blanchon 2014 - MIT License -*/ - -#include "CppUnitTest.h" -#include "JsonParser.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; -using namespace ArduinoJson::Parser; - -namespace ArduinoJsonParserTests -{ - TEST_CLASS(JsonStringTests) - { - const char* actual; - char json[256]; - JsonParser<32> parser; - - public: - - TEST_METHOD(EmptyString) - { - whenInputIs(""); - outputMustBe(0); - } - - TEST_METHOD(JustOneQuote) - { - whenInputIs("\""); - outputMustBe(0); - } - - TEST_METHOD(SimpleString) - { - whenInputIs("\"Hi!\""); - outputMustBe("Hi!"); - } - - TEST_METHOD(EscapedQuote) - { - whenInputIs("\"12\\\"34\""); // ie 12\"34 - outputMustBe("12\"34"); - } - - TEST_METHOD(EscapedReverseSolidus) - { - whenInputIs("\"12\\\\34\""); // ie 12\\34 - outputMustBe("12\\34"); - } - - TEST_METHOD(EscapedSolidus) - { - whenInputIs("\"12\\/34\""); - outputMustBe("12/34"); - } - - TEST_METHOD(EscapedBackspace) - { - whenInputIs("\"12\\b34\""); - outputMustBe("12\b34"); - } - - TEST_METHOD(EscapedFormfeed) - { - whenInputIs("\"12\\f34\""); - outputMustBe("12\f34"); - } - - TEST_METHOD(EscapedNewline) - { - whenInputIs("\"12\\n34\""); - outputMustBe("12\n34"); - } - - TEST_METHOD(EscapedCarriageReturn) - { - whenInputIs("\"12\\r34\""); - outputMustBe("12\r34"); - } - - TEST_METHOD(EscapedTab) - { - whenInputIs("\"12\\t34\""); - outputMustBe("12\t34"); - } - - TEST_METHOD(AllEscapedCharsTogether) - { - whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\""); - outputMustBe("1\"2\\3/4\b5\f6\n7\r8\t9"); - } - - private: - - void whenInputIs(const char* input) - { - strcpy(json, input); - actual = parser.parse(json); - } - - void outputMustBe(const char* expected) - { - Assert::AreEqual(expected, actual); - } - }; -} \ No newline at end of file diff --git a/JsonParserTests/TestHashGenerator.cpp b/JsonParserTests/TestHashGenerator.cpp deleted file mode 100644 index 754e2119..00000000 --- a/JsonParserTests/TestHashGenerator.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "stdafx.h" -#include "CppUnitTest.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -namespace ArduinoJsonParserTests -{ - TEST_CLASS(TestHashGenerator) - { - public: - - TEST_METHOD(TestMethod1) - { - JsonArray<5> arr; - arr.Add(1); - arr.Add("Hi!"); - - JsonHashTable<4> hash; - hash.Add("key1", 1); - hash.Add("key2", "Hello!"); - hash.Add("key3", arr); - } - - }; -} \ No newline at end of file