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