mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Added StaticJsonDocument and DynamicJsonDocument.
Removed StaticJsonArray and DynamicJsonArray. Removed StaticJsonObject and DynamicJsonObject. Removed StaticJsonVariant and DynamicJsonVariant.
This commit is contained in:
		
							
								
								
									
										14
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -6,9 +6,7 @@ HEAD | ||||
|  | ||||
| * Fixed `JsonBuffer::parse()` not respecting nesting limit correctly (issue #693) | ||||
| * Fixed inconsistencies in nesting level counting (PR #695 from Zhenyu Wu) | ||||
| * Added `DynamicJsonArray` and `StaticJsonArray` | ||||
| * Added `DynamicJsonObject` and `StaticJsonObject` | ||||
| * Added `DynamicJsonVariant` and `StaticJsonVariant` | ||||
| * Added `DynamicJsonDocument` and `StaticJsonDocument` | ||||
| * Added `deserializeJson()` | ||||
| * Added `serializeJson()` and `serializeJsonPretty()` | ||||
| * Added `measureJson()` and `measureJsonPretty()` | ||||
| @@ -37,11 +35,12 @@ HEAD | ||||
| > New code: | ||||
| >  | ||||
| > ```c++ | ||||
| > DynamicJsonObject obj; | ||||
| > JsonError error = deserializeJson(obj, json); | ||||
| > DynamicJsonDocument doc; | ||||
| > JsonError error = deserializeJson(doc, json); | ||||
| > if (error) { | ||||
| >  | ||||
| > } | ||||
| > JsonObject& obj = doc.as<JsonObject>(); | ||||
| > ``` | ||||
| >  | ||||
| > #### Serialization | ||||
| @@ -58,9 +57,10 @@ HEAD | ||||
| > New code: | ||||
| >  | ||||
| > ```c++ | ||||
| > DynamicJsonObject obj; | ||||
| > DynamicJsonDocument obj; | ||||
| > JsonObject& obj = doc.to<JsonObject>(); | ||||
| > obj["key"] = "value"; | ||||
| > serializeJson(obj, Serial); | ||||
| > serializeJson(doc, Serial); | ||||
| > ``` | ||||
|  | ||||
| v5.13.1 | ||||
|   | ||||
							
								
								
									
										11
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								README.md
									
									
									
									
									
								
							| @@ -59,9 +59,10 @@ Here is a program that parses a JSON document with ArduinoJson. | ||||
| ```c++ | ||||
| char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|  | ||||
| DynamicJsonObject root; | ||||
| deserializeJson(root, json); | ||||
| DynamicJsonDocument doc; | ||||
| deserializeJson(doc, json); | ||||
|  | ||||
| JsonObject& root = doc.as<JsonObject>(); | ||||
| const char* sensor = root["sensor"]; | ||||
| long time          = root["time"]; | ||||
| double latitude    = root["data"][0]; | ||||
| @@ -75,7 +76,9 @@ See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_ | ||||
| Here is a program that generates a JSON document with ArduinoJson: | ||||
|  | ||||
| ```c++ | ||||
| DynamicJsonObject root; | ||||
| DynamicJsonDocument doc; | ||||
|  | ||||
| JsonObject& root = doc.to<JsonObject>(); | ||||
| root["sensor"] = "gps"; | ||||
| root["time"] = 1351824120; | ||||
|  | ||||
| @@ -83,7 +86,7 @@ JsonArray& data = root.createNestedArray("data"); | ||||
| data.add(48.756080); | ||||
| data.add(2.302038); | ||||
|  | ||||
| serializeJson(root, Serial); | ||||
| serializeJson(doc, Serial); | ||||
| // This prints: | ||||
| // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||
| ``` | ||||
|   | ||||
| @@ -29,17 +29,19 @@ void loadConfiguration(const char *filename, Config &config) { | ||||
|   // Open file for reading | ||||
|   File file = SD.open(filename); | ||||
|  | ||||
|   // Allocate the memory pool on the stack. | ||||
|   // Don't forget to change the capacity to match your JSON document. | ||||
|   // Allocate the document on the stack. | ||||
|   // Don't forget to change the capacity to match your requirements. | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   StaticJsonObject<512> root; | ||||
|  | ||||
|   // Parse the root object | ||||
|   JsonError error = deserializeJson(root, file); | ||||
|   StaticJsonDocument<512> doc; | ||||
|  | ||||
|   // Deserialize the JSON document | ||||
|   JsonError error = deserializeJson(doc, file); | ||||
|   if (error) | ||||
|     Serial.println(F("Failed to read file, using default configuration")); | ||||
|  | ||||
|   // Get the root object in the document | ||||
|   JsonObject &root = doc.as<JsonObject>(); | ||||
|  | ||||
|   // Copy values from the JsonObject to the Config | ||||
|   config.port = root["port"] | 2731; | ||||
|   strlcpy(config.hostname,                   // <- destination | ||||
| @@ -62,17 +64,20 @@ void saveConfiguration(const char *filename, const Config &config) { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Allocate the memory pool on the stack | ||||
|   // Don't forget to change the capacity to match your JSON document. | ||||
|   // Use https://arduinojson.org/assistant/ to compute the capacity. | ||||
|   StaticJsonObject<256> root; | ||||
|   // Allocate the document on the stack. | ||||
|   // Don't forget to change the capacity to match your requirements. | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   StaticJsonDocument<256> doc; | ||||
|  | ||||
|   // Set the values | ||||
|   // Make our document contain an object | ||||
|   JsonObject &root = doc.to<JsonObject>(); | ||||
|  | ||||
|   // Set the values in the object | ||||
|   root["hostname"] = config.hostname; | ||||
|   root["port"] = config.port; | ||||
|  | ||||
|   // Serialize JSON to file | ||||
|   if (serializeJson(root, file) == 0) { | ||||
|   if (serializeJson(doc, file) == 0) { | ||||
|     Serial.println(F("Failed to write to file")); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -11,17 +11,20 @@ void setup() { | ||||
|   Serial.begin(9600); | ||||
|   while (!Serial) continue; | ||||
|  | ||||
|   // Root JSON object | ||||
|   // The JSON document | ||||
|   // | ||||
|   // Inside the brackets, 200 is the size of the memory pool in bytes. | ||||
|   // Don't forget to change this value to match your JSON document. | ||||
|   // Inside the brackets, 200 is the RAM allocated to this document. | ||||
|   // Don't forget to change this value to match your requirement. | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   StaticJsonObject<200> root; | ||||
|   StaticJsonDocument<200> doc; | ||||
|  | ||||
|   // StaticJsonObject allocates memory on the stack, it can be | ||||
|   // replaced by DynamicJsonObject which allocates in the heap. | ||||
|   // replaced by DynamicJsonDocument which allocates in the heap. | ||||
|   // | ||||
|   // DynamicJsonObject  root(200); | ||||
|   // DynamicJsonDocument  doc(200); | ||||
|  | ||||
|   // Make our document be an object | ||||
|   JsonObject& root = doc.to<JsonObject>(); | ||||
|  | ||||
|   // Add values in the object | ||||
|   // | ||||
| @@ -30,10 +33,8 @@ void setup() { | ||||
|   root["sensor"] = "gps"; | ||||
|   root["time"] = 1351824120; | ||||
|  | ||||
|   // Add a nested array. | ||||
|   // Add an array. | ||||
|   // | ||||
|   // It's also possible to create the array separately and add it to the | ||||
|   // JsonObject but it's less efficient. | ||||
|   JsonArray& data = root.createNestedArray("data"); | ||||
|   data.add(48.756080); | ||||
|   data.add(2.302038); | ||||
|   | ||||
| @@ -70,19 +70,21 @@ void setup() { | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Allocate JsonBuffer | ||||
|   // Allocate the JSON document | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; | ||||
|   DynamicJsonObject root(capacity); | ||||
|   DynamicJsonDocument doc(capacity); | ||||
|  | ||||
|   // Parse JSON object | ||||
|   JsonError error = deserializeJson(root, client); | ||||
|   JsonError error = deserializeJson(doc, client); | ||||
|   if (error) { | ||||
|     Serial.println(F("Parsing failed!")); | ||||
|     Serial.print(F("deserializeJson() failed: ")); | ||||
|     Serial.println(error.c_str()); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Extract values | ||||
|   JsonObject& root = doc.as<JsonObject>(); | ||||
|   Serial.println(F("Response:")); | ||||
|   Serial.println(root["sensor"].as<char*>()); | ||||
|   Serial.println(root["time"].as<char*>()); | ||||
|   | ||||
| @@ -16,12 +16,12 @@ void setup() { | ||||
|   // Inside the brackets, 200 is the size of the memory pool in bytes. | ||||
|   // Don't forget to change this value to match your JSON document. | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   StaticJsonObject<200> root; | ||||
|   StaticJsonDocument<200> doc; | ||||
|  | ||||
|   // StaticJsonObject allocates memory on the stack, it can be | ||||
|   // StaticJsonDocument<N> allocates memory on the stack, it can be | ||||
|   // replaced by DynamicJsonObject which allocates in the heap. | ||||
|   // | ||||
|   // DynamicJsonObject  root(200); | ||||
|   // DynamicJsonObject doc(200); | ||||
|  | ||||
|   // JSON input string. | ||||
|   // | ||||
| @@ -31,23 +31,23 @@ void setup() { | ||||
|   char json[] = | ||||
|       "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|  | ||||
|   // Root of the object tree. | ||||
|   // | ||||
|   // It's a reference to the JsonObject, the actual bytes are inside the | ||||
|   // JsonBuffer with all the other nodes of the object tree. | ||||
|   // Memory is freed when jsonBuffer goes out of scope. | ||||
|   JsonError error = deserializeJson(root, json); | ||||
|   // Deserialize the JSON document | ||||
|   JsonError error = deserializeJson(doc, json); | ||||
|  | ||||
|   // Test if parsing succeeds. | ||||
|   if (error) { | ||||
|     Serial.println("deserializeJson() failed"); | ||||
|     Serial.print(F("deserializeJson() failed: ")); | ||||
|     Serial.println(error.c_str()); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Get the root object in the document | ||||
|   JsonObject& root = doc.as<JsonObject>(); | ||||
|  | ||||
|   // Fetch values. | ||||
|   // | ||||
|   // Most of the time, you can rely on the implicit casts. | ||||
|   // In other case, you can do root["time"].as<long>(); | ||||
|   // In other case, you can do doc["time"].as<long>(); | ||||
|   const char* sensor = root["sensor"]; | ||||
|   long time = root["time"]; | ||||
|   double latitude = root["data"][0]; | ||||
|   | ||||
| @@ -51,9 +51,12 @@ void loop() { | ||||
|   // Read the request (we ignore the content in this example) | ||||
|   while (client.available()) client.read(); | ||||
|  | ||||
|   // Allocate the root JsonObject | ||||
|   // Allocate the JSON document | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   StaticJsonObject<500> root; | ||||
|   StaticJsonDocument<500> doc; | ||||
|  | ||||
|   // Make our document represent an object | ||||
|   JsonObject& root = doc.to<JsonObject>(); | ||||
|  | ||||
|   // Create the "analog" array | ||||
|   JsonArray& analogValues = root.createNestedArray("analog"); | ||||
|   | ||||
| @@ -43,9 +43,12 @@ void setup() { | ||||
| } | ||||
|  | ||||
| void loop() { | ||||
|   // Allocate the root JsonObject | ||||
|   // Allocate the JSON document | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   StaticJsonObject<500> root; | ||||
|   StaticJsonDocument<500> doc; | ||||
|  | ||||
|   // Make our document represent an object | ||||
|   JsonObject& root = doc.to<JsonObject>(); | ||||
|  | ||||
|   // Create the "analog" array | ||||
|   JsonArray& analogValues = root.createNestedArray("analog"); | ||||
|   | ||||
| @@ -12,17 +12,17 @@ void setup() { | ||||
|   Serial.begin(9600); | ||||
|   while (!Serial) continue; | ||||
|  | ||||
|   // Root JSON object | ||||
|   // Allocate the JSON document | ||||
|   // | ||||
|   // Inside the brackets, 200 is the size of the memory pool in bytes. | ||||
|   // Don't forget to change this value to match your JSON document. | ||||
|   // Use arduinojson.org/assistant to compute the capacity. | ||||
|   StaticJsonObject<200> root; | ||||
|   StaticJsonDocument<200> doc; | ||||
|  | ||||
|   // StaticJsonObject allocates memory on the stack, it can be | ||||
|   // replaced by DynamicJsonObject which allocates in the heap. | ||||
|   // | ||||
|   // DynamicJsonObject  root(200); | ||||
|   // DynamicJsonObject doc(200); | ||||
|  | ||||
|   // MessagePack input string. | ||||
|   // | ||||
| @@ -40,23 +40,27 @@ void setup() { | ||||
|   //   "data": [48.75608, 2.302038] | ||||
|   // } | ||||
|  | ||||
|   // Root of the object tree. | ||||
|   // doc of the object tree. | ||||
|   // | ||||
|   // It's a reference to the JsonObject, the actual bytes are inside the | ||||
|   // JsonBuffer with all the other nodes of the object tree. | ||||
|   // Memory is freed when jsonBuffer goes out of scope. | ||||
|   MsgPackError error = deserializeMsgPack(root, input); | ||||
|   MsgPackError error = deserializeMsgPack(doc, input); | ||||
|  | ||||
|   // Test if parsing succeeds. | ||||
|   if (error) { | ||||
|     Serial.println("deserializeMsgPack() failed"); | ||||
|     Serial.print("deserializeMsgPack() failed: "); | ||||
|     Serial.println(error.c_str()); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   // Get the root object in the document | ||||
|   JsonObject& root = doc.as<JsonObject>(); | ||||
|  | ||||
|   // Fetch values. | ||||
|   // | ||||
|   // Most of the time, you can rely on the implicit casts. | ||||
|   // In other case, you can do root["time"].as<long>(); | ||||
|   // In other case, you can do doc["time"].as<long>(); | ||||
|   const char* sensor = root["sensor"]; | ||||
|   long time = root["time"]; | ||||
|   double latitude = root["data"][0]; | ||||
|   | ||||
| @@ -14,33 +14,34 @@ | ||||
| void setup() { | ||||
| #ifdef PROGMEM  // <- check that Flash strings are supported | ||||
|  | ||||
|   DynamicJsonObject root; | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   // You can use a Flash String as your JSON input. | ||||
|   // WARNING: the content of the Flash String will be duplicated in the | ||||
|   // JsonBuffer. | ||||
|   deserializeJson(root, F("{\"sensor\":\"gps\",\"time\":1351824120," | ||||
|   deserializeJson(doc, F("{\"sensor\":\"gps\",\"time\":1351824120," | ||||
|                          "\"data\":[48.756080,2.302038]}")); | ||||
|   JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|   // You can use a Flash String to get an element of a JsonObject | ||||
|   // No duplication is done. | ||||
|   long time = root[F("time")]; | ||||
|   long time = obj[F("time")]; | ||||
|  | ||||
|   // You can use a Flash String to set an element of a JsonObject | ||||
|   // WARNING: the content of the Flash String will be duplicated in the | ||||
|   // JsonBuffer. | ||||
|   root[F("time")] = time; | ||||
|   obj[F("time")] = time; | ||||
|  | ||||
|   // You can set a Flash String to a JsonObject or JsonArray: | ||||
|   // WARNING: the content of the Flash String will be duplicated in the | ||||
|   // JsonBuffer. | ||||
|   root["sensor"] = F("gps"); | ||||
|   obj["sensor"] = F("gps"); | ||||
|  | ||||
|   // It works with RawJson too: | ||||
|   root["sensor"] = RawJson(F("\"gps\"")); | ||||
|   obj["sensor"] = RawJson(F("\"gps\"")); | ||||
|  | ||||
|   // You can compare the content of a JsonVariant to a Flash String | ||||
|   if (root["sensor"] == F("gps")) { | ||||
|   if (obj["sensor"] == F("gps")) { | ||||
|     // ... | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -11,50 +11,51 @@ | ||||
| #include <ArduinoJson.h> | ||||
|  | ||||
| void setup() { | ||||
|   DynamicJsonObject root; | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   // You can use a String as your JSON input. | ||||
|   // WARNING: the content of the String will be duplicated in the JsonBuffer. | ||||
|   String input = | ||||
|       "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|   deserializeJson(root, input); | ||||
|   deserializeJson(doc, input); | ||||
|   JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|   // You can use a String to get an element of a JsonObject | ||||
|   // No duplication is done. | ||||
|   long time = root[String("time")]; | ||||
|   long time = obj[String("time")]; | ||||
|  | ||||
|   // You can use a String to set an element of a JsonObject | ||||
|   // WARNING: the content of the String will be duplicated in the JsonBuffer. | ||||
|   root[String("time")] = time; | ||||
|   obj[String("time")] = time; | ||||
|  | ||||
|   // You can get a String from a JsonObject or JsonArray: | ||||
|   // No duplication is done, at least not in the JsonBuffer. | ||||
|   String sensor = root["sensor"]; | ||||
|   String sensor = obj["sensor"]; | ||||
|  | ||||
|   // Unfortunately, the following doesn't work (issue #118): | ||||
|   // sensor = root["sensor"]; // <-  error "ambiguous overload for 'operator='" | ||||
|   // sensor = obj["sensor"]; // <-  error "ambiguous overload for 'operator='" | ||||
|   // As a workaround, you need to replace by: | ||||
|   sensor = root["sensor"].as<String>(); | ||||
|   sensor = obj["sensor"].as<String>(); | ||||
|  | ||||
|   // You can set a String to a JsonObject or JsonArray: | ||||
|   // WARNING: the content of the String will be duplicated in the JsonBuffer. | ||||
|   root["sensor"] = sensor; | ||||
|   obj["sensor"] = sensor; | ||||
|  | ||||
|   // It works with RawJson too: | ||||
|   root["sensor"] = RawJson(sensor); | ||||
|   obj["sensor"] = RawJson(sensor); | ||||
|  | ||||
|   // You can also concatenate strings | ||||
|   // WARNING: the content of the String will be duplicated in the JsonBuffer. | ||||
|   root[String("sen") + "sor"] = String("gp") + "s"; | ||||
|   obj[String("sen") + "sor"] = String("gp") + "s"; | ||||
|  | ||||
|   // You can compare the content of a JsonObject with a String | ||||
|   if (root["sensor"] == sensor) { | ||||
|   if (obj["sensor"] == sensor) { | ||||
|     // ... | ||||
|   } | ||||
|  | ||||
|   // Lastly, you can print the resulting JSON to a String | ||||
|   String output; | ||||
|   serializeJson(root, output); | ||||
|   serializeJson(doc, output); | ||||
| } | ||||
|  | ||||
| void loop() { | ||||
|   | ||||
| @@ -16,11 +16,11 @@ class memstream : public std::istream { | ||||
| }; | ||||
|  | ||||
| extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | ||||
|   DynamicJsonVariant variant; | ||||
|   DynamicJsonDocument doc; | ||||
|   memstream json(data, size); | ||||
|   JsonError error = deserializeJson(variant, json); | ||||
|   JsonVariant variant = jsonBuffer.parse(json); | ||||
|   if (!error) { | ||||
|   JsonError error = deserializeJson(doc, json); | ||||
|   if (error == JsonError::Ok) { | ||||
|     JsonVariant variant = doc.as<JsonVariant>(); | ||||
|     variant.as<std::string>();  // <- serialize to JSON | ||||
|   } | ||||
|   return 0; | ||||
|   | ||||
							
								
								
									
										10
									
								
								keywords.txt
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								keywords.txt
									
									
									
									
									
								
							| @@ -3,9 +3,8 @@ as	KEYWORD2 | ||||
| createNestedArray	KEYWORD2 | ||||
| createNestedObject	KEYWORD2 | ||||
| deserializeJson	KEYWORD2 | ||||
| DynamicJsonArray	KEYWORD1 | ||||
| DynamicJsonObject	KEYWORD1 | ||||
| DynamicJsonVariant	KEYWORD1 | ||||
| deserializeMsgPack	KEYWORD2 | ||||
| DynamicJsonDocument	KEYWORD1 | ||||
| get	KEYWORD2 | ||||
| JsonArray	KEYWORD1 | ||||
| JsonObject	KEYWORD1 | ||||
| @@ -13,6 +12,5 @@ JsonVariant	KEYWORD1 | ||||
| serializeJson	KEYWORD2 | ||||
| serializeJsonPretty	KEYWORD2 | ||||
| set	KEYWORD2 | ||||
| StaticJsonArray	KEYWORD1 | ||||
| StaticJsonObject	KEYWORD1 | ||||
| StaticJsonVariant	KEYWORD1 | ||||
| StaticJsonDocument	KEYWORD1 | ||||
| to	KEYWORD2 | ||||
|   | ||||
| @@ -4,18 +4,14 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "ArduinoJson/DynamicJsonArray.hpp" | ||||
| #include "ArduinoJson/DynamicJsonObject.hpp" | ||||
| #include "ArduinoJson/DynamicJsonVariant.hpp" | ||||
| #include "ArduinoJson/DynamicJsonDocument.hpp" | ||||
| #include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" | ||||
| #include "ArduinoJson/StaticJsonArray.hpp" | ||||
| #include "ArduinoJson/StaticJsonObject.hpp" | ||||
| #include "ArduinoJson/StaticJsonVariant.hpp" | ||||
| #include "ArduinoJson/StaticJsonDocument.hpp" | ||||
| #include "ArduinoJson/deserializeJson.hpp" | ||||
| #include "ArduinoJson/deserializeMsgPack.hpp" | ||||
|  | ||||
| #include "ArduinoJson/Json/Deserialization/JsonParserImpl.hpp" | ||||
| #include "ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp" | ||||
| #include "ArduinoJson/Json/Deserialization/JsonDeserializer.hpp" | ||||
| #include "ArduinoJson/Json/Serialization/JsonSerializer.hpp" | ||||
| #include "ArduinoJson/JsonArrayImpl.hpp" | ||||
| #include "ArduinoJson/JsonObjectImpl.hpp" | ||||
| #include "ArduinoJson/JsonVariantImpl.hpp" | ||||
|   | ||||
| @@ -1,32 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonArray.hpp" | ||||
| #include "Memory/DynamicJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| class DynamicJsonArray : public JsonArray { | ||||
|   DynamicJsonBuffer _buffer; | ||||
|  | ||||
|  public: | ||||
|   DynamicJsonArray() : JsonArray(&_buffer) {} | ||||
|   DynamicJsonArray(size_t capacity) | ||||
|       : JsonArray(&_buffer), _buffer(capacity - sizeof(JsonArray)) {} | ||||
|  | ||||
|   void clear() { | ||||
|     Internals::List<JsonVariant>::clear(); | ||||
|     _buffer.clear(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size() + sizeof(JsonArray); | ||||
|   } | ||||
|  | ||||
|   DynamicJsonBuffer& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
| }; | ||||
| }  // namespace ArduinoJson | ||||
							
								
								
									
										83
									
								
								src/ArduinoJson/DynamicJsonDocument.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/ArduinoJson/DynamicJsonDocument.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonArray.hpp" | ||||
| #include "JsonObject.hpp" | ||||
| #include "JsonVariant.hpp" | ||||
| #include "Memory/DynamicJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| class DynamicJsonDocument { | ||||
|   Internals::DynamicJsonBuffer _buffer; | ||||
|   JsonVariant _root; | ||||
|  | ||||
|  public: | ||||
|   DynamicJsonDocument() {} | ||||
|   DynamicJsonDocument(size_t capacity) : _buffer(capacity) {} | ||||
|  | ||||
|   template <typename T> | ||||
|   bool is() const { | ||||
|     return _root.is<T>(); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   typename Internals::JsonVariantAs<T>::type as() const { | ||||
|     return _root.as<T>(); | ||||
|   } | ||||
|  | ||||
|   // JsonObject& to<JsonObject>() | ||||
|   template <typename T> | ||||
|   typename Internals::EnableIf<Internals::IsSame<T, JsonObject>::value, | ||||
|                                JsonObject&>::type | ||||
|   to() { | ||||
|     clear(); | ||||
|     JsonObject* object = new (&_buffer) JsonObject(&_buffer); | ||||
|     if (!object) return JsonObject::invalid(); | ||||
|     _root = object; | ||||
|     return *object; | ||||
|   } | ||||
|  | ||||
|   // JsonArray& to<JsonArray>() | ||||
|   template <typename T> | ||||
|   typename Internals::EnableIf<Internals::IsSame<T, JsonArray>::value, | ||||
|                                JsonArray&>::type | ||||
|   to() { | ||||
|     clear(); | ||||
|     JsonArray* array = new (&_buffer) JsonArray(&_buffer); | ||||
|     if (!array) return JsonArray::invalid(); | ||||
|     _root = array; | ||||
|     return *array; | ||||
|   } | ||||
|  | ||||
|   // JsonVariant& to<JsonVariant>() | ||||
|   template <typename T> | ||||
|   typename Internals::EnableIf<Internals::IsSame<T, JsonVariant>::value, | ||||
|                                T&>::type | ||||
|   to() { | ||||
|     clear(); | ||||
|     return _root; | ||||
|   } | ||||
|  | ||||
|   Internals::DynamicJsonBuffer& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
|  | ||||
|   void clear() { | ||||
|     _buffer.clear(); | ||||
|     _root = JsonVariant(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size(); | ||||
|   } | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   void visit(Visitor visitor) const { | ||||
|     return _root.visit(visitor); | ||||
|   } | ||||
| }; | ||||
| }  // namespace ArduinoJson | ||||
| @@ -1,32 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonObject.hpp" | ||||
| #include "Memory/DynamicJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| class DynamicJsonObject : public JsonObject { | ||||
|   DynamicJsonBuffer _buffer; | ||||
|  | ||||
|  public: | ||||
|   DynamicJsonObject() : JsonObject(&_buffer) {} | ||||
|   DynamicJsonObject(size_t capacity) | ||||
|       : JsonObject(&_buffer), _buffer(capacity - sizeof(JsonObject)) {} | ||||
|  | ||||
|   DynamicJsonBuffer& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
|  | ||||
|   void clear() { | ||||
|     Internals::List<JsonPair>::clear(); | ||||
|     _buffer.clear(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size() + sizeof(JsonObject); | ||||
|   } | ||||
| }; | ||||
| }  // namespace ArduinoJson | ||||
| @@ -1,45 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonVariant.hpp" | ||||
| #include "Memory/DynamicJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| class DynamicJsonVariant : public JsonVariant { | ||||
|   DynamicJsonBuffer _buffer; | ||||
|  | ||||
|  public: | ||||
|   DynamicJsonVariant() : JsonVariant() {} | ||||
|   DynamicJsonVariant(size_t capacity) : JsonVariant(), _buffer(capacity) {} | ||||
|  | ||||
|   template <typename T> | ||||
|   DynamicJsonVariant& operator=(const T& value) { | ||||
|     _buffer.clear(); | ||||
|     JsonVariant::operator=(value); | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   DynamicJsonVariant& operator=(const T* value) { | ||||
|     _buffer.clear(); | ||||
|     JsonVariant::operator=(value); | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   DynamicJsonBuffer& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
|  | ||||
|   void clear() { | ||||
|     _buffer.clear(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size(); | ||||
|   } | ||||
| }; | ||||
| }  // namespace ArduinoJson | ||||
							
								
								
									
										218
									
								
								src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,218 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../../JsonError.hpp" | ||||
| #include "../../JsonVariant.hpp" | ||||
| #include "../../Memory/JsonBuffer.hpp" | ||||
| #include "../../Strings/StringWriter.hpp" | ||||
| #include "../../TypeTraits/IsConst.hpp" | ||||
| #include "../Encoding.hpp" | ||||
| #include "./Comments.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| class JsonDeserializer { | ||||
|  public: | ||||
|   JsonDeserializer(JsonBuffer *buffer, TReader reader, TWriter writer, | ||||
|                    uint8_t nestingLimit) | ||||
|       : _buffer(buffer), | ||||
|         _reader(reader), | ||||
|         _writer(writer), | ||||
|         _nestingLimit(nestingLimit) {} | ||||
|   JsonError parse(JsonVariant &variant) { | ||||
|     skipSpacesAndComments(_reader); | ||||
|  | ||||
|     switch (_reader.current()) { | ||||
|       case '[': | ||||
|         return parseArray(variant); | ||||
|  | ||||
|       case '{': | ||||
|         return parseObject(variant); | ||||
|  | ||||
|       default: | ||||
|         return parseValue(variant); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   JsonDeserializer &operator=(const JsonDeserializer &);  // non-copiable | ||||
|  | ||||
|   static bool eat(TReader &reader, char charToSkip) { | ||||
|     skipSpacesAndComments(reader); | ||||
|     if (reader.current() != charToSkip) return false; | ||||
|     reader.move(); | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE bool eat(char charToSkip) { | ||||
|     return eat(_reader, charToSkip); | ||||
|   } | ||||
|  | ||||
|   JsonError parseArray(JsonVariant &variant) { | ||||
|     if (_nestingLimit == 0) return JsonError::TooDeep; | ||||
|  | ||||
|     JsonArray *array = new (_buffer) JsonArray(_buffer); | ||||
|     if (!array) return JsonError::NoMemory; | ||||
|     variant = array; | ||||
|  | ||||
|     // Check opening braket | ||||
|     if (!eat('[')) return JsonError::InvalidInput; | ||||
|     if (eat(']')) return JsonError::Ok; | ||||
|  | ||||
|     // Read each value | ||||
|     for (;;) { | ||||
|       // 1 - Parse value | ||||
|       JsonVariant value; | ||||
|       _nestingLimit--; | ||||
|       JsonError error = parse(value); | ||||
|       _nestingLimit++; | ||||
|       if (error != JsonError::Ok) return error; | ||||
|       if (!array->add(value)) return JsonError::NoMemory; | ||||
|  | ||||
|       // 2 - More values? | ||||
|       if (eat(']')) return JsonError::Ok; | ||||
|       if (!eat(',')) return JsonError::InvalidInput; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   JsonError parseObject(JsonVariant &variant) { | ||||
|     if (_nestingLimit == 0) return JsonError::TooDeep; | ||||
|  | ||||
|     JsonObject *object = new (_buffer) JsonObject(_buffer); | ||||
|     if (!object) return JsonError::NoMemory; | ||||
|     variant = object; | ||||
|  | ||||
|     // Check opening brace | ||||
|     if (!eat('{')) return JsonError::InvalidInput; | ||||
|     if (eat('}')) return JsonError::Ok; | ||||
|  | ||||
|     // Read each key value pair | ||||
|     for (;;) { | ||||
|       // 1 - Parse key | ||||
|       const char *key; | ||||
|       JsonError error = parseString(&key); | ||||
|       if (error) return error; | ||||
|       if (!eat(':')) return JsonError::InvalidInput; | ||||
|  | ||||
|       // 2 - Parse value | ||||
|       JsonVariant value; | ||||
|       _nestingLimit--; | ||||
|       error = parse(value); | ||||
|       _nestingLimit++; | ||||
|       if (error != JsonError::Ok) return error; | ||||
|       if (!object->set(key, value)) return JsonError::NoMemory; | ||||
|  | ||||
|       // 3 - More keys/values? | ||||
|       if (eat('}')) return JsonError::Ok; | ||||
|       if (!eat(',')) return JsonError::InvalidInput; | ||||
|     } | ||||
|   } | ||||
|   JsonError parseValue(JsonVariant &variant) { | ||||
|     bool hasQuotes = isQuote(_reader.current()); | ||||
|     const char *value; | ||||
|     JsonError error = parseString(&value); | ||||
|     if (error) return error; | ||||
|     if (hasQuotes) { | ||||
|       variant = value; | ||||
|     } else { | ||||
|       variant = RawJson(value); | ||||
|     } | ||||
|     return JsonError::Ok; | ||||
|   } | ||||
|  | ||||
|   JsonError parseString(const char **result) { | ||||
|     typename RemoveReference<TWriter>::type::String str = _writer.startString(); | ||||
|  | ||||
|     skipSpacesAndComments(_reader); | ||||
|     char c = _reader.current(); | ||||
|  | ||||
|     if (isQuote(c)) {  // quotes | ||||
|       _reader.move(); | ||||
|       char stopChar = c; | ||||
|       for (;;) { | ||||
|         c = _reader.current(); | ||||
|         if (c == '\0') break; | ||||
|         _reader.move(); | ||||
|  | ||||
|         if (c == stopChar) break; | ||||
|  | ||||
|         if (c == '\\') { | ||||
|           // replace char | ||||
|           c = Encoding::unescapeChar(_reader.current()); | ||||
|           if (c == '\0') return JsonError::InvalidInput; | ||||
|           _reader.move(); | ||||
|         } | ||||
|  | ||||
|         str.append(c); | ||||
|       } | ||||
|     } else if (canBeInNonQuotedString(c)) {  // no quotes | ||||
|       do { | ||||
|         _reader.move(); | ||||
|         str.append(c); | ||||
|         c = _reader.current(); | ||||
|       } while (canBeInNonQuotedString(c)); | ||||
|     } else { | ||||
|       return JsonError::InvalidInput; | ||||
|     } | ||||
|  | ||||
|     *result = str.c_str(); | ||||
|     if (*result == NULL) return JsonError::NoMemory; | ||||
|     return JsonError::Ok; | ||||
|   } | ||||
|  | ||||
|   static inline bool isBetween(char c, char min, char max) { | ||||
|     return min <= c && c <= max; | ||||
|   } | ||||
|  | ||||
|   static inline bool canBeInNonQuotedString(char c) { | ||||
|     return isBetween(c, '0', '9') || isBetween(c, '_', 'z') || | ||||
|            isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; | ||||
|   } | ||||
|  | ||||
|   static inline bool isQuote(char c) { | ||||
|     return c == '\'' || c == '\"'; | ||||
|   } | ||||
|  | ||||
|   JsonBuffer *_buffer; | ||||
|   TReader _reader; | ||||
|   TWriter _writer; | ||||
|   uint8_t _nestingLimit; | ||||
| }; | ||||
|  | ||||
| template <typename TJsonBuffer, typename TString, typename Enable = void> | ||||
| struct JsonParserBuilder { | ||||
|   typedef typename StringTraits<TString>::Reader InputReader; | ||||
|   typedef JsonDeserializer<InputReader, TJsonBuffer &> TParser; | ||||
|  | ||||
|   static TParser makeParser(TJsonBuffer *buffer, TString &json, | ||||
|                             uint8_t nestingLimit) { | ||||
|     return TParser(buffer, InputReader(json), *buffer, nestingLimit); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TJsonBuffer, typename TChar> | ||||
| struct JsonParserBuilder<TJsonBuffer, TChar *, | ||||
|                          typename EnableIf<!IsConst<TChar>::value>::type> { | ||||
|   typedef typename StringTraits<TChar *>::Reader TReader; | ||||
|   typedef StringWriter<TChar> TWriter; | ||||
|   typedef JsonDeserializer<TReader, TWriter> TParser; | ||||
|  | ||||
|   static TParser makeParser(TJsonBuffer *buffer, TChar *json, | ||||
|                             uint8_t nestingLimit) { | ||||
|     return TParser(buffer, TReader(json), TWriter(json), nestingLimit); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TJsonBuffer, typename TString> | ||||
| inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser( | ||||
|     TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { | ||||
|   return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json, | ||||
|                                                              nestingLimit); | ||||
| } | ||||
| }  // namespace Internals | ||||
| }  // namespace ArduinoJson | ||||
| @@ -1,95 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../../JsonError.hpp" | ||||
| #include "../../JsonVariant.hpp" | ||||
| #include "../../Memory/JsonBuffer.hpp" | ||||
| #include "../../Strings/StringWriter.hpp" | ||||
| #include "../../TypeTraits/IsConst.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // Parse JSON string to create JsonArrays and JsonObjects | ||||
| // This internal class is not indended to be used directly. | ||||
| // Instead, use JsonBuffer.parseArray() or .parseObject() | ||||
| template <typename TReader, typename TWriter> | ||||
| class JsonParser { | ||||
|  public: | ||||
|   JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer, | ||||
|              uint8_t nestingLimit) | ||||
|       : _buffer(buffer), | ||||
|         _reader(reader), | ||||
|         _writer(writer), | ||||
|         _nestingLimit(nestingLimit) {} | ||||
|   JsonError parse(JsonArray &destination); | ||||
|   JsonError parse(JsonObject &destination); | ||||
|   JsonError parse(JsonVariant &destination); | ||||
|  | ||||
|  private: | ||||
|   JsonParser &operator=(const JsonParser &);  // non-copiable | ||||
|  | ||||
|   static bool eat(TReader &, char charToSkip); | ||||
|   FORCE_INLINE bool eat(char charToSkip) { | ||||
|     return eat(_reader, charToSkip); | ||||
|   } | ||||
|  | ||||
|   const char *parseString(); | ||||
|   JsonError parseArray(JsonVariant &variant); | ||||
|   JsonError parseObject(JsonVariant &variant); | ||||
|   JsonError parseValue(JsonVariant &variant); | ||||
|  | ||||
|   static inline bool isBetween(char c, char min, char max) { | ||||
|     return min <= c && c <= max; | ||||
|   } | ||||
|  | ||||
|   static inline bool canBeInNonQuotedString(char c) { | ||||
|     return isBetween(c, '0', '9') || isBetween(c, '_', 'z') || | ||||
|            isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; | ||||
|   } | ||||
|  | ||||
|   static inline bool isQuote(char c) { | ||||
|     return c == '\'' || c == '\"'; | ||||
|   } | ||||
|  | ||||
|   JsonBuffer *_buffer; | ||||
|   TReader _reader; | ||||
|   TWriter _writer; | ||||
|   uint8_t _nestingLimit; | ||||
| }; | ||||
|  | ||||
| template <typename TJsonBuffer, typename TString, typename Enable = void> | ||||
| struct JsonParserBuilder { | ||||
|   typedef typename StringTraits<TString>::Reader InputReader; | ||||
|   typedef JsonParser<InputReader, TJsonBuffer &> TParser; | ||||
|  | ||||
|   static TParser makeParser(TJsonBuffer *buffer, TString &json, | ||||
|                             uint8_t nestingLimit) { | ||||
|     return TParser(buffer, InputReader(json), *buffer, nestingLimit); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TJsonBuffer, typename TChar> | ||||
| struct JsonParserBuilder<TJsonBuffer, TChar *, | ||||
|                          typename EnableIf<!IsConst<TChar>::value>::type> { | ||||
|   typedef typename StringTraits<TChar *>::Reader TReader; | ||||
|   typedef StringWriter<TChar> TWriter; | ||||
|   typedef JsonParser<TReader, TWriter> TParser; | ||||
|  | ||||
|   static TParser makeParser(TJsonBuffer *buffer, TChar *json, | ||||
|                             uint8_t nestingLimit) { | ||||
|     return TParser(buffer, TReader(json), TWriter(json), nestingLimit); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TJsonBuffer, typename TString> | ||||
| inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser( | ||||
|     TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { | ||||
|   return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json, | ||||
|                                                              nestingLimit); | ||||
| } | ||||
| }  // namespace Internals | ||||
| }  // namespace ArduinoJson | ||||
| @@ -1,166 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../Encoding.hpp" | ||||
| #include "Comments.hpp" | ||||
| #include "JsonParser.hpp" | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat( | ||||
|     TReader &reader, char charToSkip) { | ||||
|   skipSpacesAndComments(reader); | ||||
|   if (reader.current() != charToSkip) return false; | ||||
|   reader.move(); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline ArduinoJson::JsonError | ||||
| ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(JsonArray &array) { | ||||
|   if (_nestingLimit == 0) return JsonError::TooDeep; | ||||
|  | ||||
|   // Check opening braket | ||||
|   if (!eat('[')) return JsonError::OpeningBracketExpected; | ||||
|   if (eat(']')) return JsonError::Ok; | ||||
|  | ||||
|   // Read each value | ||||
|   for (;;) { | ||||
|     // 1 - Parse value | ||||
|     JsonVariant value; | ||||
|     _nestingLimit--; | ||||
|     JsonError error = parse(value); | ||||
|     _nestingLimit++; | ||||
|     if (error != JsonError::Ok) return error; | ||||
|     if (!array.add(value)) return JsonError::NoMemory; | ||||
|  | ||||
|     // 2 - More values? | ||||
|     if (eat(']')) return JsonError::Ok; | ||||
|     if (!eat(',')) return JsonError::ClosingBracketExpected; | ||||
|   } | ||||
| } | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline ArduinoJson::JsonError | ||||
| ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse( | ||||
|     JsonObject &object) { | ||||
|   if (_nestingLimit == 0) return JsonError::TooDeep; | ||||
|  | ||||
|   // Check opening brace | ||||
|   if (!eat('{')) return JsonError::OpeningBraceExpected; | ||||
|   if (eat('}')) return JsonError::Ok; | ||||
|  | ||||
|   // Read each key value pair | ||||
|   for (;;) { | ||||
|     // 1 - Parse key | ||||
|     const char *key = parseString(); | ||||
|     if (!key) return JsonError::NoMemory; | ||||
|     if (!eat(':')) return JsonError::ColonExpected; | ||||
|  | ||||
|     // 2 - Parse value | ||||
|     JsonVariant value; | ||||
|     _nestingLimit--; | ||||
|     JsonError error = parse(value); | ||||
|     _nestingLimit++; | ||||
|     if (error != JsonError::Ok) return error; | ||||
|     if (!object.set(key, value)) return JsonError::NoMemory; | ||||
|  | ||||
|     // 3 - More keys/values? | ||||
|     if (eat('}')) return JsonError::Ok; | ||||
|     if (!eat(',')) return JsonError::ClosingBraceExpected; | ||||
|   } | ||||
| } | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline ArduinoJson::JsonError | ||||
| ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse( | ||||
|     JsonVariant &variant) { | ||||
|   skipSpacesAndComments(_reader); | ||||
|  | ||||
|   switch (_reader.current()) { | ||||
|     case '[': | ||||
|       return parseArray(variant); | ||||
|  | ||||
|     case '{': | ||||
|       return parseObject(variant); | ||||
|  | ||||
|     default: | ||||
|       return parseValue(variant); | ||||
|   } | ||||
| } | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline ArduinoJson::JsonError | ||||
| ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray( | ||||
|     JsonVariant &variant) { | ||||
|   JsonArray *array = new (_buffer) JsonArray(_buffer); | ||||
|   if (!array) return JsonError::NoMemory; | ||||
|   variant = array; | ||||
|   return parse(*array); | ||||
| } | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline ArduinoJson::JsonError | ||||
| ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject( | ||||
|     JsonVariant &variant) { | ||||
|   JsonObject *object = new (_buffer) JsonObject(_buffer); | ||||
|   if (!object) return JsonError::NoMemory; | ||||
|   variant = object; | ||||
|   return parse(*object); | ||||
| } | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline ArduinoJson::JsonError | ||||
| ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseValue( | ||||
|     JsonVariant &variant) { | ||||
|   bool hasQuotes = isQuote(_reader.current()); | ||||
|   const char *value = parseString(); | ||||
|   if (value == NULL) return JsonError::NoMemory; | ||||
|   if (hasQuotes) { | ||||
|     variant = value; | ||||
|   } else { | ||||
|     variant = RawJson(value); | ||||
|   } | ||||
|   return JsonError::Ok; | ||||
| } | ||||
|  | ||||
| template <typename TReader, typename TWriter> | ||||
| inline const char * | ||||
| ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() { | ||||
|   typename RemoveReference<TWriter>::type::String str = _writer.startString(); | ||||
|  | ||||
|   skipSpacesAndComments(_reader); | ||||
|   char c = _reader.current(); | ||||
|  | ||||
|   if (isQuote(c)) {  // quotes | ||||
|     _reader.move(); | ||||
|     char stopChar = c; | ||||
|     for (;;) { | ||||
|       c = _reader.current(); | ||||
|       if (c == '\0') break; | ||||
|       _reader.move(); | ||||
|  | ||||
|       if (c == stopChar) break; | ||||
|  | ||||
|       if (c == '\\') { | ||||
|         // replace char | ||||
|         c = Encoding::unescapeChar(_reader.current()); | ||||
|         if (c == '\0') break; | ||||
|         _reader.move(); | ||||
|       } | ||||
|  | ||||
|       str.append(c); | ||||
|     } | ||||
|   } else {  // no quotes | ||||
|     for (;;) { | ||||
|       if (!canBeInNonQuotedString(c)) break; | ||||
|       _reader.move(); | ||||
|       str.append(c); | ||||
|       c = _reader.current(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   return str.c_str(); | ||||
| } | ||||
| @@ -16,26 +16,15 @@ | ||||
| #endif | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| class JsonArray; | ||||
| class JsonObject; | ||||
| class JsonVariant; | ||||
|  | ||||
| namespace Internals { | ||||
|  | ||||
| class JsonArraySubscript; | ||||
| template <typename TKey> | ||||
| class JsonObjectSubscript; | ||||
|  | ||||
| template <typename Writer> | ||||
| class JsonSerializer { | ||||
|  public: | ||||
|   static void serialize(const JsonArray &, Writer &); | ||||
|   static void serialize(const JsonArraySubscript &, Writer &); | ||||
|   static void serialize(const JsonObject &, Writer &); | ||||
|   template <typename TKey> | ||||
|   static void serialize(const JsonObjectSubscript<TKey> &, Writer &); | ||||
|   static void serialize(const JsonVariant &, Writer &); | ||||
|   template <typename TSource> | ||||
|   static void serialize(const TSource &source, Writer &writer) { | ||||
|     source.visit(Visitor(&writer)); | ||||
|   } | ||||
|  | ||||
|   struct Visitor { | ||||
|     Visitor(Writer *writer) : _writer(writer) {} | ||||
| @@ -44,12 +33,38 @@ class JsonSerializer { | ||||
|       _writer->writeFloat(value); | ||||
|     } | ||||
|  | ||||
|     void acceptArray(const JsonArray &value) { | ||||
|       serialize(value, *_writer); | ||||
|     void acceptArray(const JsonArray &array) { | ||||
|       _writer->beginArray(); | ||||
|  | ||||
|       JsonArray::const_iterator it = array.begin(); | ||||
|       while (it != array.end()) { | ||||
|         it->visit(*this); | ||||
|  | ||||
|         ++it; | ||||
|         if (it == array.end()) break; | ||||
|  | ||||
|         _writer->writeComma(); | ||||
|       } | ||||
|  | ||||
|     void acceptObject(const JsonObject &value) { | ||||
|       serialize(value, *_writer); | ||||
|       _writer->endArray(); | ||||
|     } | ||||
|  | ||||
|     void acceptObject(const JsonObject &object) { | ||||
|       _writer->beginObject(); | ||||
|  | ||||
|       JsonObject::const_iterator it = object.begin(); | ||||
|       while (it != object.end()) { | ||||
|         _writer->writeString(it->key); | ||||
|         _writer->writeColon(); | ||||
|         it->value.visit(*this); | ||||
|  | ||||
|         ++it; | ||||
|         if (it == object.end()) break; | ||||
|  | ||||
|         _writer->writeComma(); | ||||
|       } | ||||
|  | ||||
|       _writer->endObject(); | ||||
|     } | ||||
|  | ||||
|     void acceptString(const char *value) { | ||||
|   | ||||
| @@ -1,69 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../../JsonArray.hpp" | ||||
| #include "../../JsonArraySubscript.hpp" | ||||
| #include "../../JsonObject.hpp" | ||||
| #include "../../JsonObjectSubscript.hpp" | ||||
| #include "../../JsonVariant.hpp" | ||||
| #include "JsonSerializer.hpp" | ||||
|  | ||||
| template <typename Writer> | ||||
| inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||
|     const JsonArray& array, Writer& writer) { | ||||
|   writer.beginArray(); | ||||
|  | ||||
|   JsonArray::const_iterator it = array.begin(); | ||||
|   while (it != array.end()) { | ||||
|     serialize(*it, writer); | ||||
|  | ||||
|     ++it; | ||||
|     if (it == array.end()) break; | ||||
|  | ||||
|     writer.writeComma(); | ||||
|   } | ||||
|  | ||||
|   writer.endArray(); | ||||
| } | ||||
|  | ||||
| template <typename Writer> | ||||
| inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||
|     const JsonArraySubscript& arraySubscript, Writer& writer) { | ||||
|   serialize(arraySubscript.as<JsonVariant>(), writer); | ||||
| } | ||||
|  | ||||
| template <typename Writer> | ||||
| inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||
|     const JsonObject& object, Writer& writer) { | ||||
|   writer.beginObject(); | ||||
|  | ||||
|   JsonObject::const_iterator it = object.begin(); | ||||
|   while (it != object.end()) { | ||||
|     writer.writeString(it->key); | ||||
|     writer.writeColon(); | ||||
|     serialize(it->value, writer); | ||||
|  | ||||
|     ++it; | ||||
|     if (it == object.end()) break; | ||||
|  | ||||
|     writer.writeComma(); | ||||
|   } | ||||
|  | ||||
|   writer.endObject(); | ||||
| } | ||||
|  | ||||
| template <typename Writer> | ||||
| template <typename TKey> | ||||
| inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||
|     const JsonObjectSubscript<TKey>& objectSubscript, Writer& writer) { | ||||
|   serialize(objectSubscript.template as<JsonVariant>(), writer); | ||||
| } | ||||
|  | ||||
| template <typename Writer> | ||||
| inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize( | ||||
|     const JsonVariant& variant, Writer& writer) { | ||||
|   variant.visit(Visitor(&writer)); | ||||
| } | ||||
| @@ -180,6 +180,11 @@ class JsonArray : public Internals::ReferenceType, | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   void visit(Visitor visitor) const { | ||||
|     return visitor.acceptArray(*this); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   template <typename TValueRef> | ||||
|   bool set_impl(size_t index, TValueRef value) { | ||||
|   | ||||
| @@ -74,6 +74,11 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
|     return _array.set(_index, value); | ||||
|   } | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   void visit(Visitor visitor) const { | ||||
|     return _array.get<JsonVariant>(_index).visit(visitor); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   JsonArray& _array; | ||||
|   const size_t _index; | ||||
|   | ||||
| @@ -8,16 +8,7 @@ namespace ArduinoJson { | ||||
|  | ||||
| class JsonError { | ||||
|  public: | ||||
|   enum Code { | ||||
|     Ok, | ||||
|     OpeningBraceExpected, | ||||
|     ClosingBraceExpected, | ||||
|     OpeningBracketExpected, | ||||
|     ClosingBracketExpected, | ||||
|     ColonExpected, | ||||
|     TooDeep, | ||||
|     NoMemory | ||||
|   }; | ||||
|   enum Code { Ok, TooDeep, NoMemory, InvalidInput }; | ||||
|  | ||||
|   JsonError(Code code) : _code(code) {} | ||||
|  | ||||
| @@ -45,20 +36,12 @@ class JsonError { | ||||
|     switch (_code) { | ||||
|       case Ok: | ||||
|         return "Ok"; | ||||
|       case OpeningBraceExpected: | ||||
|         return "OpeningBraceExpected"; | ||||
|       case ClosingBraceExpected: | ||||
|         return "ClosingBraceExpected"; | ||||
|       case OpeningBracketExpected: | ||||
|         return "OpeningBracketExpected"; | ||||
|       case ClosingBracketExpected: | ||||
|         return "ClosingBracketExpected"; | ||||
|       case ColonExpected: | ||||
|         return "ColonExpected"; | ||||
|       case TooDeep: | ||||
|         return "TooDeep"; | ||||
|       case NoMemory: | ||||
|         return "NoMemory"; | ||||
|       case InvalidInput: | ||||
|         return "InvalidInput"; | ||||
|       default: | ||||
|         return "???"; | ||||
|     } | ||||
| @@ -73,6 +56,11 @@ inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { | ||||
|   s << e.c_str(); | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| inline std::ostream& operator<<(std::ostream& s, JsonError::Code c) { | ||||
|   s << JsonError(c).c_str(); | ||||
|   return s; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -229,6 +229,11 @@ class JsonObject : public Internals::ReferenceType, | ||||
|     return instance; | ||||
|   } | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   void visit(Visitor visitor) const { | ||||
|     return visitor.acceptObject(*this); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   // Returns the list node that matches the specified key. | ||||
|   template <typename TStringRef> | ||||
|   | ||||
| @@ -82,6 +82,11 @@ class JsonObjectSubscript | ||||
|     return _object.set(_key, value); | ||||
|   } | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   void visit(Visitor visitor) const { | ||||
|     return _object.get<JsonVariant>(_key).visit(visitor); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   JsonObject& _object; | ||||
|   TStringRef _key; | ||||
|   | ||||
| @@ -151,6 +151,12 @@ class DynamicJsonBufferBase : public JsonBuffer { | ||||
|   Block* _head; | ||||
|   size_t _nextBlockCapacity; | ||||
| }; | ||||
|  | ||||
| // Implements a JsonBuffer with dynamic memory allocation. | ||||
| // You are strongly encouraged to consider using StaticJsonBuffer which is much | ||||
| // more suitable for embedded systems. | ||||
| typedef Internals::DynamicJsonBufferBase<Internals::DefaultAllocator> | ||||
|     DynamicJsonBuffer; | ||||
| }  // namespace Internals | ||||
|  | ||||
| #if defined(__clang__) | ||||
| @@ -160,10 +166,4 @@ class DynamicJsonBufferBase : public JsonBuffer { | ||||
| #pragma GCC diagnostic pop | ||||
| #endif | ||||
| #endif | ||||
|  | ||||
| // Implements a JsonBuffer with dynamic memory allocation. | ||||
| // You are strongly encouraged to consider using StaticJsonBuffer which is much | ||||
| // more suitable for embedded systems. | ||||
| typedef Internals::DynamicJsonBufferBase<Internals::DefaultAllocator> | ||||
|     DynamicJsonBuffer; | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -92,7 +92,6 @@ class StaticJsonBufferBase : public JsonBuffer { | ||||
|   size_t _capacity; | ||||
|   size_t _size; | ||||
| }; | ||||
| }  // namespace Internals | ||||
|  | ||||
| #if defined(__clang__) | ||||
| #pragma clang diagnostic push | ||||
| @@ -118,6 +117,7 @@ class StaticJsonBuffer : public Internals::StaticJsonBufferBase { | ||||
|  private: | ||||
|   char _buffer[ACTUAL_CAPACITY]; | ||||
| }; | ||||
| }  // namespace Internals | ||||
| }  // namespace ArduinoJson | ||||
|  | ||||
| #if defined(__clang__) | ||||
|   | ||||
| @@ -28,40 +28,6 @@ class MsgPackDeserializer { | ||||
|         _writer(writer), | ||||
|         _nestingLimit(nestingLimit) {} | ||||
|  | ||||
|   MsgPackError parse(JsonArray &array) { | ||||
|     uint8_t c = readOne(); | ||||
|     size_t n; | ||||
|  | ||||
|     if ((c & 0xF0) == 0x90) { | ||||
|       n = c & 0x0F; | ||||
|     } else if (c == 0xdc) { | ||||
|       n = readInteger<uint16_t>(); | ||||
|     } else if (c == 0xdd) { | ||||
|       n = readInteger<uint32_t>(); | ||||
|     } else { | ||||
|       return MsgPackError::NotAnArray; | ||||
|     } | ||||
|  | ||||
|     return readArray(array, n); | ||||
|   } | ||||
|  | ||||
|   MsgPackError parse(JsonObject &object) { | ||||
|     uint8_t c = readOne(); | ||||
|     size_t n; | ||||
|  | ||||
|     if ((c & 0xf0) == 0x80) { | ||||
|       n = c & 0x0f; | ||||
|     } else if (c == 0xde) { | ||||
|       n = readInteger<uint16_t>(); | ||||
|     } else if (c == 0xdf) { | ||||
|       n = readInteger<uint32_t>(); | ||||
|     } else { | ||||
|       return MsgPackError::NotAnObject; | ||||
|     } | ||||
|  | ||||
|     return readObject(object, n); | ||||
|   } | ||||
|  | ||||
|   MsgPackError parse(JsonVariant &variant) { | ||||
|     uint8_t c = readOne(); | ||||
|  | ||||
|   | ||||
| @@ -8,7 +8,7 @@ namespace ArduinoJson { | ||||
|  | ||||
| class MsgPackError { | ||||
|  public: | ||||
|   enum Code { Ok, NotSupported, NoMemory, NotAnArray, NotAnObject, TooDeep }; | ||||
|   enum Code { Ok, NotSupported, NoMemory, TooDeep }; | ||||
|  | ||||
|   MsgPackError() {} | ||||
|  | ||||
| @@ -42,10 +42,6 @@ class MsgPackError { | ||||
|         return "NotSupported"; | ||||
|       case NoMemory: | ||||
|         return "NoMemory"; | ||||
|       case NotAnArray: | ||||
|         return "NotAnArray"; | ||||
|       case NotAnObject: | ||||
|         return "NotAnObject"; | ||||
|       case TooDeep: | ||||
|         return "TooDeep"; | ||||
|       default: | ||||
| @@ -62,6 +58,11 @@ inline std::ostream& operator<<(std::ostream& os, const MsgPackError& err) { | ||||
|   os << err.c_str(); | ||||
|   return os; | ||||
| } | ||||
|  | ||||
| inline std::ostream& operator<<(std::ostream& os, MsgPackError::Code code) { | ||||
|   os << MsgPackError(code).c_str(); | ||||
|   return os; | ||||
| } | ||||
| #endif | ||||
|  | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -1,32 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonArray.hpp" | ||||
| #include "Memory/StaticJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| template <size_t CAPACITY> | ||||
| class StaticJsonArray : public JsonArray { | ||||
|   StaticJsonBuffer<CAPACITY - sizeof(JsonArray)> _buffer; | ||||
|  | ||||
|  public: | ||||
|   StaticJsonArray() : JsonArray(&_buffer) {} | ||||
|  | ||||
|   void clear() { | ||||
|     Internals::List<JsonVariant>::clear(); | ||||
|     _buffer.clear(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size() + sizeof(JsonArray); | ||||
|   } | ||||
|  | ||||
|   Internals::StaticJsonBufferBase& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
| }; | ||||
| }  // namespace ArduinoJson | ||||
							
								
								
									
										80
									
								
								src/ArduinoJson/StaticJsonDocument.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								src/ArduinoJson/StaticJsonDocument.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonVariant.hpp" | ||||
| #include "Memory/StaticJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| template <size_t CAPACITY = sizeof(JsonVariant)> | ||||
| class StaticJsonDocument { | ||||
|   Internals::StaticJsonBuffer<CAPACITY> _buffer; | ||||
|   JsonVariant _root; | ||||
|  | ||||
|  public: | ||||
|   Internals::StaticJsonBufferBase& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool is() const { | ||||
|     return _root.is<T>(); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   typename Internals::JsonVariantAs<T>::type as() const { | ||||
|     return _root.as<T>(); | ||||
|   } | ||||
|  | ||||
|   // JsonObject& to<JsonObject>() | ||||
|   template <typename T> | ||||
|   typename Internals::EnableIf<Internals::IsSame<T, JsonObject>::value, | ||||
|                                JsonObject&>::type | ||||
|   to() { | ||||
|     clear(); | ||||
|     JsonObject* object = new (&_buffer) JsonObject(&_buffer); | ||||
|     if (!object) return JsonObject::invalid(); | ||||
|     _root = object; | ||||
|     return *object; | ||||
|   } | ||||
|  | ||||
|   // JsonArray& to<JsonArray>() | ||||
|   template <typename T> | ||||
|   typename Internals::EnableIf<Internals::IsSame<T, JsonArray>::value, | ||||
|                                JsonArray&>::type | ||||
|   to() { | ||||
|     clear(); | ||||
|     JsonArray* array = new (&_buffer) JsonArray(&_buffer); | ||||
|     if (!array) return JsonArray::invalid(); | ||||
|     _root = array; | ||||
|     return *array; | ||||
|   } | ||||
|  | ||||
|   // JsonVariant to<JsonVariant>() | ||||
|   template <typename T> | ||||
|   typename Internals::EnableIf<Internals::IsSame<T, JsonVariant>::value, | ||||
|                                T&>::type | ||||
|   to() { | ||||
|     clear(); | ||||
|     return _root; | ||||
|   } | ||||
|  | ||||
|   void clear() { | ||||
|     _buffer.clear(); | ||||
|     _root = JsonVariant(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size(); | ||||
|   } | ||||
|  | ||||
|   template <typename Visitor> | ||||
|   void visit(Visitor visitor) const { | ||||
|     return _root.visit(visitor); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| }  // namespace ArduinoJson | ||||
| @@ -1,32 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonObject.hpp" | ||||
| #include "Memory/StaticJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| template <size_t CAPACITY> | ||||
| class StaticJsonObject : public JsonObject { | ||||
|   StaticJsonBuffer<CAPACITY - sizeof(JsonObject)> _buffer; | ||||
|  | ||||
|  public: | ||||
|   StaticJsonObject() : JsonObject(&_buffer) {} | ||||
|  | ||||
|   void clear() { | ||||
|     Internals::List<JsonPair>::clear(); | ||||
|     _buffer.clear(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size() + sizeof(JsonObject); | ||||
|   } | ||||
|  | ||||
|   Internals::StaticJsonBufferBase& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
| }; | ||||
| }  // namespace ArduinoJson | ||||
| @@ -1,43 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonVariant.hpp" | ||||
| #include "Memory/StaticJsonBuffer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| template <size_t CAPACITY = sizeof(JsonVariant)> | ||||
| class StaticJsonVariant : public JsonVariant { | ||||
|   StaticJsonBuffer<CAPACITY> _buffer; | ||||
|  | ||||
|  public: | ||||
|   template <typename T> | ||||
|   StaticJsonVariant& operator=(const T& value) { | ||||
|     _buffer.clear(); | ||||
|     JsonVariant::operator=(value); | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   StaticJsonVariant& operator=(const T* value) { | ||||
|     _buffer.clear(); | ||||
|     JsonVariant::operator=(value); | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   Internals::StaticJsonBufferBase& buffer() { | ||||
|     return _buffer; | ||||
|   } | ||||
|  | ||||
|   void clear() { | ||||
|     _buffer.clear(); | ||||
|   } | ||||
|  | ||||
|   size_t memoryUsage() const { | ||||
|     return _buffer.size(); | ||||
|   } | ||||
| }; | ||||
| }  // namespace ArduinoJson | ||||
| @@ -4,6 +4,8 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <stdlib.h>  // for size_t | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
|   | ||||
| @@ -4,43 +4,40 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Json/Deserialization/JsonParser.hpp" | ||||
| #include "Json/Deserialization/JsonDeserializer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| // JsonError deserializeJson(TDestination& destination, TString json); | ||||
| // TDestination = JsonArray, JsonObject, JsonVariant | ||||
| // JsonError deserializeJson(TDocument& doc, TString json); | ||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument | ||||
| // TString = const std::string&, const String& | ||||
| template <typename TDestination, typename TString> | ||||
| template <typename TDocument, typename TString> | ||||
| typename Internals::EnableIf<!Internals::IsArray<TString>::value, | ||||
|                              JsonError>::type | ||||
| deserializeJson(TDestination &destination, const TString &json, | ||||
| deserializeJson(TDocument &doc, const TString &json, | ||||
|                 uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { | ||||
|   destination.clear(); | ||||
|   return Internals::makeParser(&destination.buffer(), json, nestingLimit) | ||||
|       .parse(destination); | ||||
|   return Internals::makeParser(&doc.buffer(), json, nestingLimit) | ||||
|       .parse(doc.template to<JsonVariant>()); | ||||
| } | ||||
| // | ||||
| // JsonError deserializeJson(TDestination& destination, TString json); | ||||
| // TDestination = JsonArray, JsonObject, JsonVariant | ||||
| // JsonError deserializeJson(TDocument& doc, TString json); | ||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument | ||||
| // TString = const char*, const char[N], const FlashStringHelper* | ||||
| template <typename TDestination, typename TString> | ||||
| template <typename TDocument, typename TString> | ||||
| JsonError deserializeJson( | ||||
|     TDestination &destination, TString *json, | ||||
|     TDocument &doc, TString *json, | ||||
|     uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { | ||||
|   destination.clear(); | ||||
|   return Internals::makeParser(&destination.buffer(), json, nestingLimit) | ||||
|       .parse(destination); | ||||
|   return Internals::makeParser(&doc.buffer(), json, nestingLimit) | ||||
|       .parse(doc.template to<JsonVariant>()); | ||||
| } | ||||
| // | ||||
| // JsonError deserializeJson(TDestination& destination, TString json); | ||||
| // TDestination = JsonArray, JsonObject, JsonVariant | ||||
| // JsonError deserializeJson(TDocument& doc, TString json); | ||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument | ||||
| // TString = std::istream&, Stream& | ||||
| template <typename TDestination, typename TString> | ||||
| template <typename TDocument, typename TString> | ||||
| JsonError deserializeJson( | ||||
|     TDestination &destination, TString &json, | ||||
|     TDocument &doc, TString &json, | ||||
|     uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { | ||||
|   destination.clear(); | ||||
|   return Internals::makeParser(&destination.buffer(), json, nestingLimit) | ||||
|       .parse(destination); | ||||
|   return Internals::makeParser(&doc.buffer(), json, nestingLimit) | ||||
|       .parse(doc.template to<JsonVariant>()); | ||||
| } | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -7,43 +7,37 @@ | ||||
| #include "MsgPack/MsgPackDeserializer.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| // MsgPackError deserializeMsgPack(TDestination& destination, TString json); | ||||
| // TDestination = JsonArray, JsonObject, JsonVariant | ||||
| // MsgPackError deserializeMsgPack(TDocument& doc, TString json); | ||||
| // TDocument = DynamicJsonArray | StaticJsonArray | ||||
| // TString = const std::string&, const String& | ||||
| template <typename TDestination, typename TString> | ||||
| template <typename TDocument, typename TString> | ||||
| typename Internals::EnableIf<!Internals::IsArray<TString>::value, | ||||
|                              MsgPackError>::type | ||||
| deserializeMsgPack(TDestination &destination, const TString &json, | ||||
| deserializeMsgPack(TDocument &doc, const TString &json, | ||||
|                    uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { | ||||
|   destination.clear(); | ||||
|   return Internals::makeMsgPackDeserializer(&destination.buffer(), json, | ||||
|                                             nestingLimit) | ||||
|       .parse(destination); | ||||
|   return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) | ||||
|       .parse(doc.template to<JsonVariant>()); | ||||
| } | ||||
| // | ||||
| // MsgPackError deserializeMsgPack(TDestination& destination, TString json); | ||||
| // TDestination = JsonArray, JsonObject, JsonVariant | ||||
| // MsgPackError deserializeMsgPack(TDocument& doc, TString json); | ||||
| // TDocument = DynamicJsonArray | StaticJsonArray | ||||
| // TString = const char*, const char[N], const FlashStringHelper* | ||||
| template <typename TDestination, typename TString> | ||||
| template <typename TDocument, typename TString> | ||||
| MsgPackError deserializeMsgPack( | ||||
|     TDestination &destination, TString *json, | ||||
|     TDocument &doc, TString *json, | ||||
|     uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { | ||||
|   destination.clear(); | ||||
|   return Internals::makeMsgPackDeserializer(&destination.buffer(), json, | ||||
|                                             nestingLimit) | ||||
|       .parse(destination); | ||||
|   return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) | ||||
|       .parse(doc.template to<JsonVariant>()); | ||||
| } | ||||
| // | ||||
| // MsgPackError deserializeMsgPack(TDestination& destination, TString json); | ||||
| // TDestination = JsonArray, JsonObject, JsonVariant | ||||
| // MsgPackError deserializeMsgPack(TDocument& doc, TString json); | ||||
| // TDocument = DynamicJsonArray | StaticJsonArray | ||||
| // TString = std::istream&, Stream& | ||||
| template <typename TDestination, typename TString> | ||||
| template <typename TDocument, typename TString> | ||||
| MsgPackError deserializeMsgPack( | ||||
|     TDestination &destination, TString &json, | ||||
|     TDocument &doc, TString &json, | ||||
|     uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { | ||||
|   destination.clear(); | ||||
|   return Internals::makeMsgPackDeserializer(&destination.buffer(), json, | ||||
|                                             nestingLimit) | ||||
|       .parse(destination); | ||||
|   return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) | ||||
|       .parse(doc.template to<JsonVariant>()); | ||||
| } | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -68,7 +68,7 @@ add_subdirectory(DynamicJsonBuffer) | ||||
| add_subdirectory(IntegrationTests) | ||||
| add_subdirectory(JsonArray) | ||||
| add_subdirectory(JsonObject) | ||||
| add_subdirectory(JsonParser) | ||||
| add_subdirectory(JsonDeserializer) | ||||
| add_subdirectory(JsonSerializer) | ||||
| add_subdirectory(JsonVariant) | ||||
| add_subdirectory(JsonWriter) | ||||
|   | ||||
| @@ -18,8 +18,7 @@ std::stringstream allocatorLog; | ||||
|  | ||||
| struct SpyingAllocator : DefaultAllocator { | ||||
|   void* allocate(size_t n) { | ||||
|     allocatorLog << static_cast<const char*>("A") | ||||
|                  << (n - DynamicJsonBuffer::EmptyBlockSize); | ||||
|     allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize); | ||||
|     return DefaultAllocator::allocate(n); | ||||
|   } | ||||
|   void deallocate(void* p) { | ||||
|   | ||||
| @@ -23,19 +23,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { | ||||
|   } | ||||
|  | ||||
|   // TODO: uncomment | ||||
|   // SECTION("parseArray()") { | ||||
|   //   char json[] = "[{}]"; | ||||
|   //   DynamicJsonArray arr; | ||||
|  | ||||
|   //   JsonError err = deserializeJson(arr, json); | ||||
|  | ||||
|   //   REQUIRE(err != JsonError::Ok); | ||||
|   // } | ||||
|  | ||||
|   // TODO: uncomment | ||||
|   // SECTION("parseObject()") { | ||||
|   // SECTION("deserializeJson()") { | ||||
|   //   char json[] = "{[]}"; | ||||
|   //   DynamicJsonObject obj; | ||||
|   //   DynamicJsonDocument obj; | ||||
|  | ||||
|   //   JsonError err = deserializeJson(obj, json); | ||||
|  | ||||
|   | ||||
| @@ -2,9 +2,11 @@ | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <ArduinoJson/Memory/DynamicJsonBuffer.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| TEST_CASE("DynamicJsonBuffer::size()") { | ||||
|   DynamicJsonBuffer buffer; | ||||
|  | ||||
|   | ||||
| @@ -2,9 +2,11 @@ | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <ArduinoJson/Memory/DynamicJsonBuffer.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| TEST_CASE("DynamicJsonBuffer::startString()") { | ||||
|   SECTION("WorksWhenBufferIsBigEnough") { | ||||
|     DynamicJsonBuffer jsonBuffer(6); | ||||
|   | ||||
| @@ -6,10 +6,10 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("Gbathree") { | ||||
|   DynamicJsonObject _object; | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   JsonError error = deserializeJson( | ||||
|       _object, | ||||
|       doc, | ||||
|       "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," | ||||
|       "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" | ||||
|       "baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":" | ||||
| @@ -20,67 +20,68 @@ TEST_CASE("Gbathree") { | ||||
|       "\"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]}"); | ||||
|   JsonObject& root = doc.as<JsonObject>(); | ||||
|  | ||||
|   SECTION("Success") { | ||||
|     REQUIRE(error == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("ProtocolName") { | ||||
|     REQUIRE("fluorescence" == _object["protocol_name"]); | ||||
|     REQUIRE("fluorescence" == root["protocol_name"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Repeats") { | ||||
|     REQUIRE(1 == _object["repeats"]); | ||||
|     REQUIRE(1 == root["repeats"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Wait") { | ||||
|     REQUIRE(0 == _object["wait"]); | ||||
|     REQUIRE(0 == root["wait"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Measurements") { | ||||
|     REQUIRE(3 == _object["measurements"]); | ||||
|     REQUIRE(3 == root["measurements"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Meas2_Light") { | ||||
|     REQUIRE(15 == _object["meas2_light"]); | ||||
|     REQUIRE(15 == root["meas2_light"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Meas1_Baseline") { | ||||
|     REQUIRE(0 == _object["meas1_baseline"]); | ||||
|     REQUIRE(0 == root["meas1_baseline"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Act_Light") { | ||||
|     REQUIRE(20 == _object["act_light"]); | ||||
|     REQUIRE(20 == root["act_light"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Pulsesize") { | ||||
|     REQUIRE(25 == _object["pulsesize"]); | ||||
|     REQUIRE(25 == root["pulsesize"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Pulsedistance") { | ||||
|     REQUIRE(10000 == _object["pulsedistance"]); | ||||
|     REQUIRE(10000 == root["pulsedistance"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Actintensity1") { | ||||
|     REQUIRE(50 == _object["actintensity1"]); | ||||
|     REQUIRE(50 == root["actintensity1"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Actintensity2") { | ||||
|     REQUIRE(255 == _object["actintensity2"]); | ||||
|     REQUIRE(255 == root["actintensity2"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Measintensity") { | ||||
|     REQUIRE(255 == _object["measintensity"]); | ||||
|     REQUIRE(255 == root["measintensity"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Calintensity") { | ||||
|     REQUIRE(255 == _object["calintensity"]); | ||||
|     REQUIRE(255 == root["calintensity"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("Pulses") { | ||||
|     // "pulses":[50,50,50] | ||||
|  | ||||
|     JsonArray& array = _object["pulses"]; | ||||
|     JsonArray& array = root["pulses"]; | ||||
|     REQUIRE(array.success()); | ||||
|  | ||||
|     REQUIRE(3 == array.size()); | ||||
| @@ -93,7 +94,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Act") { | ||||
|     // "act":[2,1,2,2] | ||||
|  | ||||
|     JsonArray& array = _object["act"]; | ||||
|     JsonArray& array = root["act"]; | ||||
|     REQUIRE(array.success()); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
| @@ -106,7 +107,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Detectors") { | ||||
|     // "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]] | ||||
|  | ||||
|     JsonArray& array = _object["detectors"]; | ||||
|     JsonArray& array = root["detectors"]; | ||||
|     REQUIRE(array.success()); | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
| @@ -123,7 +124,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Alta") { | ||||
|     // alta:[2,2,2,2] | ||||
|  | ||||
|     JsonArray& array = _object["alta"]; | ||||
|     JsonArray& array = root["alta"]; | ||||
|     REQUIRE(array.success()); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
| @@ -136,7 +137,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Altb") { | ||||
|     // altb:[2,2,2,2] | ||||
|  | ||||
|     JsonArray& array = _object["altb"]; | ||||
|     JsonArray& array = root["altb"]; | ||||
|     REQUIRE(array.success()); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
| @@ -149,7 +150,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Measlights") { | ||||
|     // "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] | ||||
|  | ||||
|     JsonArray& array = _object["measlights"]; | ||||
|     JsonArray& array = root["measlights"]; | ||||
|     REQUIRE(array.success()); | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
| @@ -167,7 +168,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Measlights2") { | ||||
|     // "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] | ||||
|  | ||||
|     JsonArray& array = _object["measlights2"]; | ||||
|     JsonArray& array = root["measlights2"]; | ||||
|     REQUIRE(array.success()); | ||||
|     REQUIRE(4 == array.size()); | ||||
|  | ||||
| @@ -184,7 +185,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Altc") { | ||||
|     // altc:[2,2,2,2] | ||||
|  | ||||
|     JsonArray& array = _object["altc"]; | ||||
|     JsonArray& array = root["altc"]; | ||||
|     REQUIRE(array.success()); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
| @@ -197,7 +198,7 @@ TEST_CASE("Gbathree") { | ||||
|   SECTION("Altd") { | ||||
|     // altd:[2,2,2,2] | ||||
|  | ||||
|     JsonArray& array = _object["altd"]; | ||||
|     JsonArray& array = root["altd"]; | ||||
|     REQUIRE(array.success()); | ||||
|  | ||||
|     REQUIRE(4 == array.size()); | ||||
|   | ||||
| @@ -6,15 +6,15 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| void check(std::string originalJson) { | ||||
|   DynamicJsonObject obj; | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   std::string prettyJson; | ||||
|   deserializeJson(obj, originalJson); | ||||
|   serializeJsonPretty(obj, prettyJson); | ||||
|   deserializeJson(doc, originalJson); | ||||
|   serializeJsonPretty(doc, prettyJson); | ||||
|  | ||||
|   std::string finalJson; | ||||
|   deserializeJson(obj, originalJson); | ||||
|   serializeJson(obj, finalJson); | ||||
|   deserializeJson(doc, originalJson); | ||||
|   serializeJson(doc, finalJson); | ||||
|  | ||||
|   REQUIRE(originalJson == finalJson); | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,8 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::add()") { | ||||
|   DynamicJsonArray _array; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray& _array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _array.add(123); | ||||
| @@ -38,7 +39,8 @@ TEST_CASE("JsonArray::add()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _array.add(arr); | ||||
|  | ||||
| @@ -48,7 +50,8 @@ TEST_CASE("JsonArray::add()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _array.add(obj); | ||||
|  | ||||
| @@ -59,7 +62,8 @@ TEST_CASE("JsonArray::add()") { | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     const char* str = "hello"; | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|     arr.add(str); | ||||
|  | ||||
|     _array.add(arr[0]); | ||||
| @@ -69,7 +73,8 @@ TEST_CASE("JsonArray::add()") { | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     const char* str = "hello"; | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj = doc2.to<JsonObject>(); | ||||
|     obj["x"] = str; | ||||
|  | ||||
|     _array.add(obj["x"]); | ||||
| @@ -80,30 +85,30 @@ TEST_CASE("JsonArray::add()") { | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array.add("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array.add(const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array.add(std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate RawJson(const char*)") { | ||||
|     _array.add(RawJson("{}")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate RawJson(char*)") { | ||||
|     _array.add(RawJson(const_cast<char*>("{}"))); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3; | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,8 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray basics") { | ||||
|   DynamicJsonArray array; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray& array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("SuccessIsTrue") { | ||||
|     REQUIRE(array.success()); | ||||
|   | ||||
| @@ -7,7 +7,8 @@ | ||||
|  | ||||
| TEST_CASE("JsonArray::copyFrom()") { | ||||
|   SECTION("OneDimension") { | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     char json[32]; | ||||
|     int source[] = {1, 2, 3}; | ||||
|  | ||||
| @@ -20,7 +21,8 @@ TEST_CASE("JsonArray::copyFrom()") { | ||||
|  | ||||
|   SECTION("OneDimension_JsonBufferTooSmall") { | ||||
|     const size_t SIZE = JSON_ARRAY_SIZE(2); | ||||
|     StaticJsonArray<SIZE> array; | ||||
|     StaticJsonDocument<SIZE> doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     char json[32]; | ||||
|     int source[] = {1, 2, 3}; | ||||
|  | ||||
| @@ -32,7 +34,8 @@ TEST_CASE("JsonArray::copyFrom()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("TwoDimensions") { | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     char json[32]; | ||||
|     int source[][3] = {{1, 2, 3}, {4, 5, 6}}; | ||||
|  | ||||
| @@ -46,7 +49,8 @@ TEST_CASE("JsonArray::copyFrom()") { | ||||
|   SECTION("TwoDimensions_JsonBufferTooSmall") { | ||||
|     const size_t SIZE = | ||||
|         JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); | ||||
|     StaticJsonArray<SIZE> array; | ||||
|     StaticJsonDocument<SIZE> doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     char json[32]; | ||||
|     int source[][3] = {{1, 2, 3}, {4, 5, 6}}; | ||||
|  | ||||
|   | ||||
| @@ -6,12 +6,13 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::copyTo()") { | ||||
|   DynamicJsonArray array; | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("BiggerOneDimensionIntegerArray") { | ||||
|     char json[] = "[1,2,3]"; | ||||
|     JsonError err = deserializeJson(array, json); | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|     int destination[4] = {0}; | ||||
|     size_t result = array.copyTo(destination); | ||||
| @@ -25,8 +26,9 @@ TEST_CASE("JsonArray::copyTo()") { | ||||
|  | ||||
|   SECTION("SmallerOneDimensionIntegerArray") { | ||||
|     char json[] = "[1,2,3]"; | ||||
|     JsonError err = deserializeJson(array, json); | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|     int destination[2] = {0}; | ||||
|     size_t result = array.copyTo(destination); | ||||
| @@ -39,8 +41,9 @@ TEST_CASE("JsonArray::copyTo()") { | ||||
|   SECTION("TwoOneDimensionIntegerArray") { | ||||
|     char json[] = "[[1,2],[3],[4]]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(array, json); | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|     int destination[3][2] = {{0}}; | ||||
|     array.copyTo(destination); | ||||
|   | ||||
| @@ -7,7 +7,8 @@ | ||||
|  | ||||
| template <typename TIterator> | ||||
| static void run_iterator_test() { | ||||
|   StaticJsonArray<JSON_ARRAY_SIZE(2)> array; | ||||
|   StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; | ||||
|   JsonArray& array = doc.to<JsonArray>(); | ||||
|   array.add(12); | ||||
|   array.add(34); | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,8 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::remove()") { | ||||
|   DynamicJsonArray _array; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray& _array = doc.to<JsonArray>(); | ||||
|   _array.add(1); | ||||
|   _array.add(2); | ||||
|   _array.add(3); | ||||
|   | ||||
| @@ -8,7 +8,8 @@ | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("JsonArray::set()") { | ||||
|   DynamicJsonArray _array; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray& _array = doc.to<JsonArray>(); | ||||
|   _array.add(0); | ||||
|  | ||||
|   SECTION("int") { | ||||
| @@ -40,7 +41,8 @@ TEST_CASE("JsonArray::set()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _array.set(0, arr); | ||||
|  | ||||
| @@ -50,7 +52,8 @@ TEST_CASE("JsonArray::set()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _array.set(0, obj); | ||||
|  | ||||
| @@ -60,7 +63,8 @@ TEST_CASE("JsonArray::set()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|  | ||||
|     _array.set(0, arr[0]); | ||||
| @@ -69,7 +73,8 @@ TEST_CASE("JsonArray::set()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj = doc2.to<JsonObject>(); | ||||
|     obj["x"] = "hello"; | ||||
|  | ||||
|     _array.set(0, obj["x"]); | ||||
| @@ -80,18 +85,18 @@ TEST_CASE("JsonArray::set()") { | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array.set(0, "world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array.set(0, const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array.set(0, std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,8 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::size()") { | ||||
|   DynamicJsonArray _array; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray& _array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("increases after add()") { | ||||
|     _array.add("hello"); | ||||
|   | ||||
| @@ -7,7 +7,8 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::operator[]") { | ||||
|   DynamicJsonArray _array; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray& _array = doc.to<JsonArray>(); | ||||
|   _array.add(0); | ||||
|  | ||||
|   SECTION("int") { | ||||
| @@ -51,7 +52,8 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|   } | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _array[0] = arr; | ||||
|  | ||||
| @@ -64,7 +66,8 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _array[0] = obj; | ||||
|  | ||||
| @@ -77,7 +80,8 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|     const char* str = "hello"; | ||||
|  | ||||
|     arr.add(str); | ||||
| @@ -88,8 +92,9 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     DynamicJsonObject obj; | ||||
|     const char* str = "hello"; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj = doc2.to<JsonObject>(); | ||||
|  | ||||
|     obj["x"] = str; | ||||
|  | ||||
| @@ -101,18 +106,18 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array[0] = "world"; | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array[0] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array[0] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _array.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										16
									
								
								test/JsonDeserializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/JsonDeserializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2018 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonDeserializerTests | ||||
| 	deserializeJsonArray.cpp | ||||
| 	deserializeJsonArrayStatic.cpp | ||||
| 	deserializeJsonObject.cpp | ||||
| 	deserializeJsonObjectStatic.cpp | ||||
| 	deserializeJsonValue.cpp | ||||
| 	JsonError.cpp | ||||
| 	nestingLimit.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonDeserializerTests catch) | ||||
| add_test(JsonDeserializer JsonDeserializerTests) | ||||
| @@ -22,23 +22,21 @@ void testBoolification(JsonError error, bool expected) { | ||||
| TEST_CASE("JsonError") { | ||||
|   SECTION("c_str()") { | ||||
|     TEST_STRINGIFICATION(Ok); | ||||
|     TEST_STRINGIFICATION(OpeningBraceExpected); | ||||
|     TEST_STRINGIFICATION(ClosingBraceExpected); | ||||
|     TEST_STRINGIFICATION(OpeningBracketExpected); | ||||
|     TEST_STRINGIFICATION(ClosingBracketExpected); | ||||
|     TEST_STRINGIFICATION(ColonExpected); | ||||
|     TEST_STRINGIFICATION(TooDeep); | ||||
|     TEST_STRINGIFICATION(NoMemory); | ||||
|     TEST_STRINGIFICATION(InvalidInput); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("as boolean") { | ||||
|     TEST_BOOLIFICATION(Ok, false); | ||||
|     TEST_BOOLIFICATION(OpeningBraceExpected, true); | ||||
|     TEST_BOOLIFICATION(ClosingBraceExpected, true); | ||||
|     TEST_BOOLIFICATION(OpeningBracketExpected, true); | ||||
|     TEST_BOOLIFICATION(ClosingBracketExpected, true); | ||||
|     TEST_BOOLIFICATION(ColonExpected, true); | ||||
|     TEST_BOOLIFICATION(TooDeep, true); | ||||
|     TEST_BOOLIFICATION(NoMemory, true); | ||||
|     TEST_BOOLIFICATION(InvalidInput, true); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("ostream") { | ||||
|     std::stringstream s; | ||||
|     s << JsonError::InvalidInput; | ||||
|     REQUIRE(s.str() == "InvalidInput"); | ||||
|   } | ||||
| } | ||||
| @@ -5,11 +5,12 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| 
 | ||||
| TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|   DynamicJsonArray arr; | ||||
| TEST_CASE("deserialize JSON array") { | ||||
|   DynamicJsonDocument doc; | ||||
| 
 | ||||
|   SECTION("An empty array") { | ||||
|     JsonError err = deserializeJson(arr, "[]"); | ||||
|     JsonError err = deserializeJson(doc, "[]"); | ||||
|     JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(0 == arr.size()); | ||||
| @@ -17,14 +18,16 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
| 
 | ||||
|   SECTION("Spaces") { | ||||
|     SECTION("Before the opening bracket") { | ||||
|       JsonError err = deserializeJson(arr, "  []"); | ||||
|       JsonError err = deserializeJson(doc, "  []"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(0 == arr.size()); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Before first value") { | ||||
|       JsonError err = deserializeJson(arr, "[ \t\r\n42]"); | ||||
|       JsonError err = deserializeJson(doc, "[ \t\r\n42]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -32,7 +35,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After first value") { | ||||
|       JsonError err = deserializeJson(arr, "[42 \t\r\n]"); | ||||
|       JsonError err = deserializeJson(doc, "[42 \t\r\n]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -42,7 +46,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
| 
 | ||||
|   SECTION("Values types") { | ||||
|     SECTION("On integer") { | ||||
|       JsonError err = deserializeJson(arr, "[42]"); | ||||
|       JsonError err = deserializeJson(doc, "[42]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -50,7 +55,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Two integers") { | ||||
|       JsonError err = deserializeJson(arr, "[42,84]"); | ||||
|       JsonError err = deserializeJson(doc, "[42,84]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -59,7 +65,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Double") { | ||||
|       JsonError err = deserializeJson(arr, "[4.2,1e2]"); | ||||
|       JsonError err = deserializeJson(doc, "[4.2,1e2]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -68,7 +75,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Unsigned long") { | ||||
|       JsonError err = deserializeJson(arr, "[4294967295]"); | ||||
|       JsonError err = deserializeJson(doc, "[4294967295]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -76,7 +84,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Boolean") { | ||||
|       JsonError err = deserializeJson(arr, "[true,false]"); | ||||
|       JsonError err = deserializeJson(doc, "[true,false]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -85,7 +94,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Null") { | ||||
|       JsonError err = deserializeJson(arr, "[null,null]"); | ||||
|       JsonError err = deserializeJson(doc, "[null,null]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -96,7 +106,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
| 
 | ||||
|   SECTION("Quotes") { | ||||
|     SECTION("Double quotes") { | ||||
|       JsonError err = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); | ||||
|       JsonError err = deserializeJson(doc, "[ \"hello\" , \"world\" ]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -105,7 +116,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Single quotes") { | ||||
|       JsonError err = deserializeJson(arr, "[ 'hello' , 'world' ]"); | ||||
|       JsonError err = deserializeJson(doc, "[ 'hello' , 'world' ]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -114,7 +126,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("No quotes") { | ||||
|       JsonError err = deserializeJson(arr, "[ hello , world ]"); | ||||
|       JsonError err = deserializeJson(doc, "[ hello , world ]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -123,7 +136,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Double quotes (empty strings)") { | ||||
|       JsonError err = deserializeJson(arr, "[\"\",\"\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"\",\"\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -132,7 +146,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Single quotes (empty strings)") { | ||||
|       JsonError err = deserializeJson(arr, "[\'\',\'\']"); | ||||
|       JsonError err = deserializeJson(doc, "[\'\',\'\']"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -141,30 +156,28 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("No quotes (empty strings)") { | ||||
|       JsonError err = deserializeJson(arr, "[,]"); | ||||
|       JsonError err = deserializeJson(doc, "[,]"); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
|       REQUIRE(arr[0] == ""); | ||||
|       REQUIRE(arr[1] == ""); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Closing single quotes missing") { | ||||
|       JsonError err = deserializeJson(arr, "[\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"]"); | ||||
| 
 | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Closing double quotes missing") { | ||||
|       JsonError err = deserializeJson(arr, "[\']"); | ||||
|       JsonError err = deserializeJson(doc, "[\']"); | ||||
| 
 | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   SECTION("Block comments") { | ||||
|     SECTION("Before opening bracket") { | ||||
|       JsonError err = deserializeJson(arr, "/*COMMENT*/  [\"hello\"]"); | ||||
|       JsonError err = deserializeJson(doc, "/*COMMENT*/  [\"hello\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -172,7 +185,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After opening bracket") { | ||||
|       JsonError err = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[/*COMMENT*/ \"hello\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -180,7 +194,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Before closing bracket") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -188,7 +203,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After closing bracket") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -196,7 +212,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Before comma") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -205,7 +222,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After comma") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -214,24 +232,25 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("/*/") { | ||||
|       JsonError err = deserializeJson(arr, "[/*/\n]"); | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       JsonError err = deserializeJson(doc, "[/*/\n]"); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Unfinished comment") { | ||||
|       JsonError err = deserializeJson(arr, "[/*COMMENT]"); | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       JsonError err = deserializeJson(doc, "[/*COMMENT]"); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Final slash missing") { | ||||
|       JsonError err = deserializeJson(arr, "[/*COMMENT*]"); | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       JsonError err = deserializeJson(doc, "[/*COMMENT*]"); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   SECTION("Line comments") { | ||||
|     SECTION("Before opening bracket") { | ||||
|       JsonError err = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); | ||||
|       JsonError err = deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -239,7 +258,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After opening bracket") { | ||||
|       JsonError err = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -247,7 +267,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Before closing bracket") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\r\n]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -255,7 +276,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After closing bracket") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
| @@ -263,7 +285,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Before comma") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -272,7 +295,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After comma") { | ||||
|       JsonError err = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); | ||||
|       JsonError err = deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(2 == arr.size()); | ||||
| @@ -281,53 +305,51 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Invalid comment") { | ||||
|       JsonError err = deserializeJson(arr, "[/COMMENT\n]"); | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       JsonError err = deserializeJson(doc, "[/COMMENT\n]"); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("End document with comment") { | ||||
|       JsonError err = deserializeJson(arr, "[//COMMENT"); | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       JsonError err = deserializeJson(doc, "[//COMMENT"); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   SECTION("Misc") { | ||||
|     SECTION("Garbage") { | ||||
|       JsonError err = deserializeJson(arr, "%*$£¤"); | ||||
|       JsonError err = deserializeJson(doc, "%*$£¤"); | ||||
| 
 | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("The opening bracket is missing") { | ||||
|       JsonError err = deserializeJson(arr, "]"); | ||||
|       JsonError err = deserializeJson(doc, "]"); | ||||
| 
 | ||||
|       REQUIRE(err != JsonError::Ok);  // TODO
 | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("The closing bracket is missing") { | ||||
|       JsonError err = deserializeJson(arr, "["); | ||||
|       REQUIRE(err != JsonError::Ok);  // TODO
 | ||||
|       JsonError err = deserializeJson(doc, "["); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Escape sequences") { | ||||
|       JsonError err = | ||||
|           deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); | ||||
|           deserializeJson(doc, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(1 == arr.size()); | ||||
|       REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Unterminated escape sequence") { | ||||
|       JsonError err = deserializeJson(arr, "\"\\\0\"", 4); | ||||
|       REQUIRE(err != JsonError::Ok); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Nested objects") { | ||||
|       char jsonString[] = | ||||
|           " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; | ||||
| 
 | ||||
|       JsonError err = deserializeJson(arr, jsonString); | ||||
|       JsonError err = deserializeJson(doc, jsonString); | ||||
|       JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|       JsonObject& object1 = arr[0]; | ||||
|       const JsonObject& object2 = arr[1]; | ||||
| @@ -352,10 +374,11 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { | ||||
|   } | ||||
| 
 | ||||
|   SECTION("Should clear the JsonArray") { | ||||
|     deserializeJson(arr, "[1,2,3,4]"); | ||||
|     deserializeJson(arr, "[]"); | ||||
|     deserializeJson(doc, "[1,2,3,4]"); | ||||
|     deserializeJson(doc, "[]"); | ||||
|     JsonArray& arr = doc.as<JsonArray>(); | ||||
| 
 | ||||
|     REQUIRE(arr.size() == 0); | ||||
|     REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										105
									
								
								test/JsonDeserializer/deserializeJsonArrayStatic.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								test/JsonDeserializer/deserializeJsonArrayStatic.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserialize JSON array with a StaticJsonDocument") { | ||||
|   SECTION("BufferOfTheRightSizeForEmptyArray") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc; | ||||
|     char input[] = "[]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForArrayWithOneValue") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1) - 1> doc; | ||||
|     char input[] = "[1]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForArrayWithOneValue") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; | ||||
|     char input[] = "[1]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForArrayWithNestedObject") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1> doc; | ||||
|     char input[] = "[{}]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> doc; | ||||
|     char input[] = "[{}]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("CharPtrNull") { | ||||
|     StaticJsonDocument<100> doc; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, static_cast<char*>(0)); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("ConstCharPtrNull") { | ||||
|     StaticJsonDocument<100> doc; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, static_cast<const char*>(0)); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("CopyStringNotSpaces") { | ||||
|     StaticJsonDocument<100> doc; | ||||
|  | ||||
|     deserializeJson(doc, "  [ \"1234567\" ] "); | ||||
|  | ||||
|     REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == doc.memoryUsage()); | ||||
|     // note: we use a string of 8 bytes to be sure that the StaticJsonBuffer | ||||
|     // will not insert bytes to enforce alignement | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonArray") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(4)> doc; | ||||
|     char input[] = "[1,2,3,4]"; | ||||
|  | ||||
|     deserializeJson(doc, input); | ||||
|     deserializeJson(doc, "[]"); | ||||
|  | ||||
|     JsonArray& arr = doc.as<JsonArray>(); | ||||
|     REQUIRE(arr.size() == 0); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|   } | ||||
|  | ||||
|   SECTION("Array") { | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; | ||||
|     char input[] = "[1,2]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
|     JsonArray& arr = doc.as<JsonArray>(); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<JsonArray>()); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); | ||||
|     REQUIRE(arr[0] == 1); | ||||
|     REQUIRE(arr[1] == 2); | ||||
|   } | ||||
| } | ||||
| @@ -5,40 +5,55 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| 
 | ||||
| TEST_CASE("deserializeJson(DynamicJsonObject&)") { | ||||
|   DynamicJsonObject obj; | ||||
| TEST_CASE("deserialize JSON object") { | ||||
|   DynamicJsonDocument doc; | ||||
| 
 | ||||
|   SECTION("An empty object") { | ||||
|     JsonError err = deserializeJson(obj, "{}"); | ||||
|     JsonError err = deserializeJson(doc, "{}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<JsonObject>()); | ||||
|     REQUIRE(obj.size() == 0); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("Quotes") { | ||||
|     SECTION("Double quotes") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key\":\"value\"}"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key\":\"value\"}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Single quotes") { | ||||
|       JsonError err = deserializeJson(obj, "{'key':'value'}"); | ||||
|       JsonError err = deserializeJson(doc, "{'key':'value'}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("No quotes") { | ||||
|       JsonError err = deserializeJson(obj, "{key:value}"); | ||||
|       JsonError err = deserializeJson(doc, "{key:value}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("No quotes, allow underscore in key") { | ||||
|       JsonError err = deserializeJson(obj, "{_k_e_y_:42}"); | ||||
|       JsonError err = deserializeJson(doc, "{_k_e_y_:42}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["_k_e_y_"] == 42); | ||||
|     } | ||||
| @@ -46,37 +61,52 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { | ||||
| 
 | ||||
|   SECTION("Spaces") { | ||||
|     SECTION("Before the key") { | ||||
|       JsonError err = deserializeJson(obj, "{ \"key\":\"value\"}"); | ||||
|       JsonError err = deserializeJson(doc, "{ \"key\":\"value\"}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After the key") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key\" :\"value\"}"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key\" :\"value\"}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Before the value") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key\": \"value\"}"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key\": \"value\"}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("After the value") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key\":\"value\" }"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key\":\"value\" }"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 1); | ||||
|       REQUIRE(obj["key"] == "value"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Before the colon") { | ||||
|       JsonError err = | ||||
|           deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|           deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
| @@ -84,8 +114,11 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { | ||||
| 
 | ||||
|     SECTION("After the colon") { | ||||
|       JsonError err = | ||||
|           deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|           deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
| @@ -95,40 +128,55 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { | ||||
|   SECTION("Values types") { | ||||
|     SECTION("String") { | ||||
|       JsonError err = | ||||
|           deserializeJson(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|           deserializeJson(doc, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == "value1"); | ||||
|       REQUIRE(obj["key2"] == "value2"); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Integer") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key1\":42,\"key2\":-42}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == 42); | ||||
|       REQUIRE(obj["key2"] == -42); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Double") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == 12.345); | ||||
|       REQUIRE(obj["key2"] == -7E89); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Booleans") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key1\":true,\"key2\":false}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"] == true); | ||||
|       REQUIRE(obj["key2"] == false); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("Null") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); | ||||
|       JsonError err = deserializeJson(doc, "{\"key1\":null,\"key2\":null}"); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["key1"].as<char*>() == 0); | ||||
|       REQUIRE(obj["key2"].as<char*>() == 0); | ||||
| @@ -137,7 +185,8 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { | ||||
|     SECTION("Array") { | ||||
|       char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; | ||||
| 
 | ||||
|       JsonError err = deserializeJson(obj, jsonString); | ||||
|       JsonError err = deserializeJson(doc, jsonString); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|       JsonArray& array1 = obj["ab"]; | ||||
|       const JsonArray& array2 = obj["cd"]; | ||||
| @@ -165,40 +214,49 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { | ||||
| 
 | ||||
|   SECTION("Misc") { | ||||
|     SECTION("The opening brace is missing") { | ||||
|       JsonError err = deserializeJson(obj, "}"); | ||||
|       REQUIRE(err == JsonError::OpeningBraceExpected); | ||||
|       JsonError err = deserializeJson(doc, "}"); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("The closing brace is missing") { | ||||
|       JsonError err = deserializeJson(obj, "{\"hello\":\"world\""); | ||||
|       REQUIRE(err == JsonError::ClosingBraceExpected); | ||||
|       JsonError err = deserializeJson(doc, "{\"hello\":\"world\""); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("A quoted key without value") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key\"}"); | ||||
|       REQUIRE(err == JsonError::ColonExpected); | ||||
|       JsonError err = deserializeJson(doc, "{\"key\"}"); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("A non-quoted key without value") { | ||||
|       JsonError err = deserializeJson(obj, "{key}"); | ||||
|       REQUIRE(err == JsonError::ColonExpected); | ||||
|       JsonError err = deserializeJson(doc, "{key}"); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("A dangling comma") { | ||||
|       JsonError err = deserializeJson(obj, "{\"key1\":\"value1\",}"); | ||||
|       REQUIRE(err == JsonError::ColonExpected); | ||||
|       JsonError err = deserializeJson(doc, "{\"key1\":\"value1\",}"); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::InvalidInput); | ||||
|     } | ||||
| 
 | ||||
|     SECTION("null as a key") { | ||||
|       JsonError err = deserializeJson(obj, "{null:\"value\"}"); | ||||
|       JsonError err = deserializeJson(doc, "{null:\"value\"}"); | ||||
| 
 | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   SECTION("Should clear the JsonObject") { | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|     deserializeJson(obj, "{}"); | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     deserializeJson(doc, "{}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
| 
 | ||||
|     REQUIRE(doc.is<JsonObject>()); | ||||
|     REQUIRE(obj.size() == 0); | ||||
|     REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
| @@ -5,76 +5,76 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| 
 | ||||
| TEST_CASE("deserializeJson(StaticJsonObject&)") { | ||||
| TEST_CASE("deserialize JSON object with StaticJsonDocument") { | ||||
|   SECTION("BufferOfTheRightSizeForEmptyObject") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(0)> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc; | ||||
|     char input[] = "{}"; | ||||
| 
 | ||||
|     JsonError err = deserializeJson(obj, input); | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("TooSmallBufferForObjectWithOneValue") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1) - 1> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1) - 1> doc; | ||||
|     char input[] = "{\"a\":1}"; | ||||
| 
 | ||||
|     JsonError err = deserializeJson(obj, input); | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("BufferOfTheRightSizeForObjectWithOneValue") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1)> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     char input[] = "{\"a\":1}"; | ||||
| 
 | ||||
|     JsonError err = deserializeJson(obj, input); | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("TooSmallBufferForObjectWithNestedObject") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0) - 1> doc; | ||||
|     char input[] = "{\"a\":[]}"; | ||||
| 
 | ||||
|     JsonError err = deserializeJson(obj, input); | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1) + JSON_ARRAY_SIZE(0)> doc; | ||||
|     char input[] = "{\"a\":[]}"; | ||||
| 
 | ||||
|     JsonError err = deserializeJson(obj, input); | ||||
|     JsonError err = deserializeJson(doc, input); | ||||
| 
 | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("CharPtrNull") { | ||||
|     StaticJsonObject<100> obj; | ||||
|     StaticJsonDocument<100> doc; | ||||
| 
 | ||||
|     JsonError err = deserializeJson(obj, static_cast<char*>(0)); | ||||
|     JsonError err = deserializeJson(doc, static_cast<char*>(0)); | ||||
| 
 | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("ConstCharPtrNull") { | ||||
|     StaticJsonObject<100> obj; | ||||
|     StaticJsonDocument<100> doc; | ||||
| 
 | ||||
|     JsonError err = deserializeJson(obj, static_cast<const char*>(0)); | ||||
|     JsonError err = deserializeJson(doc, static_cast<const char*>(0)); | ||||
| 
 | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
| 
 | ||||
|   SECTION("Should clear the JsonObject") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1)> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     char input[] = "{\"hello\":\"world\"}"; | ||||
| 
 | ||||
|     deserializeJson(obj, input); | ||||
|     deserializeJson(obj, "{}"); | ||||
|     deserializeJson(doc, input); | ||||
|     deserializeJson(doc, "{}"); | ||||
| 
 | ||||
|     REQUIRE(obj.size() == 0); | ||||
|     REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|     REQUIRE(doc.as<JsonObject>().size() == 0); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										103
									
								
								test/JsonDeserializer/deserializeJsonValue.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								test/JsonDeserializer/deserializeJsonValue.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("deserializeJson(DynamicJsonDocument&)") { | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("EmptyObject") { | ||||
|     JsonError err = deserializeJson(doc, "{}"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<JsonObject>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("EmptyArray") { | ||||
|     JsonError err = deserializeJson(doc, "[]"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<JsonArray>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("Integer") { | ||||
|     JsonError err = deserializeJson(doc, "-42"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<int>()); | ||||
|     REQUIRE_FALSE(doc.is<bool>()); | ||||
|     REQUIRE(doc.as<int>() == -42); | ||||
|   } | ||||
|  | ||||
|   SECTION("Double") { | ||||
|     JsonError err = deserializeJson(doc, "-1.23e+4"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE_FALSE(doc.is<int>()); | ||||
|     REQUIRE(doc.is<double>()); | ||||
|     REQUIRE(doc.as<double>() == Approx(-1.23e+4)); | ||||
|   } | ||||
|  | ||||
|   SECTION("Double quoted string") { | ||||
|     JsonError err = deserializeJson(doc, "\"hello world\""); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<char*>()); | ||||
|     REQUIRE_THAT(doc.as<char*>(), Equals("hello world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("Single quoted string") { | ||||
|     JsonError err = deserializeJson(doc, "\'hello world\'"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<char*>()); | ||||
|     REQUIRE_THAT(doc.as<char*>(), Equals("hello world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("True") { | ||||
|     JsonError err = deserializeJson(doc, "true"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<bool>()); | ||||
|     REQUIRE(doc.as<bool>() == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("False") { | ||||
|     JsonError err = deserializeJson(doc, "false"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<bool>()); | ||||
|     REQUIRE(doc.as<bool>() == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("OpenBrace") { | ||||
|     JsonError err = deserializeJson(doc, "{"); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("Incomplete string") { | ||||
|     JsonError err = deserializeJson(doc, "\"hello"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(doc.is<char*>()); | ||||
|     REQUIRE_THAT(doc.as<char*>(), Equals("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("Unterminated escape sequence") { | ||||
|     JsonError err = deserializeJson(doc, "\"\\\0\""); | ||||
|     REQUIRE(err == JsonError::InvalidInput); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonVariant") { | ||||
|     deserializeJson(doc, "[1,2,3]"); | ||||
|     deserializeJson(doc, "{}"); | ||||
|  | ||||
|     REQUIRE(doc.is<JsonObject>()); | ||||
|     REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										32
									
								
								test/JsonDeserializer/nestingLimit.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								test/JsonDeserializer/nestingLimit.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| #define SHOULD_WORK(expression) REQUIRE(JsonError::Ok == expression); | ||||
| #define SHOULD_FAIL(expression) REQUIRE(JsonError::TooDeep == expression); | ||||
|  | ||||
| TEST_CASE("JsonDeserializer nestingLimit") { | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("limit = 0") { | ||||
|     SHOULD_WORK(deserializeJson(doc, "\"toto\"", 0)); | ||||
|     SHOULD_WORK(deserializeJson(doc, "123", 0)); | ||||
|     SHOULD_WORK(deserializeJson(doc, "true", 0)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "[]", 0)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "{}", 0)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "[\"toto\"]", 0)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "{\"toto\":1}", 0)); | ||||
|   } | ||||
|  | ||||
|   SECTION("limit = 1") { | ||||
|     SHOULD_WORK(deserializeJson(doc, "[\"toto\"]", 1)); | ||||
|     SHOULD_WORK(deserializeJson(doc, "{\"toto\":1}", 1)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "{\"toto\":{}}", 1)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "{\"toto\":[]}", 1)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "[[\"toto\"]]", 1)); | ||||
|     SHOULD_FAIL(deserializeJson(doc, "[{\"toto\":1}]", 1)); | ||||
|   } | ||||
| } | ||||
| @@ -6,13 +6,10 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject basics") { | ||||
|   DynamicJsonObject _object; | ||||
|  | ||||
|   SECTION("InitialSizeIsZero") { | ||||
|     REQUIRE(0 == _object.size()); | ||||
|   } | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("SuccessIsTrue") { | ||||
|     REQUIRE(_object.success()); | ||||
|     REQUIRE(obj.success()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -6,24 +6,25 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::containsKey()") { | ||||
|   DynamicJsonObject _object; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("ContainsKeyReturnsFalseForNonExistingKey") { | ||||
|     _object.set("hello", 42); | ||||
|     obj.set("hello", 42); | ||||
|  | ||||
|     REQUIRE(false == _object.containsKey("world")); | ||||
|     REQUIRE(false == obj.containsKey("world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("ContainsKeyReturnsTrueForDefinedValue") { | ||||
|     _object.set("hello", 42); | ||||
|     obj.set("hello", 42); | ||||
|  | ||||
|     REQUIRE(true == _object.containsKey("hello")); | ||||
|     REQUIRE(true == obj.containsKey("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("ContainsKeyReturnsFalseAfterRemove") { | ||||
|     _object.set("hello", 42); | ||||
|     _object.remove("hello"); | ||||
|     obj.set("hello", 42); | ||||
|     obj.remove("hello"); | ||||
|  | ||||
|     REQUIRE(false == _object.containsKey("hello")); | ||||
|     REQUIRE(false == obj.containsKey("hello")); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -8,7 +8,8 @@ | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("JsonObject::get()") { | ||||
|   DynamicJsonObject obj; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("GetConstCharPointer_GivenStringLiteral") { | ||||
|     obj.set("hello", "world"); | ||||
|   | ||||
| @@ -8,7 +8,8 @@ | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("JsonObject::begin()/end()") { | ||||
|   StaticJsonObject<JSON_OBJECT_SIZE(2)> obj; | ||||
|   StaticJsonDocument<JSON_OBJECT_SIZE(2)> doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|   obj["ab"] = 12; | ||||
|   obj["cd"] = 34; | ||||
|  | ||||
|   | ||||
| @@ -7,7 +7,8 @@ | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonObject::remove()") { | ||||
|   DynamicJsonObject obj; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("SizeDecreased_WhenValuesAreRemoved") { | ||||
|     obj["hello"] = 1; | ||||
| @@ -26,7 +27,9 @@ TEST_CASE("JsonObject::remove()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("RemoveByIterator") { | ||||
|     deserializeJson(obj, "{\"a\":0,\"b\":1,\"c\":2}"); | ||||
|     obj["a"] = 0; | ||||
|     obj["b"] = 1; | ||||
|     obj["c"] = 2; | ||||
|  | ||||
|     for (JsonObject::iterator it = obj.begin(); it != obj.end(); ++it) { | ||||
|       if (it->value == 1) obj.remove(it); | ||||
|   | ||||
| @@ -7,129 +7,136 @@ | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonObject::set()") { | ||||
|   DynamicJsonObject _object; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _object.set("hello", 123); | ||||
|     obj.set("hello", 123); | ||||
|  | ||||
|     REQUIRE(123 == _object["hello"].as<int>()); | ||||
|     REQUIRE(_object["hello"].is<int>()); | ||||
|     REQUIRE_FALSE(_object["hello"].is<bool>()); | ||||
|     REQUIRE(123 == obj["hello"].as<int>()); | ||||
|     REQUIRE(obj["hello"].is<int>()); | ||||
|     REQUIRE_FALSE(obj["hello"].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     _object.set("hello", 123.45); | ||||
|     obj.set("hello", 123.45); | ||||
|  | ||||
|     REQUIRE(123.45 == _object["hello"].as<double>()); | ||||
|     REQUIRE(_object["hello"].is<double>()); | ||||
|     REQUIRE_FALSE(_object["hello"].is<bool>()); | ||||
|     REQUIRE(123.45 == obj["hello"].as<double>()); | ||||
|     REQUIRE(obj["hello"].is<double>()); | ||||
|     REQUIRE_FALSE(obj["hello"].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     _object.set("hello", true); | ||||
|     obj.set("hello", true); | ||||
|  | ||||
|     REQUIRE(_object["hello"].as<bool>()); | ||||
|     REQUIRE(_object["hello"].is<bool>()); | ||||
|     REQUIRE_FALSE(_object["hello"].is<long>()); | ||||
|     REQUIRE(obj["hello"].as<bool>()); | ||||
|     REQUIRE(obj["hello"].is<bool>()); | ||||
|     REQUIRE_FALSE(obj["hello"].is<long>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     _object.set("hello", "h3110"); | ||||
|     obj.set("hello", "h3110"); | ||||
|  | ||||
|     REQUIRE(std::string("h3110") == _object["hello"].as<const char*>()); | ||||
|     REQUIRE(_object["hello"].is<const char*>()); | ||||
|     REQUIRE_FALSE(_object["hello"].is<long>()); | ||||
|     REQUIRE(std::string("h3110") == obj["hello"].as<const char*>()); | ||||
|     REQUIRE(obj["hello"].is<const char*>()); | ||||
|     REQUIRE_FALSE(obj["hello"].is<long>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested array") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _object.set("hello", arr); | ||||
|     obj.set("hello", arr); | ||||
|  | ||||
|     REQUIRE(&arr == &_object["hello"].as<JsonArray>()); | ||||
|     REQUIRE(_object["hello"].is<JsonArray&>()); | ||||
|     REQUIRE_FALSE(_object["hello"].is<JsonObject&>()); | ||||
|     REQUIRE(&arr == &obj["hello"].as<JsonArray>()); | ||||
|     REQUIRE(obj["hello"].is<JsonArray&>()); | ||||
|     REQUIRE_FALSE(obj["hello"].is<JsonObject&>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("nested object") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj2 = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _object.set("hello", obj); | ||||
|     obj.set("hello", obj2); | ||||
|  | ||||
|     REQUIRE(&obj == &_object["hello"].as<JsonObject>()); | ||||
|     REQUIRE(_object["hello"].is<JsonObject&>()); | ||||
|     REQUIRE_FALSE(_object["hello"].is<JsonArray&>()); | ||||
|     REQUIRE(&obj2 == &obj["hello"].as<JsonObject>()); | ||||
|     REQUIRE(obj["hello"].is<JsonObject&>()); | ||||
|     REQUIRE_FALSE(obj["hello"].is<JsonArray&>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|     arr.add(42); | ||||
|  | ||||
|     _object.set("a", arr[0]); | ||||
|     obj.set("a", arr[0]); | ||||
|  | ||||
|     REQUIRE(42 == _object["a"]); | ||||
|     REQUIRE(42 == obj["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     DynamicJsonObject obj; | ||||
|     obj.set("x", 42); | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj2 = doc2.to<JsonObject>(); | ||||
|     obj2.set("x", 42); | ||||
|  | ||||
|     _object.set("a", obj["x"]); | ||||
|     obj.set("a", obj2["x"]); | ||||
|  | ||||
|     REQUIRE(42 == _object["a"]); | ||||
|     REQUIRE(42 == obj["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns true when allocation succeeds") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1) + 15> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1) + 15> doc2; | ||||
|     JsonObject& obj2 = doc2.to<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(true == obj.set(std::string("hello"), std::string("world"))); | ||||
|     REQUIRE(true == obj2.set(std::string("hello"), std::string("world"))); | ||||
|   } | ||||
|  | ||||
|   SECTION("returns false when allocation fails") { | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1) + 10> obj; | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1) + 10> doc2; | ||||
|     JsonObject& obj2 = doc2.to<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(false == obj.set(std::string("hello"), std::string("world"))); | ||||
|     REQUIRE(false == obj2.set(std::string("hello"), std::string("world"))); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _object.set("hello", "world"); | ||||
|     obj.set("hello", "world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1); | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* value") { | ||||
|     _object.set("hello", const_cast<char*>("world")); | ||||
|     obj.set("hello", const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key") { | ||||
|     _object.set(const_cast<char*>("hello"), "world"); | ||||
|     obj.set(const_cast<char*>("hello"), "world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key&value") { | ||||
|     _object.set(const_cast<char*>("hello"), const_cast<char*>("world")); | ||||
|     obj.set(const_cast<char*>("hello"), const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string value") { | ||||
|     _object.set("hello", std::string("world")); | ||||
|     obj.set("hello", std::string("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key") { | ||||
|     _object.set(std::string("hello"), "world"); | ||||
|     obj.set(std::string("hello"), "world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key&value") { | ||||
|     _object.set(std::string("hello"), std::string("world")); | ||||
|     obj.set(std::string("hello"), std::string("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -7,16 +7,21 @@ | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonObject::size()") { | ||||
|   DynamicJsonObject _object; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("initial size is zero") { | ||||
|     REQUIRE(0 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("increases when values are added") { | ||||
|     _object.set("hello", 42); | ||||
|     REQUIRE(1 == _object.size()); | ||||
|     obj.set("hello", 42); | ||||
|     REQUIRE(1 == obj.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("doesn't increase when the smae key is added twice") { | ||||
|     _object["hello"] = 1; | ||||
|     _object["hello"] = 2; | ||||
|     REQUIRE(1 == _object.size()); | ||||
|     obj["hello"] = 1; | ||||
|     obj["hello"] = 2; | ||||
|     REQUIRE(1 == obj.size()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -6,146 +6,150 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonObject::operator[]") { | ||||
|   DynamicJsonObject _object; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _object["hello"] = 123; | ||||
|     obj["hello"] = 123; | ||||
|  | ||||
|     REQUIRE(123 == _object["hello"].as<int>()); | ||||
|     REQUIRE(true == _object["hello"].is<int>()); | ||||
|     REQUIRE(false == _object["hello"].is<bool>()); | ||||
|     REQUIRE(123 == obj["hello"].as<int>()); | ||||
|     REQUIRE(true == obj["hello"].is<int>()); | ||||
|     REQUIRE(false == obj["hello"].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("volatile int") {  // issue #415 | ||||
|     volatile int i = 123; | ||||
|     _object["hello"] = i; | ||||
|     obj["hello"] = i; | ||||
|  | ||||
|     REQUIRE(123 == _object["hello"].as<int>()); | ||||
|     REQUIRE(true == _object["hello"].is<int>()); | ||||
|     REQUIRE(false == _object["hello"].is<bool>()); | ||||
|     REQUIRE(123 == obj["hello"].as<int>()); | ||||
|     REQUIRE(true == obj["hello"].is<int>()); | ||||
|     REQUIRE(false == obj["hello"].is<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("double") { | ||||
|     _object["hello"] = 123.45; | ||||
|     obj["hello"] = 123.45; | ||||
|  | ||||
|     REQUIRE(true == _object["hello"].is<double>()); | ||||
|     REQUIRE(false == _object["hello"].is<long>()); | ||||
|     REQUIRE(123.45 == _object["hello"].as<double>()); | ||||
|     REQUIRE(true == obj["hello"].is<double>()); | ||||
|     REQUIRE(false == obj["hello"].is<long>()); | ||||
|     REQUIRE(123.45 == obj["hello"].as<double>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("bool") { | ||||
|     _object["hello"] = true; | ||||
|     obj["hello"] = true; | ||||
|  | ||||
|     REQUIRE(true == _object["hello"].is<bool>()); | ||||
|     REQUIRE(false == _object["hello"].is<long>()); | ||||
|     REQUIRE(true == _object["hello"].as<bool>()); | ||||
|     REQUIRE(true == obj["hello"].is<bool>()); | ||||
|     REQUIRE(false == obj["hello"].is<long>()); | ||||
|     REQUIRE(true == obj["hello"].as<bool>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("const char*") { | ||||
|     _object["hello"] = "h3110"; | ||||
|     obj["hello"] = "h3110"; | ||||
|  | ||||
|     REQUIRE(true == _object["hello"].is<const char*>()); | ||||
|     REQUIRE(false == _object["hello"].is<long>()); | ||||
|     REQUIRE(std::string("h3110") == _object["hello"].as<const char*>()); | ||||
|     REQUIRE(std::string("h3110") == | ||||
|             _object["hello"].as<char*>());  // <- short hand | ||||
|     REQUIRE(true == obj["hello"].is<const char*>()); | ||||
|     REQUIRE(false == obj["hello"].is<long>()); | ||||
|     REQUIRE(std::string("h3110") == obj["hello"].as<const char*>()); | ||||
|     REQUIRE(std::string("h3110") == obj["hello"].as<char*>());  // <- short hand | ||||
|   } | ||||
|  | ||||
|   SECTION("array") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|  | ||||
|     _object["hello"] = arr; | ||||
|     obj["hello"] = arr; | ||||
|  | ||||
|     REQUIRE(&arr == &_object["hello"].as<JsonArray&>()); | ||||
|     REQUIRE(&arr == &_object["hello"].as<JsonArray>());  // <- short hand | ||||
|     REQUIRE(&arr == &_object["hello"].as<const JsonArray&>()); | ||||
|     REQUIRE(&arr == &_object["hello"].as<const JsonArray>());  // <- short hand | ||||
|     REQUIRE(true == _object["hello"].is<JsonArray&>()); | ||||
|     REQUIRE(true == _object["hello"].is<JsonArray>()); | ||||
|     REQUIRE(true == _object["hello"].is<const JsonArray&>()); | ||||
|     REQUIRE(true == _object["hello"].is<const JsonArray>()); | ||||
|     REQUIRE(false == _object["hello"].is<JsonObject&>()); | ||||
|     REQUIRE(&arr == &obj["hello"].as<JsonArray&>()); | ||||
|     REQUIRE(&arr == &obj["hello"].as<JsonArray>());  // <- short hand | ||||
|     REQUIRE(&arr == &obj["hello"].as<const JsonArray&>()); | ||||
|     REQUIRE(&arr == &obj["hello"].as<const JsonArray>());  // <- short hand | ||||
|     REQUIRE(true == obj["hello"].is<JsonArray&>()); | ||||
|     REQUIRE(true == obj["hello"].is<JsonArray>()); | ||||
|     REQUIRE(true == obj["hello"].is<const JsonArray&>()); | ||||
|     REQUIRE(true == obj["hello"].is<const JsonArray>()); | ||||
|     REQUIRE(false == obj["hello"].is<JsonObject&>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("object") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj2 = doc2.to<JsonObject>(); | ||||
|  | ||||
|     _object["hello"] = obj; | ||||
|     obj["hello"] = obj2; | ||||
|  | ||||
|     REQUIRE(&obj == &_object["hello"].as<JsonObject&>()); | ||||
|     REQUIRE(&obj == &_object["hello"].as<JsonObject>());  // <- short hand | ||||
|     REQUIRE(&obj == &_object["hello"].as<const JsonObject&>()); | ||||
|     REQUIRE(&obj == &_object["hello"].as<const JsonObject>());  // <- short hand | ||||
|     REQUIRE(true == _object["hello"].is<JsonObject&>()); | ||||
|     REQUIRE(true == _object["hello"].is<JsonObject>()); | ||||
|     REQUIRE(true == _object["hello"].is<const JsonObject&>()); | ||||
|     REQUIRE(true == _object["hello"].is<const JsonObject>()); | ||||
|     REQUIRE(false == _object["hello"].is<JsonArray&>()); | ||||
|     REQUIRE(&obj2 == &obj["hello"].as<JsonObject&>()); | ||||
|     REQUIRE(&obj2 == &obj["hello"].as<JsonObject>());  // <- short hand | ||||
|     REQUIRE(&obj2 == &obj["hello"].as<const JsonObject&>()); | ||||
|     REQUIRE(&obj2 == &obj["hello"].as<const JsonObject>());  // <- short hand | ||||
|     REQUIRE(true == obj["hello"].is<JsonObject&>()); | ||||
|     REQUIRE(true == obj["hello"].is<JsonObject>()); | ||||
|     REQUIRE(true == obj["hello"].is<const JsonObject&>()); | ||||
|     REQUIRE(true == obj["hello"].is<const JsonObject>()); | ||||
|     REQUIRE(false == obj["hello"].is<JsonArray&>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("array subscript") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|     arr.add(42); | ||||
|  | ||||
|     _object["a"] = arr[0]; | ||||
|     obj["a"] = arr[0]; | ||||
|  | ||||
|     REQUIRE(42 == _object["a"]); | ||||
|     REQUIRE(42 == obj["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("object subscript") { | ||||
|     DynamicJsonObject obj; | ||||
|     obj.set("x", 42); | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj2 = doc2.to<JsonObject>(); | ||||
|     obj2.set("x", 42); | ||||
|  | ||||
|     _object["a"] = obj["x"]; | ||||
|     obj["a"] = obj2["x"]; | ||||
|  | ||||
|     REQUIRE(42 == _object["a"]); | ||||
|     REQUIRE(42 == obj["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("char key[]") {  // issue #423 | ||||
|     char key[] = "hello"; | ||||
|     _object[key] = 42; | ||||
|     REQUIRE(42 == _object[key]); | ||||
|     obj[key] = 42; | ||||
|     REQUIRE(42 == obj[key]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _object["hello"] = "world"; | ||||
|     obj["hello"] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1); | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* value") { | ||||
|     _object["hello"] = const_cast<char*>("world"); | ||||
|     obj["hello"] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key") { | ||||
|     _object[const_cast<char*>("hello")] = "world"; | ||||
|     obj[const_cast<char*>("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key&value") { | ||||
|     _object[const_cast<char*>("hello")] = const_cast<char*>("world"); | ||||
|     obj[const_cast<char*>("hello")] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string value") { | ||||
|     _object["hello"] = std::string("world"); | ||||
|     obj["hello"] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key") { | ||||
|     _object[std::string("hello")] = "world"; | ||||
|     obj[std::string("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key&value") { | ||||
|     _object[std::string("hello")] = std::string("world"); | ||||
|     obj[std::string("hello")] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= _object.memoryUsage()); | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -1,17 +0,0 @@ | ||||
| # ArduinoJson - arduinojson.org | ||||
| # Copyright Benoit Blanchon 2014-2018 | ||||
| # MIT License | ||||
|  | ||||
| add_executable(JsonParserTests | ||||
| 	DynamicJsonArray.cpp | ||||
| 	DynamicJsonObject.cpp | ||||
| 	DynamicJsonVariant.cpp | ||||
| 	JsonError.cpp | ||||
| 	nestingLimit.cpp | ||||
| 	StaticJsonArray.cpp | ||||
| 	StaticJsonObject.cpp | ||||
| 	StaticJsonVariant.cpp | ||||
| ) | ||||
|  | ||||
| target_link_libraries(JsonParserTests catch) | ||||
| add_test(JsonParser JsonParserTests) | ||||
| @@ -1,98 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("deserializeJson(DynamicJsonVariant&)") { | ||||
|   DynamicJsonVariant variant; | ||||
|  | ||||
|   SECTION("EmptyObject") { | ||||
|     JsonError err = deserializeJson(variant, "{}"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<JsonObject>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("EmptyArray") { | ||||
|     JsonError err = deserializeJson(variant, "[]"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<JsonArray>()); | ||||
|   } | ||||
|  | ||||
|   SECTION("Integer") { | ||||
|     JsonError err = deserializeJson(variant, "-42"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<int>()); | ||||
|     REQUIRE_FALSE(variant.is<bool>()); | ||||
|     REQUIRE(variant == -42); | ||||
|   } | ||||
|  | ||||
|   SECTION("Double") { | ||||
|     JsonError err = deserializeJson(variant, "-1.23e+4"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE_FALSE(variant.is<int>()); | ||||
|     REQUIRE(variant.is<double>()); | ||||
|     REQUIRE(variant.as<double>() == Approx(-1.23e+4)); | ||||
|   } | ||||
|  | ||||
|   SECTION("Double quoted string") { | ||||
|     JsonError err = deserializeJson(variant, "\"hello world\""); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<char*>()); | ||||
|     REQUIRE_THAT(variant.as<char*>(), Equals("hello world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("Single quoted string") { | ||||
|     JsonError err = deserializeJson(variant, "\'hello world\'"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<char*>()); | ||||
|     REQUIRE_THAT(variant.as<char*>(), Equals("hello world")); | ||||
|   } | ||||
|  | ||||
|   SECTION("True") { | ||||
|     JsonError err = deserializeJson(variant, "true"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<bool>()); | ||||
|     REQUIRE(variant == true); | ||||
|   } | ||||
|  | ||||
|   SECTION("False") { | ||||
|     JsonError err = deserializeJson(variant, "false"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<bool>()); | ||||
|     REQUIRE(variant == false); | ||||
|   } | ||||
|  | ||||
|   SECTION("OpenBrace") { | ||||
|     JsonError err = deserializeJson(variant, "{"); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("Incomplete string") { | ||||
|     JsonError err = deserializeJson(variant, "\"hello"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<char*>()); | ||||
|     REQUIRE_THAT(variant.as<char*>(), Equals("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonVariant") { | ||||
|     deserializeJson(variant, "[1,2,3]"); | ||||
|     deserializeJson(variant, "{}"); | ||||
|  | ||||
|     REQUIRE(variant.is<JsonObject>()); | ||||
|     REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
| @@ -1,90 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserializeJson(StaticJsonArray&)") { | ||||
|   SECTION("BufferOfTheRightSizeForEmptyArray") { | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(0)> arr; | ||||
|     char input[] = "[]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(arr, input); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForArrayWithOneValue") { | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(1) - 1> arr; | ||||
|     char input[] = "[1]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(arr, input); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForArrayWithOneValue") { | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(1)> arr; | ||||
|     char input[] = "[1]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(arr, input); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("TooSmallBufferForArrayWithNestedObject") { | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0) - 1> arr; | ||||
|     char input[] = "[{}]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(arr, input); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(1) + JSON_OBJECT_SIZE(0)> arr; | ||||
|     char input[] = "[{}]"; | ||||
|  | ||||
|     JsonError err = deserializeJson(arr, input); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("CharPtrNull") { | ||||
|     StaticJsonArray<100> arr; | ||||
|  | ||||
|     JsonError err = deserializeJson(arr, static_cast<char*>(0)); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("ConstCharPtrNull") { | ||||
|     StaticJsonArray<100> arr; | ||||
|  | ||||
|     JsonError err = deserializeJson(arr, static_cast<const char*>(0)); | ||||
|  | ||||
|     REQUIRE(err != JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("CopyStringNotSpaces") { | ||||
|     StaticJsonArray<100> arr; | ||||
|  | ||||
|     deserializeJson(arr, "  [ \"1234567\" ] "); | ||||
|  | ||||
|     REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == arr.memoryUsage()); | ||||
|     // note: we use a string of 8 bytes to be sure that the StaticJsonBuffer | ||||
|     // will not insert bytes to enforce alignement | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonArray") { | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(4)> arr; | ||||
|     char input[] = "[1,2,3,4]"; | ||||
|  | ||||
|     deserializeJson(arr, input); | ||||
|     deserializeJson(arr, "[]"); | ||||
|  | ||||
|     REQUIRE(arr.size() == 0); | ||||
|     REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); | ||||
|   } | ||||
| } | ||||
| @@ -1,35 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace Catch::Matchers; | ||||
|  | ||||
| TEST_CASE("deserializeJson(StaticJsonVariant&)") { | ||||
|   SECTION("Array") { | ||||
|     StaticJsonVariant<JSON_ARRAY_SIZE(2)> variant; | ||||
|  | ||||
|     char input[] = "[1,2]"; | ||||
|     JsonError err = deserializeJson(variant, input); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<JsonArray>()); | ||||
|     REQUIRE(variant[0] == 1); | ||||
|     REQUIRE(variant[1] == 2); | ||||
|     REQUIRE(variant.memoryUsage() == JSON_ARRAY_SIZE(2)); | ||||
|   } | ||||
|  | ||||
|   SECTION("Should clear the JsonVariant") { | ||||
|     StaticJsonVariant<JSON_ARRAY_SIZE(2)> variant; | ||||
|     char input[] = "[1,2]"; | ||||
|     deserializeJson(variant, input); | ||||
|  | ||||
|     JsonError err = deserializeJson(variant, "{}"); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(variant.is<JsonObject>()); | ||||
|     REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); | ||||
|   } | ||||
| } | ||||
| @@ -1,70 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| #define SHOULD_WORK(expression) REQUIRE(JsonError::Ok == expression); | ||||
| #define SHOULD_FAIL(expression) REQUIRE(JsonError::TooDeep == expression); | ||||
|  | ||||
| TEST_CASE("JsonParser nestingLimit") { | ||||
|   SECTION("deserializeJson(JsonArray&)") { | ||||
|     DynamicJsonArray arr; | ||||
|  | ||||
|     SECTION("limit = 0") { | ||||
|       SHOULD_FAIL(deserializeJson(arr, "[]", 0)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 1") { | ||||
|       SHOULD_WORK(deserializeJson(arr, "[]", 1)); | ||||
|       SHOULD_FAIL(deserializeJson(arr, "[[]]", 1)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 2") { | ||||
|       SHOULD_WORK(deserializeJson(arr, "[[]]", 2)); | ||||
|       SHOULD_FAIL(deserializeJson(arr, "[[[]]]", 2)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("deserializeJson(JsonObject&)") { | ||||
|     DynamicJsonObject obj; | ||||
|  | ||||
|     SECTION("limit = 0") { | ||||
|       SHOULD_FAIL(deserializeJson(obj, "{}", 0)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 1") { | ||||
|       SHOULD_WORK(deserializeJson(obj, "{\"key\":42}", 1)); | ||||
|       SHOULD_FAIL(deserializeJson(obj, "{\"key\":{\"key\":42}}", 1)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 2") { | ||||
|       SHOULD_WORK(deserializeJson(obj, "{\"key\":{\"key\":42}}", 2)); | ||||
|       SHOULD_FAIL(deserializeJson(obj, "{\"key\":{\"key\":{\"key\":42}}}", 2)); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("deserializeJson(JsonVariant&)") { | ||||
|     DynamicJsonVariant var; | ||||
|  | ||||
|     SECTION("limit = 0") { | ||||
|       SHOULD_WORK(deserializeJson(var, "\"toto\"", 0)); | ||||
|       SHOULD_WORK(deserializeJson(var, "123", 0)); | ||||
|       SHOULD_WORK(deserializeJson(var, "true", 0)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "[]", 0)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "{}", 0)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "[\"toto\"]", 0)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "{\"toto\":1}", 0)); | ||||
|     } | ||||
|  | ||||
|     SECTION("limit = 1") { | ||||
|       SHOULD_WORK(deserializeJson(var, "[\"toto\"]", 1)); | ||||
|       SHOULD_WORK(deserializeJson(var, "{\"toto\":1}", 1)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "{\"toto\":{}}", 1)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "{\"toto\":[]}", 1)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "[[\"toto\"]]", 1)); | ||||
|       SHOULD_FAIL(deserializeJson(var, "[{\"toto\":1}]", 1)); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -15,7 +15,8 @@ static void check(JsonArray &array, std::string expected) { | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(JsonArray)") { | ||||
|   StaticJsonArray<JSON_ARRAY_SIZE(2)> array; | ||||
|   StaticJsonDocument<JSON_ARRAY_SIZE(2)> doc; | ||||
|   JsonArray &array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("Empty") { | ||||
|     check(array, "[]"); | ||||
|   | ||||
| @@ -15,7 +15,8 @@ static void check(JsonArray& array, std::string expected) { | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJsonPretty(JsonArray)") { | ||||
|   DynamicJsonArray array; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonArray& array = doc.to<JsonArray>(); | ||||
|  | ||||
|   SECTION("Empty") { | ||||
|     check(array, "[]"); | ||||
|   | ||||
| @@ -17,7 +17,8 @@ void check(const JsonObject &obj, const std::string &expected) { | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJson(JsonObject)") { | ||||
|   DynamicJsonObject obj; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject &obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("EmptyObject") { | ||||
|     check(obj, "{}"); | ||||
| @@ -92,22 +93,23 @@ TEST_CASE("serializeJson(JsonObject)") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ThreeNestedArrays") { | ||||
|     DynamicJsonArray b, c; | ||||
|     DynamicJsonDocument b; | ||||
|     DynamicJsonDocument c; | ||||
|  | ||||
|     obj.createNestedArray("a"); | ||||
|     obj["b"] = b; | ||||
|     obj.set("c", c); | ||||
|     obj["b"] = b.to<JsonArray>(); | ||||
|     obj.set("c", c.to<JsonArray>()); | ||||
|  | ||||
|     check(obj, "{\"a\":[],\"b\":[],\"c\":[]}"); | ||||
|   } | ||||
|  | ||||
|   SECTION("ThreeNestedObjects") { | ||||
|     DynamicJsonObject b; | ||||
|     DynamicJsonObject c; | ||||
|     DynamicJsonDocument b; | ||||
|     DynamicJsonDocument c; | ||||
|  | ||||
|     obj.createNestedObject("a"); | ||||
|     obj["b"] = b; | ||||
|     obj.set("c", c); | ||||
|     obj["b"] = b.to<JsonObject>(); | ||||
|     obj.set("c", c.to<JsonObject>()); | ||||
|  | ||||
|     check(obj, "{\"a\":{},\"b\":{},\"c\":{}}"); | ||||
|   } | ||||
|   | ||||
| @@ -18,7 +18,8 @@ void check(const JsonObject &obj, const std::string expected) { | ||||
| } | ||||
|  | ||||
| TEST_CASE("serializeJsonPretty(JsonObject)") { | ||||
|   DynamicJsonObject obj; | ||||
|   DynamicJsonDocument doc; | ||||
|   JsonObject &obj = doc.to<JsonObject>(); | ||||
|  | ||||
|   SECTION("EmptyObject") { | ||||
|     check(obj, "{}"); | ||||
|   | ||||
| @@ -192,7 +192,8 @@ TEST_CASE("JsonVariant::as()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ObjectAsString") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|     obj["key"] = "value"; | ||||
|  | ||||
| @@ -201,7 +202,8 @@ TEST_CASE("JsonVariant::as()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ArrayAsString") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add(4); | ||||
|     arr.add(2); | ||||
|  | ||||
| @@ -210,7 +212,8 @@ TEST_CASE("JsonVariant::as()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ArrayAsJsonArray") { | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|  | ||||
|     JsonVariant variant = arr; | ||||
|     REQUIRE(&arr == &variant.as<JsonArray&>()); | ||||
| @@ -218,7 +221,8 @@ TEST_CASE("JsonVariant::as()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ObjectAsJsonObject") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|     JsonVariant variant = obj; | ||||
|     REQUIRE(&obj == &variant.as<JsonObject&>()); | ||||
|   | ||||
| @@ -97,8 +97,9 @@ TEST_CASE("JsonVariant comparisons") { | ||||
|   } | ||||
|  | ||||
|   SECTION("StringLiteral") { | ||||
|     DynamicJsonVariant variant; | ||||
|     deserializeJson(variant, "\"hello\""); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "\"hello\""); | ||||
|     JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|     REQUIRE_FALSE(variant != "hello"); | ||||
| @@ -114,8 +115,7 @@ TEST_CASE("JsonVariant comparisons") { | ||||
|   } | ||||
|  | ||||
|   SECTION("String") { | ||||
|     DynamicJsonVariant variant; | ||||
|     deserializeJson(variant, "\"hello\""); | ||||
|     JsonVariant variant = "hello"; | ||||
|  | ||||
|     REQUIRE(variant == std::string("hello")); | ||||
|     REQUIRE_FALSE(variant != std::string("hello")); | ||||
| @@ -179,7 +179,10 @@ TEST_CASE("JsonVariant comparisons") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ArrayInVariant") { | ||||
|     DynamicJsonArray array1, array2; | ||||
|     DynamicJsonDocument doc1; | ||||
|     JsonArray& array1 = doc1.to<JsonArray>(); | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& array2 = doc2.to<JsonArray>(); | ||||
|  | ||||
|     JsonVariant variant1 = array1; | ||||
|     JsonVariant variant2 = array1; | ||||
| @@ -193,8 +196,10 @@ TEST_CASE("JsonVariant comparisons") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ObjectInVariant") { | ||||
|     DynamicJsonObject obj1; | ||||
|     DynamicJsonObject obj2; | ||||
|     DynamicJsonDocument doc1; | ||||
|     JsonObject& obj1 = doc1.to<JsonObject>(); | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonObject& obj2 = doc2.to<JsonObject>(); | ||||
|  | ||||
|     JsonVariant variant1 = obj1; | ||||
|     JsonVariant variant2 = obj1; | ||||
| @@ -208,8 +213,11 @@ TEST_CASE("JsonVariant comparisons") { | ||||
|   } | ||||
|  | ||||
|   SECTION("VariantsOfDifferentTypes") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc1; | ||||
|     JsonObject& obj = doc1.to<JsonObject>(); | ||||
|  | ||||
|     DynamicJsonDocument doc2; | ||||
|     JsonArray& arr = doc2.to<JsonArray>(); | ||||
|     JsonVariant variants[] = { | ||||
|         true, 42, 666.667, "hello", arr, obj, | ||||
|     }; | ||||
|   | ||||
| @@ -42,7 +42,8 @@ TEST_CASE("JsonVariant copy") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ObjectsAreCopiedByReference") { | ||||
|     DynamicJsonObject object; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& object = doc.to<JsonObject>(); | ||||
|  | ||||
|     _variant1 = object; | ||||
|  | ||||
| @@ -52,7 +53,8 @@ TEST_CASE("JsonVariant copy") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ArraysAreCopiedByReference") { | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|  | ||||
|     _variant1 = array; | ||||
|  | ||||
|   | ||||
| @@ -69,10 +69,9 @@ void checkIsString(JsonVariant var) { | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant::is()") { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
|  | ||||
|   SECTION("JsonArray") { | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     checkIsArray(array); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -122,7 +122,8 @@ TEST_CASE("JsonVariant set()/get()") { | ||||
| #endif | ||||
|  | ||||
|   SECTION("CanStoreObject") { | ||||
|     DynamicJsonObject object; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject &object = doc.to<JsonObject>(); | ||||
|  | ||||
|     checkReference<JsonObject>(object); | ||||
|   } | ||||
|   | ||||
| @@ -7,7 +7,8 @@ | ||||
|  | ||||
| TEST_CASE("JsonVariant::operator[]") { | ||||
|   SECTION("Array") { | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     array.add("element at index 0"); | ||||
|     array.add("element at index 1"); | ||||
|  | ||||
| @@ -24,7 +25,8 @@ TEST_CASE("JsonVariant::operator[]") { | ||||
|   } | ||||
|  | ||||
|   SECTION("Object") { | ||||
|     DynamicJsonObject object; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& object = doc.to<JsonObject>(); | ||||
|     object["a"] = "element at key \"a\""; | ||||
|     object["b"] = "element at key \"b\""; | ||||
|  | ||||
| @@ -52,7 +54,8 @@ TEST_CASE("JsonVariant::operator[]") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ObjectSetValue") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     JsonVariant var = obj; | ||||
|     var["hello"] = "world"; | ||||
|     REQUIRE(1 == var.size()); | ||||
| @@ -60,16 +63,19 @@ TEST_CASE("JsonVariant::operator[]") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ArraySetValue") { | ||||
|     DynamicJsonVariant var; | ||||
|     deserializeJson(var, "[\"hello\"]"); | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|     JsonVariant var = arr; | ||||
|     var[0] = "world"; | ||||
|     REQUIRE(1 == var.size()); | ||||
|     REQUIRE(std::string("world") == var[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("NestedObjectSetValue") { | ||||
|     DynamicJsonVariant var; | ||||
|     deserializeJson(var, "[{}]"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "[{}]"); | ||||
|     JsonVariant var = doc.as<JsonVariant>(); | ||||
|     var[0]["hello"] = "world"; | ||||
|     REQUIRE(1 == var.size()); | ||||
|     REQUIRE(1 == var[0].size()); | ||||
|   | ||||
| @@ -17,14 +17,16 @@ TEST_CASE("JsonVariant::success()") { | ||||
|   } | ||||
|  | ||||
|   SECTION("ReturnsTrue_WhenEmptyArray") { | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|  | ||||
|     JsonVariant variant = array; | ||||
|     REQUIRE(true == variant.success()); | ||||
|   } | ||||
|  | ||||
|   SECTION("ReturnsTrue_WhenEmptyObject") { | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|  | ||||
|     JsonVariant variant = obj; | ||||
|     REQUIRE(true == variant.success()); | ||||
|   | ||||
| @@ -23,7 +23,8 @@ TEST_CASE("std::stream") { | ||||
|  | ||||
|   SECTION("JsonObject") { | ||||
|     std::ostringstream os; | ||||
|     DynamicJsonObject object; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& object = doc.to<JsonObject>(); | ||||
|     object["key"] = "value"; | ||||
|     os << object; | ||||
|     REQUIRE("{\"key\":\"value\"}" == os.str()); | ||||
| @@ -31,7 +32,8 @@ TEST_CASE("std::stream") { | ||||
|  | ||||
|   SECTION("JsonObjectSubscript") { | ||||
|     std::ostringstream os; | ||||
|     DynamicJsonObject object; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& object = doc.to<JsonObject>(); | ||||
|     object["key"] = "value"; | ||||
|     os << object["key"]; | ||||
|     REQUIRE("\"value\"" == os.str()); | ||||
| @@ -39,7 +41,8 @@ TEST_CASE("std::stream") { | ||||
|  | ||||
|   SECTION("JsonArray") { | ||||
|     std::ostringstream os; | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     array.add("value"); | ||||
|     os << array; | ||||
|     REQUIRE("[\"value\"]" == os.str()); | ||||
| @@ -47,7 +50,8 @@ TEST_CASE("std::stream") { | ||||
|  | ||||
|   SECTION("JsonArraySubscript") { | ||||
|     std::ostringstream os; | ||||
|     DynamicJsonArray array; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& array = doc.to<JsonArray>(); | ||||
|     array.add("value"); | ||||
|     os << array[0]; | ||||
|     REQUIRE("\"value\"" == os.str()); | ||||
| @@ -55,8 +59,9 @@ TEST_CASE("std::stream") { | ||||
|  | ||||
|   SECTION("ParseArray") { | ||||
|     std::istringstream json(" [ 42 /* comment */ ] "); | ||||
|     DynamicJsonArray arr; | ||||
|     JsonError err = deserializeJson(arr, json); | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|     JsonArray& arr = doc.as<JsonArray>(); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(1 == arr.size()); | ||||
| @@ -65,8 +70,9 @@ TEST_CASE("std::stream") { | ||||
|  | ||||
|   SECTION("ParseObject") { | ||||
|     std::istringstream json(" { hello : world // comment\n }"); | ||||
|     DynamicJsonObject obj; | ||||
|     JsonError err = deserializeJson(obj, json); | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(1 == obj.size()); | ||||
| @@ -75,8 +81,8 @@ TEST_CASE("std::stream") { | ||||
|  | ||||
|   SECTION("ShouldNotReadPastTheEnd") { | ||||
|     std::istringstream json("{}123"); | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, json); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, json); | ||||
|     REQUIRE('1' == json.get()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -11,21 +11,22 @@ static void eraseString(std::string &str) { | ||||
| } | ||||
|  | ||||
| TEST_CASE("std::string") { | ||||
|   DynamicJsonBuffer jb; | ||||
|  | ||||
|   SECTION("JsonArray") { | ||||
|     DynamicJsonArray array; | ||||
|  | ||||
|     SECTION("deserializeJson") { | ||||
|   SECTION("deserializeJson duplicates content") { | ||||
|     std::string json("[\"hello\"]"); | ||||
|  | ||||
|       JsonError err = deserializeJson(array, json); | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|     eraseString(json); | ||||
|  | ||||
|     JsonArray &array = doc.as<JsonArray>(); | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|     REQUIRE(std::string("hello") == array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray") { | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray &array = doc.to<JsonArray>(); | ||||
|  | ||||
|     SECTION("add()") { | ||||
|       std::string value("hello"); | ||||
|       array.add(value); | ||||
| @@ -67,168 +68,190 @@ TEST_CASE("std::string") { | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject") { | ||||
|     DynamicJsonObject object; | ||||
|     DynamicJsonDocument doc; | ||||
|  | ||||
|     SECTION("deserializeJson()") { | ||||
|       std::string json("{\"hello\":\"world\"}"); | ||||
|  | ||||
|       JsonError err = deserializeJson(object, json); | ||||
|       JsonError err = deserializeJson(doc, json); | ||||
|       JsonObject &obj = doc.as<JsonObject>(); | ||||
|       eraseString(json); | ||||
|  | ||||
|       REQUIRE(err == JsonError::Ok); | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("operator[]") { | ||||
|       char json[] = "{\"key\":\"value\"}"; | ||||
|  | ||||
|       deserializeJson(object, json); | ||||
|       deserializeJson(doc, json); | ||||
|       JsonObject &obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(std::string("value") == object[std::string("key")]); | ||||
|       REQUIRE(std::string("value") == obj[std::string("key")]); | ||||
|     } | ||||
|  | ||||
|     SECTION("operator[] const") { | ||||
|       char json[] = "{\"key\":\"value\"}"; | ||||
|  | ||||
|       deserializeJson(object, json); | ||||
|       const JsonObject &obj = object; | ||||
|       deserializeJson(doc, json); | ||||
|       JsonObject &obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(std::string("value") == obj[std::string("key")]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set(key)") { | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       std::string key("hello"); | ||||
|       object.set(key, "world"); | ||||
|       obj.set(key, "world"); | ||||
|       eraseString(key); | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set(value)") { | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       std::string value("world"); | ||||
|       object.set("hello", value); | ||||
|       obj.set("hello", value); | ||||
|       eraseString(value); | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set(key,value)") { | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       std::string key("hello"); | ||||
|       std::string value("world"); | ||||
|       object.set(key, value); | ||||
|       obj.set(key, value); | ||||
|       eraseString(key); | ||||
|       eraseString(value); | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set(JsonArraySubscript)") { | ||||
|       DynamicJsonArray arr; | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       DynamicJsonDocument doc2; | ||||
|       JsonArray &arr = doc2.to<JsonArray>(); | ||||
|       arr.add("world"); | ||||
|  | ||||
|       object.set(std::string("hello"), arr[0]); | ||||
|       obj.set(std::string("hello"), arr[0]); | ||||
|  | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("set(JsonObjectSubscript)") { | ||||
|       DynamicJsonObject obj; | ||||
|       obj.set("x", "world"); | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       DynamicJsonDocument doc2; | ||||
|       JsonObject &obj2 = doc2.to<JsonObject>(); | ||||
|       obj2.set("x", "world"); | ||||
|  | ||||
|       object.set(std::string("hello"), obj["x"]); | ||||
|       obj.set(std::string("hello"), obj2["x"]); | ||||
|  | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("get<T>()") { | ||||
|       char json[] = "{\"key\":\"value\"}"; | ||||
|       deserializeJson(object, json); | ||||
|       deserializeJson(doc, json); | ||||
|       JsonObject &obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(std::string("value") == | ||||
|               object.get<const char *>(std::string("key"))); | ||||
|               obj.get<const char *>(std::string("key"))); | ||||
|     } | ||||
|  | ||||
|     SECTION("is<T>()") { | ||||
|       char json[] = "{\"key\":\"value\"}"; | ||||
|       deserializeJson(object, json); | ||||
|       REQUIRE(true == object.is<const char *>(std::string("key"))); | ||||
|       deserializeJson(doc, json); | ||||
|       JsonObject &obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(true == obj.is<const char *>(std::string("key"))); | ||||
|     } | ||||
|  | ||||
|     SECTION("createNestedObject()") { | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       std::string key = "key"; | ||||
|       char json[64]; | ||||
|       object.createNestedObject(key); | ||||
|       obj.createNestedObject(key); | ||||
|       eraseString(key); | ||||
|       serializeJson(object, json, sizeof(json)); | ||||
|       serializeJson(doc, json, sizeof(json)); | ||||
|       REQUIRE(std::string("{\"key\":{}}") == json); | ||||
|     } | ||||
|  | ||||
|     SECTION("createNestedArray()") { | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       std::string key = "key"; | ||||
|       char json[64]; | ||||
|       object.createNestedArray(key); | ||||
|       obj.createNestedArray(key); | ||||
|       eraseString(key); | ||||
|       serializeJson(object, json, sizeof(json)); | ||||
|       serializeJson(doc, json, sizeof(json)); | ||||
|       REQUIRE(std::string("{\"key\":[]}") == json); | ||||
|     } | ||||
|  | ||||
|     SECTION("containsKey()") { | ||||
|       char json[] = "{\"key\":\"value\"}"; | ||||
|       deserializeJson(object, json); | ||||
|       REQUIRE(true == object.containsKey(std::string("key"))); | ||||
|       deserializeJson(doc, json); | ||||
|       JsonObject &obj = doc.as<JsonObject>(); | ||||
|       REQUIRE(true == obj.containsKey(std::string("key"))); | ||||
|     } | ||||
|  | ||||
|     SECTION("remove()") { | ||||
|       char json[] = "{\"key\":\"value\"}"; | ||||
|       deserializeJson(object, json); | ||||
|       REQUIRE(1 == object.size()); | ||||
|       object.remove(std::string("key")); | ||||
|       REQUIRE(0 == object.size()); | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       obj["key"] = "value"; | ||||
|  | ||||
|       obj.remove(std::string("key")); | ||||
|  | ||||
|       REQUIRE(0 == obj.size()); | ||||
|     } | ||||
|  | ||||
|     SECTION("operator[], set key") { | ||||
|       std::string key("hello"); | ||||
|       object[key] = "world"; | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       obj[key] = "world"; | ||||
|       eraseString(key); | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("operator[], set value") { | ||||
|       std::string value("world"); | ||||
|       object["hello"] = value; | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       obj["hello"] = value; | ||||
|       eraseString(value); | ||||
|       REQUIRE(std::string("world") == object["hello"]); | ||||
|       REQUIRE(std::string("world") == obj["hello"]); | ||||
|     } | ||||
|  | ||||
|     SECTION("serializeJson()") { | ||||
|       object["key"] = "value"; | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       obj["key"] = "value"; | ||||
|       std::string json; | ||||
|       serializeJson(object, json); | ||||
|       serializeJson(doc, json); | ||||
|       REQUIRE(std::string("{\"key\":\"value\"}") == json); | ||||
|     } | ||||
|  | ||||
|     SECTION("serializeJsonPretty()") { | ||||
|       object["key"] = "value"; | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|       obj["key"] = "value"; | ||||
|       std::string json; | ||||
|       serializeJsonPretty(object, json); | ||||
|       serializeJsonPretty(doc, json); | ||||
|       REQUIRE(std::string("{\r\n  \"key\": \"value\"\r\n}") == json); | ||||
|     } | ||||
|  | ||||
|     SECTION("memoryUsage() increases when adding a new key") { | ||||
|       std::string key1("hello"), key2("world"); | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|  | ||||
|       object[key1] = 1; | ||||
|       size_t sizeBefore = object.memoryUsage(); | ||||
|       object[key2] = 2; | ||||
|       size_t sizeAfter = object.memoryUsage(); | ||||
|       obj[key1] = 1; | ||||
|       size_t sizeBefore = doc.memoryUsage(); | ||||
|       obj[key2] = 2; | ||||
|       size_t sizeAfter = doc.memoryUsage(); | ||||
|  | ||||
|       REQUIRE(sizeAfter - sizeBefore >= key2.size()); | ||||
|     } | ||||
|  | ||||
|     SECTION("memoryUsage() remains when adding the same key") { | ||||
|       std::string key("hello"); | ||||
|       JsonObject &obj = doc.to<JsonObject>(); | ||||
|  | ||||
|       object[key] = 1; | ||||
|       size_t sizeBefore = object.memoryUsage(); | ||||
|       object[key] = 2; | ||||
|       size_t sizeAfter = object.memoryUsage(); | ||||
|       obj[key] = 1; | ||||
|       size_t sizeBefore = doc.memoryUsage(); | ||||
|       obj[key] = 2; | ||||
|       size_t sizeAfter = doc.memoryUsage(); | ||||
|  | ||||
|       REQUIRE(sizeBefore == sizeAfter); | ||||
|     } | ||||
|   | ||||
| @@ -13,8 +13,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonBuffer::parseArray") { | ||||
|     unsigned char json[] = "[42]"; | ||||
|  | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(1)> arr; | ||||
|     JsonError err = deserializeJson(arr, json); | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
| @@ -22,8 +22,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonBuffer::parseObject") { | ||||
|     unsigned char json[] = "{\"a\":42}"; | ||||
|  | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1)> obj; | ||||
|     JsonError err = deserializeJson(obj, json); | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     JsonError err = deserializeJson(doc, json); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
| @@ -49,8 +49,9 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonVariant::operator[]") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     deserializeJson(variant, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(std::string("world") == variant[key]); | ||||
|   } | ||||
| @@ -60,8 +61,9 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonVariant::operator[] const") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     deserializeJson(variant, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     const JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(std::string("world") == variant[key]); | ||||
|   } | ||||
| @@ -70,7 +72,7 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonVariant::operator==") { | ||||
|     unsigned char comparand[] = "hello"; | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     JsonVariant variant; | ||||
|     variant = "hello"; | ||||
|  | ||||
|     REQUIRE(comparand == variant); | ||||
| @@ -82,7 +84,7 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonVariant::operator!=") { | ||||
|     unsigned char comparand[] = "hello"; | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     JsonVariant variant; | ||||
|     variant = "world"; | ||||
|  | ||||
|     REQUIRE(comparand != variant); | ||||
| @@ -95,7 +97,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::operator[]") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj[key] = "world"; | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -105,7 +108,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObjectSubscript::operator=") {  // issue #416 | ||||
|     unsigned char value[] = "world"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj["hello"] = value; | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -114,7 +118,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObjectSubscript::set()") { | ||||
|     unsigned char value[] = "world"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj["hello"].set(value); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -124,9 +129,10 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::operator[] const") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(std::string("world") == obj[key]); | ||||
|   } | ||||
| #endif | ||||
| @@ -134,16 +140,17 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::get()") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(std::string("world") == obj.get<char*>(key)); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject::set() key") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.set(key, "world"); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -152,7 +159,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::set() value") { | ||||
|     unsigned char value[] = "world"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.set("hello", value); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -161,7 +169,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::set key&value") { | ||||
|     unsigned char key[] = "world"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.set(key, key); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["world"]); | ||||
| @@ -170,17 +179,18 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::containsKey()") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(true == obj.containsKey(key)); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject::remove()") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     obj.remove(key); | ||||
|  | ||||
|     REQUIRE(0 == obj.size()); | ||||
| @@ -189,8 +199,9 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::is()") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":42}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":42}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(true == obj.is<int>(key)); | ||||
|   } | ||||
| @@ -198,21 +209,24 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonObject::createNestedArray()") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.createNestedArray(key); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonObject::createNestedObject()") { | ||||
|     unsigned char key[] = "hello"; | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.createNestedObject(key); | ||||
|   } | ||||
|  | ||||
|   SECTION("JsonArray::add()") { | ||||
|     unsigned char value[] = "world"; | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add(value); | ||||
|  | ||||
|     REQUIRE(std::string("world") == arr[0]); | ||||
| @@ -221,7 +235,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonArray::set()") { | ||||
|     unsigned char value[] = "world"; | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|     arr.set(0, value); | ||||
|  | ||||
| @@ -231,7 +246,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonArraySubscript::set()") { | ||||
|     unsigned char value[] = "world"; | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|     arr[0].set(value); | ||||
|  | ||||
| @@ -241,7 +257,8 @@ TEST_CASE("unsigned char string") { | ||||
|   SECTION("JsonArraySubscript::operator=") { | ||||
|     unsigned char value[] = "world"; | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|     arr[0] = value; | ||||
|  | ||||
|   | ||||
| @@ -22,8 +22,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "[42]"); | ||||
|  | ||||
|     StaticJsonArray<JSON_ARRAY_SIZE(1)> arr; | ||||
|     JsonError err = deserializeJson(arr, vla); | ||||
|     StaticJsonDocument<JSON_ARRAY_SIZE(1)> doc; | ||||
|     JsonError err = deserializeJson(doc, vla); | ||||
|  | ||||
|     REQUIRE(err == JsonError::Ok); | ||||
|   } | ||||
| @@ -33,10 +33,10 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "{\"a\":42}"); | ||||
|  | ||||
|     StaticJsonObject<JSON_OBJECT_SIZE(1)> obj; | ||||
|     deserializeJson(obj, vla); | ||||
|     StaticJsonDocument<JSON_OBJECT_SIZE(1)> doc; | ||||
|     JsonError error = deserializeJson(doc, vla); | ||||
|  | ||||
|     REQUIRE(true == obj.success()); | ||||
|     REQUIRE(error == JsonError::Ok); | ||||
|   } | ||||
|  | ||||
|   SECTION("Parse") { | ||||
| @@ -44,7 +44,7 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "42"); | ||||
|  | ||||
|     StaticJsonVariant<> variant; | ||||
|     StaticJsonDocument<> variant; | ||||
|     deserializeJson(variant, vla); | ||||
|  | ||||
|     REQUIRE(42 == variant.as<int>()); | ||||
| @@ -77,8 +77,9 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     deserializeJson(variant, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(std::string("world") == variant[vla]); | ||||
|   } | ||||
| @@ -90,8 +91,9 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     deserializeJson(variant, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     const JsonVariant variant = doc.as<JsonVariant>(); | ||||
|  | ||||
|     REQUIRE(std::string("world") == variant[vla]); | ||||
|   } | ||||
| @@ -102,7 +104,7 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     JsonVariant variant; | ||||
|     variant = "hello"; | ||||
|  | ||||
|     REQUIRE((vla == variant)); | ||||
| @@ -116,7 +118,7 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonVariant variant; | ||||
|     JsonVariant variant; | ||||
|     variant = "world"; | ||||
|  | ||||
|     REQUIRE((vla != variant)); | ||||
| @@ -131,7 +133,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj[vla] = "world"; | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -143,7 +146,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj["hello"] = vla; | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"].as<char*>()); | ||||
| @@ -154,7 +158,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj["hello"].set(vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"].as<char*>()); | ||||
| @@ -166,9 +171,10 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(std::string("world") == obj[vla]); | ||||
|   } | ||||
| #endif | ||||
| @@ -178,9 +184,10 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(std::string("world") == obj.get<char*>(vla)); | ||||
|   } | ||||
|  | ||||
| @@ -189,7 +196,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.set(vla, "world"); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -200,7 +208,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.set("hello", vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["hello"]); | ||||
| @@ -211,7 +220,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.set(vla, vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == obj["world"]); | ||||
| @@ -222,9 +232,10 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|  | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     REQUIRE(true == obj.containsKey(vla)); | ||||
|   } | ||||
|  | ||||
| @@ -233,8 +244,9 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":\"world\"}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":\"world\"}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|     obj.remove(vla); | ||||
|  | ||||
|     REQUIRE(0 == obj.size()); | ||||
| @@ -245,8 +257,9 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     deserializeJson(obj, "{\"hello\":42}"); | ||||
|     DynamicJsonDocument doc; | ||||
|     deserializeJson(doc, "{\"hello\":42}"); | ||||
|     JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|     REQUIRE(true == obj.is<int>(vla)); | ||||
|   } | ||||
| @@ -256,7 +269,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.createNestedArray(vla); | ||||
|   } | ||||
|  | ||||
| @@ -265,7 +279,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "hello"); | ||||
|  | ||||
|     DynamicJsonObject obj; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonObject& obj = doc.to<JsonObject>(); | ||||
|     obj.createNestedObject(vla); | ||||
|   } | ||||
|  | ||||
| @@ -274,7 +289,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add(vla); | ||||
|  | ||||
|     REQUIRE(std::string("world") == arr[0]); | ||||
| @@ -285,7 +301,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|     arr.set(0, vla); | ||||
|  | ||||
| @@ -297,7 +314,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|     arr[0].set(vla); | ||||
|  | ||||
| @@ -309,7 +327,8 @@ TEST_CASE("Variable Length Array") { | ||||
|     char vla[i]; | ||||
|     strcpy(vla, "world"); | ||||
|  | ||||
|     DynamicJsonArray arr; | ||||
|     DynamicJsonDocument doc; | ||||
|     JsonArray& arr = doc.to<JsonArray>(); | ||||
|     arr.add("hello"); | ||||
|     arr[0] = vla; | ||||
|  | ||||
|   | ||||
| @@ -24,8 +24,6 @@ TEST_CASE("MsgPackError") { | ||||
|     TEST_STRINGIFICATION(Ok); | ||||
|     TEST_STRINGIFICATION(NotSupported); | ||||
|     TEST_STRINGIFICATION(NoMemory); | ||||
|     TEST_STRINGIFICATION(NotAnArray); | ||||
|     TEST_STRINGIFICATION(NotAnObject); | ||||
|     TEST_STRINGIFICATION(TooDeep); | ||||
|   } | ||||
|  | ||||
| @@ -33,8 +31,12 @@ TEST_CASE("MsgPackError") { | ||||
|     TEST_BOOLIFICATION(Ok, false); | ||||
|     TEST_BOOLIFICATION(NotSupported, true); | ||||
|     TEST_BOOLIFICATION(NoMemory, true); | ||||
|     TEST_BOOLIFICATION(NotAnArray, true); | ||||
|     TEST_BOOLIFICATION(NotAnObject, true); | ||||
|     TEST_BOOLIFICATION(TooDeep, true); | ||||
|   } | ||||
|  | ||||
|   SECTION("ostream") { | ||||
|     std::stringstream s; | ||||
|     s << MsgPackError::NotSupported; | ||||
|     REQUIRE(s.str() == "NotSupported"); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|  | ||||
| static void check(const char* input, MsgPackError expected, | ||||
|                   uint8_t nestingLimit = 10) { | ||||
|   DynamicJsonVariant variant; | ||||
|   DynamicJsonDocument variant; | ||||
|  | ||||
|   MsgPackError error = deserializeMsgPack(variant, input, nestingLimit); | ||||
|  | ||||
|   | ||||
| @@ -6,21 +6,14 @@ | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserializeMsgPack(JsonArray&)") { | ||||
|   DynamicJsonArray array; | ||||
|  | ||||
|   SECTION("not an array") { | ||||
|     const char* input = "\xA0"; | ||||
|  | ||||
|     MsgPackError error = deserializeMsgPack(array, input); | ||||
|  | ||||
|     REQUIRE(error == MsgPackError::NotAnArray); | ||||
|   } | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("fixarray") { | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\x90"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(array, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(array.size() == 0); | ||||
| @@ -29,7 +22,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { | ||||
|     SECTION("two integers") { | ||||
|       const char* input = "\x92\x01\x02"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(array, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(array.size() == 2); | ||||
| @@ -42,7 +36,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDC\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(array, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(array.size() == 0); | ||||
| @@ -51,7 +46,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { | ||||
|     SECTION("two strings") { | ||||
|       const char* input = "\xDC\x00\x02\xA5hello\xA5world"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(array, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(array.size() == 2); | ||||
| @@ -64,7 +60,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDD\x00\x00\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(array, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(array.size() == 0); | ||||
| @@ -74,7 +71,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { | ||||
|       const char* input = | ||||
|           "\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(array, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonArray& array = doc.as<JsonArray>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(array.size() == 2); | ||||
|   | ||||
| @@ -5,36 +5,32 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("deserializeMsgPack(JsonObject&)") { | ||||
|   DynamicJsonObject object; | ||||
|  | ||||
|   SECTION("not an object") { | ||||
|     const char* input = "\xA0"; | ||||
|  | ||||
|     MsgPackError error = deserializeMsgPack(object, input); | ||||
|  | ||||
|     REQUIRE(error == MsgPackError::NotAnObject); | ||||
|   } | ||||
| TEST_CASE("deserialize MsgPack object") { | ||||
|   DynamicJsonDocument doc; | ||||
|  | ||||
|   SECTION("fixmap") { | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\x80"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(object, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(object.size() == 0); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two integers") { | ||||
|       const char* input = "\x82\xA3one\x01\xA3two\x02"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(object, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(object.size() == 2); | ||||
|       REQUIRE(object["one"] == 1); | ||||
|       REQUIRE(object["two"] == 2); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["one"] == 1); | ||||
|       REQUIRE(obj["two"] == 2); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -42,21 +38,25 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDE\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(object, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(object.size() == 0); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two strings") { | ||||
|       const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(object, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(object.size() == 2); | ||||
|       REQUIRE(object["H"] == "hello"); | ||||
|       REQUIRE(object["W"] == "world"); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["H"] == "hello"); | ||||
|       REQUIRE(obj["W"] == "world"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| @@ -64,10 +64,12 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDF\x00\x00\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(object, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(object.size() == 0); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two floats") { | ||||
| @@ -75,12 +77,14 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { | ||||
|           "\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48" | ||||
|           "\xF5\xC3"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(object, input); | ||||
|       MsgPackError error = deserializeMsgPack(doc, input); | ||||
|       JsonObject& obj = doc.as<JsonObject>(); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(object.size() == 2); | ||||
|       REQUIRE(object["zero"] == 0.0f); | ||||
|       REQUIRE(object["pi"] == 3.14f); | ||||
|       REQUIRE(doc.is<JsonObject>()); | ||||
|       REQUIRE(obj.size() == 2); | ||||
|       REQUIRE(obj["zero"] == 0.0f); | ||||
|       REQUIRE(obj["pi"] == 3.14f); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -9,14 +9,14 @@ static const size_t epsilon = sizeof(void*); | ||||
|  | ||||
| template <size_t Capacity> | ||||
| static void check(const char* input, MsgPackError expected) { | ||||
|   StaticJsonVariant<Capacity> variant; | ||||
|   StaticJsonDocument<Capacity> variant; | ||||
|  | ||||
|   MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|   REQUIRE(error == expected); | ||||
| } | ||||
|  | ||||
| TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { | ||||
| TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") { | ||||
|   SECTION("single values always fit") { | ||||
|     check<0>("\xc0", MsgPackError::Ok);                  // nil | ||||
|     check<0>("\xc2", MsgPackError::Ok);                  // false | ||||
| @@ -82,8 +82,7 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { | ||||
|       check<JSON_OBJECT_SIZE(0)>("\x80", MsgPackError::Ok); | ||||
|     } | ||||
|     SECTION("{H:1}") { | ||||
|       check<JSON_OBJECT_SIZE(0)>("\x81\xA1H\x01", | ||||
|                                  MsgPackError::NoMemory); | ||||
|       check<JSON_OBJECT_SIZE(0)>("\x81\xA1H\x01", MsgPackError::NoMemory); | ||||
|       check<JSON_OBJECT_SIZE(1) + epsilon>("\x81\xA1H\x01", MsgPackError::Ok); | ||||
|     } | ||||
|     SECTION("{H:1,W:2}") { | ||||
| @@ -101,7 +100,8 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { | ||||
|     SECTION("{H:1}") { | ||||
|       check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x01\xA1H\x01", | ||||
|                                  MsgPackError::NoMemory); | ||||
|       check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x01\xA1H\x01", MsgPackError::Ok); | ||||
|       check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x01\xA1H\x01", | ||||
|                                            MsgPackError::Ok); | ||||
|     } | ||||
|     SECTION("{H:1,W:2}") { | ||||
|       check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x02\xA1H\x01\xA1W\x02", | ||||
| @@ -122,10 +122,10 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { | ||||
|                                            MsgPackError::Ok); | ||||
|     } | ||||
|     SECTION("{H:1,W:2}") { | ||||
|       check<JSON_OBJECT_SIZE(1) + epsilon>("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", | ||||
|                                      MsgPackError::NoMemory); | ||||
|       check<JSON_OBJECT_SIZE(2) + 2*epsilon>("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", | ||||
|                                      MsgPackError::Ok); | ||||
|       check<JSON_OBJECT_SIZE(1) + epsilon>( | ||||
|           "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::NoMemory); | ||||
|       check<JSON_OBJECT_SIZE(2) + 2 * epsilon>( | ||||
|           "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::Ok); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|  | ||||
| template <typename T, typename U> | ||||
| static void check(const char* input, U expected) { | ||||
|   DynamicJsonVariant variant; | ||||
|   DynamicJsonDocument variant; | ||||
|  | ||||
|   MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
| @@ -127,151 +127,4 @@ TEST_CASE("deserializeMsgPack(JsonVariant&)") { | ||||
|   SECTION("str 32") { | ||||
|     check<const char*>("\xdb\x00\x00\x00\x05hello", std::string("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("fixarray") { | ||||
|     DynamicJsonVariant variant; | ||||
|  | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\x90"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two integers") { | ||||
|       const char* input = "\x92\x01\x02"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 2); | ||||
|       REQUIRE(variant[0] == 1); | ||||
|       REQUIRE(variant[1] == 2); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("array 16") { | ||||
|     DynamicJsonVariant variant; | ||||
|  | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDC\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two strings") { | ||||
|       const char* input = "\xDC\x00\x02\xA5hello\xA5world"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 2); | ||||
|       REQUIRE(variant[0] == "hello"); | ||||
|       REQUIRE(variant[1] == "world"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("array 32") { | ||||
|     DynamicJsonVariant variant; | ||||
|  | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDD\x00\x00\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two floats") { | ||||
|       const char* input = | ||||
|           "\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 2); | ||||
|       REQUIRE(variant[0] == 0.0f); | ||||
|       REQUIRE(variant[1] == 3.14f); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("fixmap") { | ||||
|     DynamicJsonVariant variant; | ||||
|  | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\x80"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two integers") { | ||||
|       const char* input = "\x82\xA3one\x01\xA3two\x02"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 2); | ||||
|       REQUIRE(variant["one"] == 1); | ||||
|       REQUIRE(variant["two"] == 2); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("map 16") { | ||||
|     DynamicJsonVariant variant; | ||||
|  | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDE\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two strings") { | ||||
|       const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 2); | ||||
|       REQUIRE(variant["H"] == "hello"); | ||||
|       REQUIRE(variant["W"] == "world"); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   SECTION("map 32") { | ||||
|     DynamicJsonVariant variant; | ||||
|  | ||||
|     SECTION("empty") { | ||||
|       const char* input = "\xDF\x00\x00\x00\x00"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 0); | ||||
|     } | ||||
|  | ||||
|     SECTION("two floats") { | ||||
|       const char* input = | ||||
|           "\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48" | ||||
|           "\xF5\xC3"; | ||||
|  | ||||
|       MsgPackError error = deserializeMsgPack(variant, input); | ||||
|  | ||||
|       REQUIRE(error == MsgPackError::Ok); | ||||
|       REQUIRE(variant.size() == 2); | ||||
|       REQUIRE(variant["zero"] == 0.0f); | ||||
|       REQUIRE(variant["pi"] == 3.14f); | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -2,9 +2,11 @@ | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <ArduinoJson/Memory/StaticJsonBuffer.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| static bool isAligned(void *ptr) { | ||||
|   const size_t mask = sizeof(void *) - 1; | ||||
|   size_t addr = reinterpret_cast<size_t>(ptr); | ||||
|   | ||||
| @@ -2,9 +2,11 @@ | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <ArduinoJson/Memory/StaticJsonBuffer.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| TEST_CASE("StaticJsonBuffer::size()") { | ||||
|   StaticJsonBuffer<64> buffer; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user