From de47c0af9e5d8133f6f54108dcfd6b3485b27d2c Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Wed, 27 Dec 2017 14:15:49 +0100 Subject: [PATCH 0001/1079] Updated links to the book --- examples/JsonConfigFile/JsonConfigFile.ino | 2 +- examples/JsonGeneratorExample/JsonGeneratorExample.ino | 2 +- examples/JsonHttpClient/JsonHttpClient.ino | 2 +- examples/JsonParserExample/JsonParserExample.ino | 2 +- examples/JsonServer/JsonServer.ino | 2 +- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 2 +- examples/ProgmemExample/ProgmemExample.ino | 2 +- examples/StringExample/StringExample.ino | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index 182a86ad6..7dafb6526 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -141,4 +141,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a case study of a project that has // a complex configuration with nested members. // Contrary to this example, the project in the book uses the SPIFFS filesystem. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index 87a38f7f6..52b12cc23 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -78,4 +78,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on serialization. // It begins with a simple example, like the one above, and then adds more // features like serializing directly to a file or an HTTP request. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index 1ff84db50..e51218036 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -109,4 +109,4 @@ void loop() { // showing how to parse the response from Yahoo Weather. In the last chapter, // it shows how to parse the huge documents from OpenWeatherMap // and Weather Underground. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 61deb5584..4d35cfc43 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -75,4 +75,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on deserialization. // It begins with a simple example, like the one above, and then adds more // features like deserializing directly from a file or an HTTP request. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index c564a4cc7..fccbb390d 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -106,4 +106,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on serialization. // It begins with a simple example, then adds more features like serializing // directly to a file or an HTTP client. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index f56682281..747b90302 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -98,4 +98,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on serialization. // It begins with a simple example, then adds more features like serializing // directly to a file or any stream. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index c147e7708..9cb76eaae 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -64,4 +64,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a quick C++ course that explains // how your microcontroller stores strings in memory. It also tells why you // should not abuse Flash strings with ArduinoJson. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index 495546f0c..1f6321576 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -68,4 +68,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a quick C++ course that explains // how your microcontroller stores strings in memory. On several occasions, it // shows how you can avoid String in your program. -// Please check it out at: https://leanpub.com/arduinojson/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file From c3f51e2980499a1d78ab3284fe4ab5c2b9ee14de Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 5 Jan 2018 09:17:24 +0100 Subject: [PATCH 0002/1079] Updated links to arduinojson.org --- README.md | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3a11c190a..141425469 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). * [100% code coverage](https://coveralls.io/github/bblanchon/ArduinoJson) * [Header-only library](https://en.wikipedia.org/wiki/Header-only) * [MIT License](https://en.wikipedia.org/wiki/MIT_License) -* [Comprehensive documentation](https://arduinojson.org) +* [Comprehensive documentation](https://arduinojson.org?utm_source=readme) ## Compatibility @@ -69,7 +69,7 @@ double latitude = root["data"][0]; double longitude = root["data"][1]; ``` -See the [tutorial on arduinojson.org](http://arduinojson.org/doc/decoding/) +See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_source=readme) ### Serialization @@ -91,17 +91,20 @@ root.printTo(Serial); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} ``` -See the [tutorial on arduinojson.org](http://arduinojson.org/doc/encoding/) +See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=readme) ## Documentation -The documentation is available on [arduinojson.org](https://arduinojson.org/), here are some shortcuts: +The documentation is available on [arduinojson.org](https://arduinojson.org/?utm_source=readme), here are some shortcuts: -* The [Examples](https://arduinojson.org/example/) show how to use the library in various situations. -* The [API Reference](https://arduinojson.org/api/) contains the description of each class and function. -* The [FAQ](https://arduinojson.org/faq/) has the answer to virtually all questions. -* The [ArduinoJson Assistant](https://arduinojson.org/assistant/) writes programs for you! +* The [Examples](https://arduinojson.org/example/?utm_source=readme) show how to use the library in various situations. +* The [API Reference](https://arduinojson.org/api/?utm_source=readme) contains the description of each class and function. +* The [FAQ](https://arduinojson.org/faq/?utm_source=readme) has the answer to virtually every question. +* The [ArduinoJson Assistant](https://arduinojson.org/assistant/?utm_source=readme) writes programs for you! --- -Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)! \ No newline at end of file +Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)! + +What? You don't like it but you *love* it? +We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=readme), so you can help and learn at the same time! \ No newline at end of file From 5c33fd4b944075d243dfb62c706c07df8de043c9 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 5 Jan 2018 09:20:01 +0100 Subject: [PATCH 0003/1079] Set copyright year to 2018 --- ArduinoJson.h | 2 +- CMakeLists.txt | 2 +- LICENSE.md | 2 +- examples/JsonConfigFile/JsonConfigFile.ino | 2 +- examples/JsonGeneratorExample/JsonGeneratorExample.ino | 2 +- examples/JsonHttpClient/JsonHttpClient.ino | 2 +- examples/JsonParserExample/JsonParserExample.ino | 2 +- examples/JsonServer/JsonServer.ino | 2 +- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 2 +- examples/ProgmemExample/ProgmemExample.ino | 2 +- examples/StringExample/StringExample.ino | 2 +- src/ArduinoJson.h | 2 +- src/ArduinoJson.hpp | 2 +- src/ArduinoJson/Configuration.hpp | 2 +- src/ArduinoJson/Data/Encoding.hpp | 2 +- src/ArduinoJson/Data/JsonBufferAllocated.hpp | 2 +- src/ArduinoJson/Data/JsonFloat.hpp | 2 +- src/ArduinoJson/Data/JsonInteger.hpp | 2 +- src/ArduinoJson/Data/JsonVariantAs.hpp | 2 +- src/ArduinoJson/Data/JsonVariantContent.hpp | 2 +- src/ArduinoJson/Data/JsonVariantDefault.hpp | 2 +- src/ArduinoJson/Data/JsonVariantType.hpp | 2 +- src/ArduinoJson/Data/List.hpp | 2 +- src/ArduinoJson/Data/ListConstIterator.hpp | 2 +- src/ArduinoJson/Data/ListIterator.hpp | 2 +- src/ArduinoJson/Data/ListNode.hpp | 2 +- src/ArduinoJson/Data/NonCopyable.hpp | 2 +- src/ArduinoJson/Data/ReferenceType.hpp | 2 +- src/ArduinoJson/Data/ValueSetter.hpp | 2 +- src/ArduinoJson/Deserialization/Comments.hpp | 2 +- src/ArduinoJson/Deserialization/JsonParser.hpp | 2 +- src/ArduinoJson/Deserialization/JsonParserImpl.hpp | 2 +- src/ArduinoJson/Deserialization/StringWriter.hpp | 2 +- src/ArduinoJson/DynamicJsonBuffer.hpp | 2 +- src/ArduinoJson/JsonArray.hpp | 2 +- src/ArduinoJson/JsonArrayImpl.hpp | 2 +- src/ArduinoJson/JsonArraySubscript.hpp | 2 +- src/ArduinoJson/JsonBuffer.hpp | 2 +- src/ArduinoJson/JsonBufferBase.hpp | 2 +- src/ArduinoJson/JsonBufferImpl.hpp | 2 +- src/ArduinoJson/JsonObject.hpp | 2 +- src/ArduinoJson/JsonObjectImpl.hpp | 2 +- src/ArduinoJson/JsonObjectSubscript.hpp | 2 +- src/ArduinoJson/JsonPair.hpp | 2 +- src/ArduinoJson/JsonVariant.hpp | 2 +- src/ArduinoJson/JsonVariantBase.hpp | 2 +- src/ArduinoJson/JsonVariantCasts.hpp | 2 +- src/ArduinoJson/JsonVariantComparisons.hpp | 2 +- src/ArduinoJson/JsonVariantImpl.hpp | 2 +- src/ArduinoJson/JsonVariantOr.hpp | 2 +- src/ArduinoJson/JsonVariantSubscripts.hpp | 2 +- src/ArduinoJson/Polyfills/attributes.hpp | 2 +- src/ArduinoJson/Polyfills/ctype.hpp | 2 +- src/ArduinoJson/Polyfills/isFloat.hpp | 2 +- src/ArduinoJson/Polyfills/isInteger.hpp | 2 +- src/ArduinoJson/Polyfills/math.hpp | 2 +- src/ArduinoJson/Polyfills/parseFloat.hpp | 2 +- src/ArduinoJson/Polyfills/parseInteger.hpp | 2 +- src/ArduinoJson/RawJson.hpp | 2 +- src/ArduinoJson/Serialization/DummyPrint.hpp | 2 +- src/ArduinoJson/Serialization/DynamicStringBuilder.hpp | 2 +- src/ArduinoJson/Serialization/FloatParts.hpp | 2 +- src/ArduinoJson/Serialization/IndentedPrint.hpp | 2 +- src/ArduinoJson/Serialization/JsonPrintable.hpp | 2 +- src/ArduinoJson/Serialization/JsonSerializer.hpp | 2 +- src/ArduinoJson/Serialization/JsonSerializerImpl.hpp | 2 +- src/ArduinoJson/Serialization/JsonWriter.hpp | 2 +- src/ArduinoJson/Serialization/Prettyfier.hpp | 2 +- src/ArduinoJson/Serialization/StaticStringBuilder.hpp | 2 +- src/ArduinoJson/Serialization/StreamPrintAdapter.hpp | 2 +- src/ArduinoJson/StaticJsonBuffer.hpp | 2 +- src/ArduinoJson/StringTraits/ArduinoStream.hpp | 2 +- src/ArduinoJson/StringTraits/CharPointer.hpp | 2 +- src/ArduinoJson/StringTraits/FlashString.hpp | 2 +- src/ArduinoJson/StringTraits/StdStream.hpp | 2 +- src/ArduinoJson/StringTraits/StdString.hpp | 2 +- src/ArduinoJson/StringTraits/StringTraits.hpp | 2 +- src/ArduinoJson/TypeTraits/EnableIf.hpp | 2 +- src/ArduinoJson/TypeTraits/FloatTraits.hpp | 2 +- src/ArduinoJson/TypeTraits/IsArray.hpp | 2 +- src/ArduinoJson/TypeTraits/IsBaseOf.hpp | 2 +- src/ArduinoJson/TypeTraits/IsChar.hpp | 2 +- src/ArduinoJson/TypeTraits/IsConst.hpp | 2 +- src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp | 2 +- src/ArduinoJson/TypeTraits/IsIntegral.hpp | 2 +- src/ArduinoJson/TypeTraits/IsSame.hpp | 2 +- src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp | 2 +- src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp | 2 +- src/ArduinoJson/TypeTraits/IsVariant.hpp | 2 +- src/ArduinoJson/TypeTraits/RemoveConst.hpp | 2 +- src/ArduinoJson/TypeTraits/RemoveReference.hpp | 2 +- test/CMakeLists.txt | 2 +- test/DynamicJsonBuffer/CMakeLists.txt | 2 +- test/DynamicJsonBuffer/alloc.cpp | 2 +- test/DynamicJsonBuffer/createArray.cpp | 2 +- test/DynamicJsonBuffer/createObject.cpp | 2 +- test/DynamicJsonBuffer/no_memory.cpp | 2 +- test/DynamicJsonBuffer/size.cpp | 2 +- test/DynamicJsonBuffer/startString.cpp | 2 +- test/DynamicJsonBuffer/strdup.cpp | 2 +- test/IntegrationTests/CMakeLists.txt | 2 +- test/IntegrationTests/gbathree.cpp | 2 +- test/IntegrationTests/round_trip.cpp | 2 +- test/JsonArray/CMakeLists.txt | 2 +- test/JsonArray/add.cpp | 2 +- test/JsonArray/basics.cpp | 2 +- test/JsonArray/copyFrom.cpp | 2 +- test/JsonArray/copyTo.cpp | 2 +- test/JsonArray/invalid.cpp | 2 +- test/JsonArray/iterator.cpp | 2 +- test/JsonArray/prettyPrintTo.cpp | 2 +- test/JsonArray/printTo.cpp | 2 +- test/JsonArray/remove.cpp | 2 +- test/JsonArray/set.cpp | 2 +- test/JsonArray/subscript.cpp | 2 +- test/JsonBuffer/CMakeLists.txt | 2 +- test/JsonBuffer/nested.cpp | 2 +- test/JsonBuffer/nestingLimit.cpp | 2 +- test/JsonBuffer/parse.cpp | 2 +- test/JsonBuffer/parseArray.cpp | 2 +- test/JsonBuffer/parseObject.cpp | 2 +- test/JsonObject/CMakeLists.txt | 2 +- test/JsonObject/basics.cpp | 2 +- test/JsonObject/containsKey.cpp | 2 +- test/JsonObject/get.cpp | 2 +- test/JsonObject/invalid.cpp | 2 +- test/JsonObject/iterator.cpp | 2 +- test/JsonObject/prettyPrintTo.cpp | 2 +- test/JsonObject/printTo.cpp | 2 +- test/JsonObject/remove.cpp | 2 +- test/JsonObject/set.cpp | 2 +- test/JsonObject/subscript.cpp | 2 +- test/JsonVariant/CMakeLists.txt | 2 +- test/JsonVariant/as.cpp | 2 +- test/JsonVariant/compare.cpp | 2 +- test/JsonVariant/copy.cpp | 2 +- test/JsonVariant/is.cpp | 2 +- test/JsonVariant/or.cpp | 2 +- test/JsonVariant/printTo.cpp | 2 +- test/JsonVariant/set_get.cpp | 2 +- test/JsonVariant/subscript.cpp | 2 +- test/JsonVariant/success.cpp | 2 +- test/JsonVariant/undefined.cpp | 2 +- test/JsonWriter/CMakeLists.txt | 2 +- test/JsonWriter/writeFloat.cpp | 2 +- test/JsonWriter/writeString.cpp | 2 +- test/Misc/CMakeLists.txt | 2 +- test/Misc/FloatParts.cpp | 2 +- test/Misc/StringBuilder.cpp | 2 +- test/Misc/TypeTraits.cpp | 2 +- test/Misc/deprecated.cpp | 2 +- test/Misc/std_stream.cpp | 2 +- test/Misc/std_string.cpp | 2 +- test/Misc/unsigned_char.cpp | 2 +- test/Misc/vla.cpp | 2 +- test/Polyfills/CMakeLists.txt | 2 +- test/Polyfills/isFloat.cpp | 2 +- test/Polyfills/isInteger.cpp | 2 +- test/Polyfills/parseFloat.cpp | 2 +- test/Polyfills/parseInteger.cpp | 2 +- test/StaticJsonBuffer/CMakeLists.txt | 2 +- test/StaticJsonBuffer/alloc.cpp | 2 +- test/StaticJsonBuffer/createArray.cpp | 2 +- test/StaticJsonBuffer/createObject.cpp | 2 +- test/StaticJsonBuffer/parseArray.cpp | 2 +- test/StaticJsonBuffer/parseObject.cpp | 2 +- test/StaticJsonBuffer/size.cpp | 2 +- test/StaticJsonBuffer/startString.cpp | 2 +- third-party/catch/CMakeLists.txt | 2 +- third-party/catch/catch.cpp | 2 +- 170 files changed, 170 insertions(+), 170 deletions(-) diff --git a/ArduinoJson.h b/ArduinoJson.h index b5327564b..9f78b9f18 100644 --- a/ArduinoJson.h +++ b/ArduinoJson.h @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include "src/ArduinoJson.h" diff --git a/CMakeLists.txt b/CMakeLists.txt index ce60a187c..66c565b5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License cmake_minimum_required(VERSION 3.0) diff --git a/LICENSE.md b/LICENSE.md index 627b1767d..247c50843 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,7 +1,7 @@ The MIT License (MIT) --------------------- -Copyright © 2014-2017 Benoit BLANCHON +Copyright © 2014-2018 Benoit BLANCHON Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index 7dafb6526..ce6dca3e6 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows how to store your project configuration in a file. diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index 52b12cc23..fad41ef2f 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows how to generate a JSON document with ArduinoJson. diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index e51218036..6e5c05efc 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows how to parse a JSON document in an HTTP response. diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 4d35cfc43..a9b3ee912 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows how to deserialize a JSON document with ArduinoJson. diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index fccbb390d..229e289ac 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows how to implement an HTTP server that sends JSON document diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index 747b90302..eb9f19a66 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows how to send a JSON document to a UDP socket. diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index 9cb76eaae..287c5067e 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows the different ways you can use Flash strings with diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index 1f6321576..d070d551a 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License // // This example shows the different ways you can use String with ArduinoJson. diff --git a/src/ArduinoJson.h b/src/ArduinoJson.h index 287b04822..3782aeabc 100644 --- a/src/ArduinoJson.h +++ b/src/ArduinoJson.h @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 2798f6066..445a2c8a6 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Configuration.hpp b/src/ArduinoJson/Configuration.hpp index 8370569ce..82483adfa 100644 --- a/src/ArduinoJson/Configuration.hpp +++ b/src/ArduinoJson/Configuration.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/Encoding.hpp b/src/ArduinoJson/Data/Encoding.hpp index 39ea9d65e..a0efa2c74 100644 --- a/src/ArduinoJson/Data/Encoding.hpp +++ b/src/ArduinoJson/Data/Encoding.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/JsonBufferAllocated.hpp b/src/ArduinoJson/Data/JsonBufferAllocated.hpp index e028c150b..443aae4df 100644 --- a/src/ArduinoJson/Data/JsonBufferAllocated.hpp +++ b/src/ArduinoJson/Data/JsonBufferAllocated.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/JsonFloat.hpp b/src/ArduinoJson/Data/JsonFloat.hpp index 2e8cf9be4..0ed42140f 100644 --- a/src/ArduinoJson/Data/JsonFloat.hpp +++ b/src/ArduinoJson/Data/JsonFloat.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/JsonInteger.hpp b/src/ArduinoJson/Data/JsonInteger.hpp index f872f820e..c8ddd00b4 100644 --- a/src/ArduinoJson/Data/JsonInteger.hpp +++ b/src/ArduinoJson/Data/JsonInteger.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/JsonVariantAs.hpp b/src/ArduinoJson/Data/JsonVariantAs.hpp index fcae0fef8..8f202c5eb 100644 --- a/src/ArduinoJson/Data/JsonVariantAs.hpp +++ b/src/ArduinoJson/Data/JsonVariantAs.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/JsonVariantContent.hpp b/src/ArduinoJson/Data/JsonVariantContent.hpp index 94c2adab3..c525a6060 100644 --- a/src/ArduinoJson/Data/JsonVariantContent.hpp +++ b/src/ArduinoJson/Data/JsonVariantContent.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/JsonVariantDefault.hpp b/src/ArduinoJson/Data/JsonVariantDefault.hpp index 9b12ca03a..57ecc83ee 100644 --- a/src/ArduinoJson/Data/JsonVariantDefault.hpp +++ b/src/ArduinoJson/Data/JsonVariantDefault.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/JsonVariantType.hpp b/src/ArduinoJson/Data/JsonVariantType.hpp index 49d21fdba..21f890e52 100644 --- a/src/ArduinoJson/Data/JsonVariantType.hpp +++ b/src/ArduinoJson/Data/JsonVariantType.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/List.hpp b/src/ArduinoJson/Data/List.hpp index 26d8c58d1..506308cc3 100644 --- a/src/ArduinoJson/Data/List.hpp +++ b/src/ArduinoJson/Data/List.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/ListConstIterator.hpp b/src/ArduinoJson/Data/ListConstIterator.hpp index e0b0752b0..a6af685e5 100644 --- a/src/ArduinoJson/Data/ListConstIterator.hpp +++ b/src/ArduinoJson/Data/ListConstIterator.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/ListIterator.hpp b/src/ArduinoJson/Data/ListIterator.hpp index e27e3dc77..01fa287f7 100644 --- a/src/ArduinoJson/Data/ListIterator.hpp +++ b/src/ArduinoJson/Data/ListIterator.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/ListNode.hpp b/src/ArduinoJson/Data/ListNode.hpp index b4e90362b..c0907120e 100644 --- a/src/ArduinoJson/Data/ListNode.hpp +++ b/src/ArduinoJson/Data/ListNode.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/NonCopyable.hpp b/src/ArduinoJson/Data/NonCopyable.hpp index c07b04cee..73f3d8edb 100644 --- a/src/ArduinoJson/Data/NonCopyable.hpp +++ b/src/ArduinoJson/Data/NonCopyable.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/ReferenceType.hpp b/src/ArduinoJson/Data/ReferenceType.hpp index 1f2a861ff..1e491172f 100644 --- a/src/ArduinoJson/Data/ReferenceType.hpp +++ b/src/ArduinoJson/Data/ReferenceType.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Data/ValueSetter.hpp b/src/ArduinoJson/Data/ValueSetter.hpp index 68db56a07..266df2985 100644 --- a/src/ArduinoJson/Data/ValueSetter.hpp +++ b/src/ArduinoJson/Data/ValueSetter.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Deserialization/Comments.hpp b/src/ArduinoJson/Deserialization/Comments.hpp index 3c04be2ec..c2c48ebcc 100644 --- a/src/ArduinoJson/Deserialization/Comments.hpp +++ b/src/ArduinoJson/Deserialization/Comments.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index 02c9c2017..bd26a15c8 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 56f27b5c1..3921225bb 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Deserialization/StringWriter.hpp b/src/ArduinoJson/Deserialization/StringWriter.hpp index af1d8021f..fd5507ea5 100644 --- a/src/ArduinoJson/Deserialization/StringWriter.hpp +++ b/src/ArduinoJson/Deserialization/StringWriter.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/DynamicJsonBuffer.hpp b/src/ArduinoJson/DynamicJsonBuffer.hpp index da7fa8395..fc8270f00 100644 --- a/src/ArduinoJson/DynamicJsonBuffer.hpp +++ b/src/ArduinoJson/DynamicJsonBuffer.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 7906b97d0..8ce21d7c6 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonArrayImpl.hpp b/src/ArduinoJson/JsonArrayImpl.hpp index fe5902116..924b7ea7a 100644 --- a/src/ArduinoJson/JsonArrayImpl.hpp +++ b/src/ArduinoJson/JsonArrayImpl.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonArraySubscript.hpp b/src/ArduinoJson/JsonArraySubscript.hpp index b156602bc..06d33094f 100644 --- a/src/ArduinoJson/JsonArraySubscript.hpp +++ b/src/ArduinoJson/JsonArraySubscript.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonBuffer.hpp b/src/ArduinoJson/JsonBuffer.hpp index 79f31f0bf..5a42a7d00 100644 --- a/src/ArduinoJson/JsonBuffer.hpp +++ b/src/ArduinoJson/JsonBuffer.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonBufferBase.hpp b/src/ArduinoJson/JsonBufferBase.hpp index 051444d70..08be31fbe 100644 --- a/src/ArduinoJson/JsonBufferBase.hpp +++ b/src/ArduinoJson/JsonBufferBase.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonBufferImpl.hpp b/src/ArduinoJson/JsonBufferImpl.hpp index 4746aec05..cdea374bb 100644 --- a/src/ArduinoJson/JsonBufferImpl.hpp +++ b/src/ArduinoJson/JsonBufferImpl.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 2209c9bc7..5dff10903 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonObjectImpl.hpp b/src/ArduinoJson/JsonObjectImpl.hpp index 313df4533..e7689b507 100644 --- a/src/ArduinoJson/JsonObjectImpl.hpp +++ b/src/ArduinoJson/JsonObjectImpl.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index 393473a53..1657cf77c 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonPair.hpp b/src/ArduinoJson/JsonPair.hpp index 0030955de..417243045 100644 --- a/src/ArduinoJson/JsonPair.hpp +++ b/src/ArduinoJson/JsonPair.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index 8162dc678..f2d7ff95b 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonVariantBase.hpp b/src/ArduinoJson/JsonVariantBase.hpp index 46f18a6f8..8c669eb54 100644 --- a/src/ArduinoJson/JsonVariantBase.hpp +++ b/src/ArduinoJson/JsonVariantBase.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonVariantCasts.hpp b/src/ArduinoJson/JsonVariantCasts.hpp index 5f6377f00..85a96de4a 100644 --- a/src/ArduinoJson/JsonVariantCasts.hpp +++ b/src/ArduinoJson/JsonVariantCasts.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonVariantComparisons.hpp b/src/ArduinoJson/JsonVariantComparisons.hpp index 049e95689..156d0db32 100644 --- a/src/ArduinoJson/JsonVariantComparisons.hpp +++ b/src/ArduinoJson/JsonVariantComparisons.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonVariantImpl.hpp b/src/ArduinoJson/JsonVariantImpl.hpp index b84ee1a60..1ebec9813 100644 --- a/src/ArduinoJson/JsonVariantImpl.hpp +++ b/src/ArduinoJson/JsonVariantImpl.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonVariantOr.hpp b/src/ArduinoJson/JsonVariantOr.hpp index 564f1dc3b..895737ba7 100644 --- a/src/ArduinoJson/JsonVariantOr.hpp +++ b/src/ArduinoJson/JsonVariantOr.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/JsonVariantSubscripts.hpp b/src/ArduinoJson/JsonVariantSubscripts.hpp index 86f7a5696..210f26113 100644 --- a/src/ArduinoJson/JsonVariantSubscripts.hpp +++ b/src/ArduinoJson/JsonVariantSubscripts.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Polyfills/attributes.hpp b/src/ArduinoJson/Polyfills/attributes.hpp index 9f0e03a49..2c4e7e6c4 100644 --- a/src/ArduinoJson/Polyfills/attributes.hpp +++ b/src/ArduinoJson/Polyfills/attributes.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Polyfills/ctype.hpp b/src/ArduinoJson/Polyfills/ctype.hpp index a306357a1..0e0f973e8 100644 --- a/src/ArduinoJson/Polyfills/ctype.hpp +++ b/src/ArduinoJson/Polyfills/ctype.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Polyfills/isFloat.hpp b/src/ArduinoJson/Polyfills/isFloat.hpp index a9019b104..c89f8c4b0 100644 --- a/src/ArduinoJson/Polyfills/isFloat.hpp +++ b/src/ArduinoJson/Polyfills/isFloat.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Polyfills/isInteger.hpp b/src/ArduinoJson/Polyfills/isInteger.hpp index 3d9b0f4ef..d63fdfba4 100644 --- a/src/ArduinoJson/Polyfills/isInteger.hpp +++ b/src/ArduinoJson/Polyfills/isInteger.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Polyfills/math.hpp b/src/ArduinoJson/Polyfills/math.hpp index aec12d5e3..3c631631a 100644 --- a/src/ArduinoJson/Polyfills/math.hpp +++ b/src/ArduinoJson/Polyfills/math.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Polyfills/parseFloat.hpp b/src/ArduinoJson/Polyfills/parseFloat.hpp index c3792dcb9..54034c5cf 100644 --- a/src/ArduinoJson/Polyfills/parseFloat.hpp +++ b/src/ArduinoJson/Polyfills/parseFloat.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Polyfills/parseInteger.hpp b/src/ArduinoJson/Polyfills/parseInteger.hpp index bcab87a49..a1feb2aa1 100644 --- a/src/ArduinoJson/Polyfills/parseInteger.hpp +++ b/src/ArduinoJson/Polyfills/parseInteger.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/RawJson.hpp b/src/ArduinoJson/RawJson.hpp index c02f2a00b..5477278fd 100644 --- a/src/ArduinoJson/RawJson.hpp +++ b/src/ArduinoJson/RawJson.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/DummyPrint.hpp b/src/ArduinoJson/Serialization/DummyPrint.hpp index 209db9b92..9fdf2d6a0 100644 --- a/src/ArduinoJson/Serialization/DummyPrint.hpp +++ b/src/ArduinoJson/Serialization/DummyPrint.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp b/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp index 5cf956f74..41be6392c 100644 --- a/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp +++ b/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/FloatParts.hpp b/src/ArduinoJson/Serialization/FloatParts.hpp index 3a417439a..aceaa6384 100644 --- a/src/ArduinoJson/Serialization/FloatParts.hpp +++ b/src/ArduinoJson/Serialization/FloatParts.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/IndentedPrint.hpp b/src/ArduinoJson/Serialization/IndentedPrint.hpp index fea59788f..864f9aaa4 100644 --- a/src/ArduinoJson/Serialization/IndentedPrint.hpp +++ b/src/ArduinoJson/Serialization/IndentedPrint.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/JsonPrintable.hpp b/src/ArduinoJson/Serialization/JsonPrintable.hpp index d427dd759..9ea4bfb4a 100644 --- a/src/ArduinoJson/Serialization/JsonPrintable.hpp +++ b/src/ArduinoJson/Serialization/JsonPrintable.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Serialization/JsonSerializer.hpp index 3aacbdf21..c431ac839 100644 --- a/src/ArduinoJson/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Serialization/JsonSerializer.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp b/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp index 3c3560dc6..0faae2769 100644 --- a/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp +++ b/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/JsonWriter.hpp b/src/ArduinoJson/Serialization/JsonWriter.hpp index 055aab668..62027e9f1 100644 --- a/src/ArduinoJson/Serialization/JsonWriter.hpp +++ b/src/ArduinoJson/Serialization/JsonWriter.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/Prettyfier.hpp b/src/ArduinoJson/Serialization/Prettyfier.hpp index 6f3ee74bd..8b4f0d2eb 100644 --- a/src/ArduinoJson/Serialization/Prettyfier.hpp +++ b/src/ArduinoJson/Serialization/Prettyfier.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/StaticStringBuilder.hpp b/src/ArduinoJson/Serialization/StaticStringBuilder.hpp index 722574a39..9617bbd97 100644 --- a/src/ArduinoJson/Serialization/StaticStringBuilder.hpp +++ b/src/ArduinoJson/Serialization/StaticStringBuilder.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/Serialization/StreamPrintAdapter.hpp b/src/ArduinoJson/Serialization/StreamPrintAdapter.hpp index 6ae21632b..60f0af4a3 100644 --- a/src/ArduinoJson/Serialization/StreamPrintAdapter.hpp +++ b/src/ArduinoJson/Serialization/StreamPrintAdapter.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/StaticJsonBuffer.hpp b/src/ArduinoJson/StaticJsonBuffer.hpp index 70123f2e0..c68eb7125 100644 --- a/src/ArduinoJson/StaticJsonBuffer.hpp +++ b/src/ArduinoJson/StaticJsonBuffer.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/StringTraits/ArduinoStream.hpp b/src/ArduinoJson/StringTraits/ArduinoStream.hpp index 3a9eb65e8..0fe08100b 100644 --- a/src/ArduinoJson/StringTraits/ArduinoStream.hpp +++ b/src/ArduinoJson/StringTraits/ArduinoStream.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/StringTraits/CharPointer.hpp b/src/ArduinoJson/StringTraits/CharPointer.hpp index c2519665f..b41e47dab 100644 --- a/src/ArduinoJson/StringTraits/CharPointer.hpp +++ b/src/ArduinoJson/StringTraits/CharPointer.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/StringTraits/FlashString.hpp b/src/ArduinoJson/StringTraits/FlashString.hpp index dd668d101..2530ceeef 100644 --- a/src/ArduinoJson/StringTraits/FlashString.hpp +++ b/src/ArduinoJson/StringTraits/FlashString.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/StringTraits/StdStream.hpp b/src/ArduinoJson/StringTraits/StdStream.hpp index 322720dc8..ef2033916 100644 --- a/src/ArduinoJson/StringTraits/StdStream.hpp +++ b/src/ArduinoJson/StringTraits/StdStream.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/StringTraits/StdString.hpp b/src/ArduinoJson/StringTraits/StdString.hpp index 108704f2e..d7b14b208 100644 --- a/src/ArduinoJson/StringTraits/StdString.hpp +++ b/src/ArduinoJson/StringTraits/StdString.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/StringTraits/StringTraits.hpp b/src/ArduinoJson/StringTraits/StringTraits.hpp index 75d933c58..eec04dc53 100644 --- a/src/ArduinoJson/StringTraits/StringTraits.hpp +++ b/src/ArduinoJson/StringTraits/StringTraits.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/EnableIf.hpp b/src/ArduinoJson/TypeTraits/EnableIf.hpp index 6c7f0b16d..c07b217f0 100644 --- a/src/ArduinoJson/TypeTraits/EnableIf.hpp +++ b/src/ArduinoJson/TypeTraits/EnableIf.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/FloatTraits.hpp b/src/ArduinoJson/TypeTraits/FloatTraits.hpp index 5d89fa3a7..d7acd05ee 100644 --- a/src/ArduinoJson/TypeTraits/FloatTraits.hpp +++ b/src/ArduinoJson/TypeTraits/FloatTraits.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsArray.hpp b/src/ArduinoJson/TypeTraits/IsArray.hpp index 62ffbca95..c65d00ebb 100644 --- a/src/ArduinoJson/TypeTraits/IsArray.hpp +++ b/src/ArduinoJson/TypeTraits/IsArray.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsBaseOf.hpp b/src/ArduinoJson/TypeTraits/IsBaseOf.hpp index 36d74136b..30e51b5d3 100644 --- a/src/ArduinoJson/TypeTraits/IsBaseOf.hpp +++ b/src/ArduinoJson/TypeTraits/IsBaseOf.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsChar.hpp b/src/ArduinoJson/TypeTraits/IsChar.hpp index d616507fb..8e210d76d 100644 --- a/src/ArduinoJson/TypeTraits/IsChar.hpp +++ b/src/ArduinoJson/TypeTraits/IsChar.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsConst.hpp b/src/ArduinoJson/TypeTraits/IsConst.hpp index 9e0e8c6dd..295d03c84 100644 --- a/src/ArduinoJson/TypeTraits/IsConst.hpp +++ b/src/ArduinoJson/TypeTraits/IsConst.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp b/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp index f0c22a015..7e3d305b5 100644 --- a/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp +++ b/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsIntegral.hpp b/src/ArduinoJson/TypeTraits/IsIntegral.hpp index 5d89ff7f0..a319f5cc8 100644 --- a/src/ArduinoJson/TypeTraits/IsIntegral.hpp +++ b/src/ArduinoJson/TypeTraits/IsIntegral.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsSame.hpp b/src/ArduinoJson/TypeTraits/IsSame.hpp index 14a742978..bbf3ec17c 100644 --- a/src/ArduinoJson/TypeTraits/IsSame.hpp +++ b/src/ArduinoJson/TypeTraits/IsSame.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp b/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp index 2b52a36b9..8b590087f 100644 --- a/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp +++ b/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp b/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp index aa7f10f9a..0e43ab01f 100644 --- a/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp +++ b/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/IsVariant.hpp b/src/ArduinoJson/TypeTraits/IsVariant.hpp index 1050c3747..85a5e3fef 100644 --- a/src/ArduinoJson/TypeTraits/IsVariant.hpp +++ b/src/ArduinoJson/TypeTraits/IsVariant.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/RemoveConst.hpp b/src/ArduinoJson/TypeTraits/RemoveConst.hpp index 5c8ae69c2..f9714bd3b 100644 --- a/src/ArduinoJson/TypeTraits/RemoveConst.hpp +++ b/src/ArduinoJson/TypeTraits/RemoveConst.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/src/ArduinoJson/TypeTraits/RemoveReference.hpp b/src/ArduinoJson/TypeTraits/RemoveReference.hpp index 3f05125c2..8d5a929fb 100644 --- a/src/ArduinoJson/TypeTraits/RemoveReference.hpp +++ b/src/ArduinoJson/TypeTraits/RemoveReference.hpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #pragma once diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index bdc6a7eb9..4fee0ea1c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") diff --git a/test/DynamicJsonBuffer/CMakeLists.txt b/test/DynamicJsonBuffer/CMakeLists.txt index 358e33b53..f028ccc4f 100644 --- a/test/DynamicJsonBuffer/CMakeLists.txt +++ b/test/DynamicJsonBuffer/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(DynamicJsonBufferTests diff --git a/test/DynamicJsonBuffer/alloc.cpp b/test/DynamicJsonBuffer/alloc.cpp index 2e5ea04eb..54b7842ca 100644 --- a/test/DynamicJsonBuffer/alloc.cpp +++ b/test/DynamicJsonBuffer/alloc.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/DynamicJsonBuffer/createArray.cpp b/test/DynamicJsonBuffer/createArray.cpp index 1ddb60c33..34ab07e97 100644 --- a/test/DynamicJsonBuffer/createArray.cpp +++ b/test/DynamicJsonBuffer/createArray.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/DynamicJsonBuffer/createObject.cpp b/test/DynamicJsonBuffer/createObject.cpp index 713c0f6c2..2193a659b 100644 --- a/test/DynamicJsonBuffer/createObject.cpp +++ b/test/DynamicJsonBuffer/createObject.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index 3c84d585a..013b17414 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/DynamicJsonBuffer/size.cpp b/test/DynamicJsonBuffer/size.cpp index 76e103493..8ebba424c 100644 --- a/test/DynamicJsonBuffer/size.cpp +++ b/test/DynamicJsonBuffer/size.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/DynamicJsonBuffer/startString.cpp b/test/DynamicJsonBuffer/startString.cpp index 8bc9b5a14..2e5bef7fe 100644 --- a/test/DynamicJsonBuffer/startString.cpp +++ b/test/DynamicJsonBuffer/startString.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/DynamicJsonBuffer/strdup.cpp b/test/DynamicJsonBuffer/strdup.cpp index f51587953..9feea4219 100644 --- a/test/DynamicJsonBuffer/strdup.cpp +++ b/test/DynamicJsonBuffer/strdup.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/IntegrationTests/CMakeLists.txt b/test/IntegrationTests/CMakeLists.txt index 266bfa8b4..9294bbbf9 100644 --- a/test/IntegrationTests/CMakeLists.txt +++ b/test/IntegrationTests/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(IntegrationTests diff --git a/test/IntegrationTests/gbathree.cpp b/test/IntegrationTests/gbathree.cpp index f4c5a9bcd..9a5144251 100644 --- a/test/IntegrationTests/gbathree.cpp +++ b/test/IntegrationTests/gbathree.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/IntegrationTests/round_trip.cpp b/test/IntegrationTests/round_trip.cpp index 1a1f8b9e1..ec8c0b0cb 100644 --- a/test/IntegrationTests/round_trip.cpp +++ b/test/IntegrationTests/round_trip.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/CMakeLists.txt b/test/JsonArray/CMakeLists.txt index 82f568d48..7d48a1ac8 100644 --- a/test/JsonArray/CMakeLists.txt +++ b/test/JsonArray/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(JsonArrayTests diff --git a/test/JsonArray/add.cpp b/test/JsonArray/add.cpp index 384675f95..c344457c8 100644 --- a/test/JsonArray/add.cpp +++ b/test/JsonArray/add.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/basics.cpp b/test/JsonArray/basics.cpp index b12a5e257..eada17e25 100644 --- a/test/JsonArray/basics.cpp +++ b/test/JsonArray/basics.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/copyFrom.cpp b/test/JsonArray/copyFrom.cpp index 892ae17c3..850301a7e 100644 --- a/test/JsonArray/copyFrom.cpp +++ b/test/JsonArray/copyFrom.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/copyTo.cpp b/test/JsonArray/copyTo.cpp index 90d8380b0..901505902 100644 --- a/test/JsonArray/copyTo.cpp +++ b/test/JsonArray/copyTo.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/invalid.cpp b/test/JsonArray/invalid.cpp index 470e682d0..045517bab 100644 --- a/test/JsonArray/invalid.cpp +++ b/test/JsonArray/invalid.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/iterator.cpp b/test/JsonArray/iterator.cpp index e9f001283..fff819645 100644 --- a/test/JsonArray/iterator.cpp +++ b/test/JsonArray/iterator.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/prettyPrintTo.cpp b/test/JsonArray/prettyPrintTo.cpp index 078b23dfc..fc5c526da 100644 --- a/test/JsonArray/prettyPrintTo.cpp +++ b/test/JsonArray/prettyPrintTo.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/printTo.cpp b/test/JsonArray/printTo.cpp index d07e2e853..73f14ac62 100644 --- a/test/JsonArray/printTo.cpp +++ b/test/JsonArray/printTo.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/remove.cpp b/test/JsonArray/remove.cpp index 5fda9ebde..089358183 100644 --- a/test/JsonArray/remove.cpp +++ b/test/JsonArray/remove.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/set.cpp b/test/JsonArray/set.cpp index 1c0ad80b0..77e737d13 100644 --- a/test/JsonArray/set.cpp +++ b/test/JsonArray/set.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonArray/subscript.cpp b/test/JsonArray/subscript.cpp index aee9dd85c..f1551c15b 100644 --- a/test/JsonArray/subscript.cpp +++ b/test/JsonArray/subscript.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonBuffer/CMakeLists.txt b/test/JsonBuffer/CMakeLists.txt index 6e1797d98..34b3e735a 100644 --- a/test/JsonBuffer/CMakeLists.txt +++ b/test/JsonBuffer/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(JsonBufferTests diff --git a/test/JsonBuffer/nested.cpp b/test/JsonBuffer/nested.cpp index 25746ec6d..263e40e64 100644 --- a/test/JsonBuffer/nested.cpp +++ b/test/JsonBuffer/nested.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonBuffer/nestingLimit.cpp b/test/JsonBuffer/nestingLimit.cpp index c328bee3c..0d7be1151 100644 --- a/test/JsonBuffer/nestingLimit.cpp +++ b/test/JsonBuffer/nestingLimit.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonBuffer/parse.cpp b/test/JsonBuffer/parse.cpp index 03ad55378..70e57918c 100644 --- a/test/JsonBuffer/parse.cpp +++ b/test/JsonBuffer/parse.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonBuffer/parseArray.cpp b/test/JsonBuffer/parseArray.cpp index fa464500e..2e843f8cf 100644 --- a/test/JsonBuffer/parseArray.cpp +++ b/test/JsonBuffer/parseArray.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonBuffer/parseObject.cpp b/test/JsonBuffer/parseObject.cpp index deb8f5242..1af6bde1a 100644 --- a/test/JsonBuffer/parseObject.cpp +++ b/test/JsonBuffer/parseObject.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/CMakeLists.txt b/test/JsonObject/CMakeLists.txt index 61dce9f80..a1b079696 100644 --- a/test/JsonObject/CMakeLists.txt +++ b/test/JsonObject/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(JsonObjectTests diff --git a/test/JsonObject/basics.cpp b/test/JsonObject/basics.cpp index 275c28733..dd9817029 100644 --- a/test/JsonObject/basics.cpp +++ b/test/JsonObject/basics.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/containsKey.cpp b/test/JsonObject/containsKey.cpp index e1dda37b0..f8d0a1520 100644 --- a/test/JsonObject/containsKey.cpp +++ b/test/JsonObject/containsKey.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/get.cpp b/test/JsonObject/get.cpp index f2c0e968d..b3635956a 100644 --- a/test/JsonObject/get.cpp +++ b/test/JsonObject/get.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/invalid.cpp b/test/JsonObject/invalid.cpp index be7e2a522..019ced10c 100644 --- a/test/JsonObject/invalid.cpp +++ b/test/JsonObject/invalid.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/iterator.cpp b/test/JsonObject/iterator.cpp index b2563c25a..e765d5c71 100644 --- a/test/JsonObject/iterator.cpp +++ b/test/JsonObject/iterator.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/prettyPrintTo.cpp b/test/JsonObject/prettyPrintTo.cpp index 55fd52a8e..304592469 100644 --- a/test/JsonObject/prettyPrintTo.cpp +++ b/test/JsonObject/prettyPrintTo.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/printTo.cpp b/test/JsonObject/printTo.cpp index c3e537ec9..6d0bcc9ad 100644 --- a/test/JsonObject/printTo.cpp +++ b/test/JsonObject/printTo.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/remove.cpp b/test/JsonObject/remove.cpp index fce58affb..0e68eec05 100644 --- a/test/JsonObject/remove.cpp +++ b/test/JsonObject/remove.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/set.cpp b/test/JsonObject/set.cpp index 5e873d149..b70de49d6 100644 --- a/test/JsonObject/set.cpp +++ b/test/JsonObject/set.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonObject/subscript.cpp b/test/JsonObject/subscript.cpp index f581b5368..23710570e 100644 --- a/test/JsonObject/subscript.cpp +++ b/test/JsonObject/subscript.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/CMakeLists.txt b/test/JsonVariant/CMakeLists.txt index 02bff3df4..0a00a15a1 100644 --- a/test/JsonVariant/CMakeLists.txt +++ b/test/JsonVariant/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(JsonVariantTests diff --git a/test/JsonVariant/as.cpp b/test/JsonVariant/as.cpp index efa16912e..6d3b11cc2 100644 --- a/test/JsonVariant/as.cpp +++ b/test/JsonVariant/as.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/compare.cpp b/test/JsonVariant/compare.cpp index 81361a5a8..965ec8efc 100644 --- a/test/JsonVariant/compare.cpp +++ b/test/JsonVariant/compare.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/copy.cpp b/test/JsonVariant/copy.cpp index 9cbf97824..50e0a3bf1 100644 --- a/test/JsonVariant/copy.cpp +++ b/test/JsonVariant/copy.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/is.cpp b/test/JsonVariant/is.cpp index d955a7763..1bb03cbbc 100644 --- a/test/JsonVariant/is.cpp +++ b/test/JsonVariant/is.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/or.cpp b/test/JsonVariant/or.cpp index 98a7f6118..51687deaf 100644 --- a/test/JsonVariant/or.cpp +++ b/test/JsonVariant/or.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/printTo.cpp b/test/JsonVariant/printTo.cpp index e84067479..3431eaeee 100644 --- a/test/JsonVariant/printTo.cpp +++ b/test/JsonVariant/printTo.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/set_get.cpp b/test/JsonVariant/set_get.cpp index a615ec85c..af68c8b05 100644 --- a/test/JsonVariant/set_get.cpp +++ b/test/JsonVariant/set_get.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/subscript.cpp b/test/JsonVariant/subscript.cpp index 9412d1f83..5ce13e6f6 100644 --- a/test/JsonVariant/subscript.cpp +++ b/test/JsonVariant/subscript.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/success.cpp b/test/JsonVariant/success.cpp index b01db2647..af8aad940 100644 --- a/test/JsonVariant/success.cpp +++ b/test/JsonVariant/success.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonVariant/undefined.cpp b/test/JsonVariant/undefined.cpp index fa71cf949..9615f0f4c 100644 --- a/test/JsonVariant/undefined.cpp +++ b/test/JsonVariant/undefined.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonWriter/CMakeLists.txt b/test/JsonWriter/CMakeLists.txt index f2ca45c27..12a12bfdd 100644 --- a/test/JsonWriter/CMakeLists.txt +++ b/test/JsonWriter/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(JsonWriterTests diff --git a/test/JsonWriter/writeFloat.cpp b/test/JsonWriter/writeFloat.cpp index 1d3726239..532de5dc6 100644 --- a/test/JsonWriter/writeFloat.cpp +++ b/test/JsonWriter/writeFloat.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/JsonWriter/writeString.cpp b/test/JsonWriter/writeString.cpp index 5be6722c8..e583fbcf5 100644 --- a/test/JsonWriter/writeString.cpp +++ b/test/JsonWriter/writeString.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Misc/CMakeLists.txt b/test/Misc/CMakeLists.txt index 363ebce9e..5b5726010 100644 --- a/test/Misc/CMakeLists.txt +++ b/test/Misc/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(MiscTests diff --git a/test/Misc/FloatParts.cpp b/test/Misc/FloatParts.cpp index 517d4cc2a..aeed52e75 100644 --- a/test/Misc/FloatParts.cpp +++ b/test/Misc/FloatParts.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Misc/StringBuilder.cpp b/test/Misc/StringBuilder.cpp index 13a4ee0ed..a7132dbd9 100644 --- a/test/Misc/StringBuilder.cpp +++ b/test/Misc/StringBuilder.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Misc/TypeTraits.cpp b/test/Misc/TypeTraits.cpp index 7281a42ce..1619591a2 100644 --- a/test/Misc/TypeTraits.cpp +++ b/test/Misc/TypeTraits.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Misc/deprecated.cpp b/test/Misc/deprecated.cpp index d00aee01e..bc7f97ba8 100644 --- a/test/Misc/deprecated.cpp +++ b/test/Misc/deprecated.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #define ARDUINOJSON_ENABLE_DEPRECATED 1 diff --git a/test/Misc/std_stream.cpp b/test/Misc/std_stream.cpp index 602e3f22c..170c9418a 100644 --- a/test/Misc/std_stream.cpp +++ b/test/Misc/std_stream.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index 65c1e1f70..00b76e839 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 90daa680c..5d7a47e02 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 8257f0d77..1e5ee1e24 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Polyfills/CMakeLists.txt b/test/Polyfills/CMakeLists.txt index 9fef31851..d96ce719d 100644 --- a/test/Polyfills/CMakeLists.txt +++ b/test/Polyfills/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(PolyfillsTests diff --git a/test/Polyfills/isFloat.cpp b/test/Polyfills/isFloat.cpp index 70591ee82..033f91548 100644 --- a/test/Polyfills/isFloat.cpp +++ b/test/Polyfills/isFloat.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Polyfills/isInteger.cpp b/test/Polyfills/isInteger.cpp index ff6e3dbb4..64f5937e0 100644 --- a/test/Polyfills/isInteger.cpp +++ b/test/Polyfills/isInteger.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Polyfills/parseFloat.cpp b/test/Polyfills/parseFloat.cpp index c44622824..c57bc413a 100644 --- a/test/Polyfills/parseFloat.cpp +++ b/test/Polyfills/parseFloat.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/Polyfills/parseInteger.cpp b/test/Polyfills/parseInteger.cpp index 3010bb0cb..50e5eedbe 100644 --- a/test/Polyfills/parseInteger.cpp +++ b/test/Polyfills/parseInteger.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/StaticJsonBuffer/CMakeLists.txt b/test/StaticJsonBuffer/CMakeLists.txt index f4777beee..00c78dfa5 100644 --- a/test/StaticJsonBuffer/CMakeLists.txt +++ b/test/StaticJsonBuffer/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_executable(StaticJsonBufferTests diff --git a/test/StaticJsonBuffer/alloc.cpp b/test/StaticJsonBuffer/alloc.cpp index fda11f1a6..9141def82 100644 --- a/test/StaticJsonBuffer/alloc.cpp +++ b/test/StaticJsonBuffer/alloc.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/StaticJsonBuffer/createArray.cpp b/test/StaticJsonBuffer/createArray.cpp index fd7eff7a6..9f0d3bd5f 100644 --- a/test/StaticJsonBuffer/createArray.cpp +++ b/test/StaticJsonBuffer/createArray.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/StaticJsonBuffer/createObject.cpp b/test/StaticJsonBuffer/createObject.cpp index b47e42362..c51e9bb95 100644 --- a/test/StaticJsonBuffer/createObject.cpp +++ b/test/StaticJsonBuffer/createObject.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/StaticJsonBuffer/parseArray.cpp b/test/StaticJsonBuffer/parseArray.cpp index ee22c2fc0..f2feda995 100644 --- a/test/StaticJsonBuffer/parseArray.cpp +++ b/test/StaticJsonBuffer/parseArray.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/StaticJsonBuffer/parseObject.cpp b/test/StaticJsonBuffer/parseObject.cpp index 8c413c639..83601d672 100644 --- a/test/StaticJsonBuffer/parseObject.cpp +++ b/test/StaticJsonBuffer/parseObject.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/StaticJsonBuffer/size.cpp b/test/StaticJsonBuffer/size.cpp index 1105821b9..5ef76bf4f 100644 --- a/test/StaticJsonBuffer/size.cpp +++ b/test/StaticJsonBuffer/size.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/test/StaticJsonBuffer/startString.cpp b/test/StaticJsonBuffer/startString.cpp index 922e4e617..5bfce16a4 100644 --- a/test/StaticJsonBuffer/startString.cpp +++ b/test/StaticJsonBuffer/startString.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #include diff --git a/third-party/catch/CMakeLists.txt b/third-party/catch/CMakeLists.txt index d518e8ccf..59515f541 100644 --- a/third-party/catch/CMakeLists.txt +++ b/third-party/catch/CMakeLists.txt @@ -1,5 +1,5 @@ # ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2017 +# Copyright Benoit Blanchon 2014-2018 # MIT License add_library(catch diff --git a/third-party/catch/catch.cpp b/third-party/catch/catch.cpp index 4d8b7b6aa..2eb9b09ec 100644 --- a/third-party/catch/catch.cpp +++ b/third-party/catch/catch.cpp @@ -1,5 +1,5 @@ // ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2017 +// Copyright Benoit Blanchon 2014-2018 // MIT License #define CATCH_CONFIG_MAIN From e92612b51156d0429c069402b4ffba609b166632 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sun, 14 Jan 2018 13:46:28 +0100 Subject: [PATCH 0004/1079] Changed the rules of string duplication (fixes #658) --- CHANGELOG.md | 16 ++ src/ArduinoJson/Data/ValueSaver.hpp | 34 ++++ src/ArduinoJson/Data/ValueSetter.hpp | 48 ------ src/ArduinoJson/JsonArray.hpp | 32 ++-- src/ArduinoJson/JsonArraySubscript.hpp | 18 +-- src/ArduinoJson/JsonObject.hpp | 153 +++++++----------- src/ArduinoJson/JsonObjectSubscript.hpp | 14 +- src/ArduinoJson/Polyfills/attributes.hpp | 2 +- src/ArduinoJson/StringTraits/CharPointer.hpp | 41 ++++- src/ArduinoJson/StringTraits/FlashString.hpp | 16 +- src/ArduinoJson/StringTraits/StdString.hpp | 17 +- src/ArduinoJson/StringTraits/StringTraits.hpp | 1 + test/JsonArray/CMakeLists.txt | 1 + test/JsonArray/add.cpp | 25 ++- test/JsonArray/set.cpp | 23 ++- test/JsonArray/size.cpp | 35 ++++ test/JsonArray/subscript.cpp | 23 ++- test/JsonObject/CMakeLists.txt | 1 + test/JsonObject/set.cpp | 57 +++++-- test/JsonObject/size.cpp | 23 +++ test/JsonObject/subscript.cpp | 55 +++++-- test/Misc/TypeTraits.cpp | 5 + 22 files changed, 416 insertions(+), 224 deletions(-) create mode 100644 src/ArduinoJson/Data/ValueSaver.hpp delete mode 100644 src/ArduinoJson/Data/ValueSetter.hpp create mode 100644 test/JsonArray/size.cpp create mode 100644 test/JsonObject/size.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index b68c75b70..867227fd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,22 @@ ArduinoJson: change log ======================= +HEAD +---- + +* Changed the rules of string duplication (issue #658) + +> ### New rules for string duplication +> +> | type | duplication | +> |:-------------|:------------| +> | const char* | no | +> | char* | ~~no~~ yes | +> | String | yes | +> | std::string | yes | +> +> These new rules make `JsonBuffer::strdup()` useless. + v5.12.0 ------- diff --git a/src/ArduinoJson/Data/ValueSaver.hpp b/src/ArduinoJson/Data/ValueSaver.hpp new file mode 100644 index 000000000..0a9e18838 --- /dev/null +++ b/src/ArduinoJson/Data/ValueSaver.hpp @@ -0,0 +1,34 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "../JsonBuffer.hpp" +#include "../JsonVariant.hpp" +#include "../StringTraits/StringTraits.hpp" +#include "../TypeTraits/EnableIf.hpp" + +namespace ArduinoJson { +namespace Internals { + +template +struct ValueSaver { + template + static bool save(JsonBuffer*, Destination& destination, Source source) { + destination = source; + return true; + } +}; + +template +struct ValueSaver::value>::type> { + template + static bool save(JsonBuffer* buffer, Destination& destination, + Source source) { + return StringTraits::save(source, destination, buffer); + } +}; +} +} diff --git a/src/ArduinoJson/Data/ValueSetter.hpp b/src/ArduinoJson/Data/ValueSetter.hpp deleted file mode 100644 index 266df2985..000000000 --- a/src/ArduinoJson/Data/ValueSetter.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "../JsonBuffer.hpp" -#include "../JsonVariant.hpp" -#include "../StringTraits/StringTraits.hpp" -#include "../TypeTraits/EnableIf.hpp" - -namespace ArduinoJson { -namespace Internals { - -template -struct ValueSetter { - template - static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) { - destination = source; - return true; - } -}; - -template -struct ValueSetter::should_duplicate>::type> { - template - static bool set(JsonBuffer* buffer, TDestination& destination, - TSourceRef source) { - const char* copy = buffer->strdup(source); - if (!copy) return false; - destination = copy; - return true; - } -}; - -template -struct ValueSetter::should_duplicate>::type> { - template - static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) { - // unsigned char* -> char* - destination = reinterpret_cast(source); - return true; - } -}; -} -} diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 8ce21d7c6..3c3ff36ba 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -7,7 +7,7 @@ #include "Data/JsonBufferAllocated.hpp" #include "Data/List.hpp" #include "Data/ReferenceType.hpp" -#include "Data/ValueSetter.hpp" +#include "Data/ValueSaver.hpp" #include "JsonVariant.hpp" #include "Serialization/JsonPrintable.hpp" #include "StringTraits/StringTraits.hpp" @@ -56,19 +56,17 @@ class JsonArray : public Internals::JsonPrintable, // // bool add(TValue); // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - typename TypeTraits::EnableIf::value, bool>::type add( - const T &value) { + bool add(const T &value) { return add_impl(value); } // // bool add(TValue); - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template - bool add(const T *value) { - return add_impl(value); + bool add(T *value) { + return add_impl(value); } // // bool add(TValue value, uint8_t decimals); @@ -81,21 +79,19 @@ class JsonArray : public Internals::JsonPrintable, // Sets the value at specified index. // - // bool add(size_t index, TValue); + // bool add(size_t index, const TValue&); // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - typename TypeTraits::EnableIf::value, bool>::type set( - size_t index, const T &value) { + bool set(size_t index, const T &value) { return set_impl(index, value); } // // bool add(size_t index, TValue); - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template - bool set(size_t index, const T *value) { - return set_impl(index, value); + bool set(size_t index, T *value) { + return set_impl(index, value); } // // bool set(size_t index, TValue value, uint8_t decimals); @@ -208,14 +204,14 @@ class JsonArray : public Internals::JsonPrintable, bool set_impl(size_t index, TValueRef value) { iterator it = begin() += index; if (it == end()) return false; - return Internals::ValueSetter::set(_buffer, *it, value); + return Internals::ValueSaver::save(_buffer, *it, value); } template bool add_impl(TValueRef value) { iterator it = Internals::List::add(); if (it == end()) return false; - return Internals::ValueSetter::set(_buffer, *it, value); + return Internals::ValueSaver::save(_buffer, *it, value); } }; diff --git a/src/ArduinoJson/JsonArraySubscript.hpp b/src/ArduinoJson/JsonArraySubscript.hpp index 06d33094f..da9807fb1 100644 --- a/src/ArduinoJson/JsonArraySubscript.hpp +++ b/src/ArduinoJson/JsonArraySubscript.hpp @@ -25,10 +25,9 @@ class JsonArraySubscript : public JsonVariantBase { // Replaces the value // - // operator=(TValue) + // operator=(const TValue&) // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template FORCE_INLINE JsonArraySubscript& operator=(const T& src) { _array.set(_index, src); @@ -36,9 +35,9 @@ class JsonArraySubscript : public JsonVariantBase { } // // operator=(TValue) - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template - FORCE_INLINE JsonArraySubscript& operator=(const T* src) { + FORCE_INLINE JsonArraySubscript& operator=(T* src) { _array.set(_index, src); return *this; } @@ -59,19 +58,18 @@ class JsonArraySubscript : public JsonVariantBase { // Replaces the value // - // bool set(TValue) + // bool set(const TValue&) // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template FORCE_INLINE bool set(const TValue& value) { return _array.set(_index, value); } // // bool set(TValue) - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template - FORCE_INLINE bool set(const TValue* value) { + FORCE_INLINE bool set(TValue* value) { return _array.set(_index, value); } // diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 5dff10903..8bd8105bf 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -7,7 +7,7 @@ #include "Data/JsonBufferAllocated.hpp" #include "Data/List.hpp" #include "Data/ReferenceType.hpp" -#include "Data/ValueSetter.hpp" +#include "Data/ValueSaver.hpp" #include "JsonPair.hpp" #include "Serialization/JsonPrintable.hpp" #include "StringTraits/StringTraits.hpp" @@ -50,17 +50,15 @@ class JsonObject : public Internals::JsonPrintable, // JsonObjectSubscript operator[](TKey) // TKey = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - JsonObjectSubscript >::type - operator[](const TString& key) { + JsonObjectSubscript operator[](const TString& key) { return JsonObjectSubscript(*this, key); } // // JsonObjectSubscript operator[](TKey) - // TKey = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, char[], const char[N], const FlashStringHelper* template - JsonObjectSubscript operator[](const TString* key) { - return JsonObjectSubscript(*this, key); + JsonObjectSubscript operator[](TString* key) { + return JsonObjectSubscript(*this, key); } // Gets the value associated with the specified key. @@ -68,10 +66,8 @@ class JsonObject : public Internals::JsonPrintable, // const JsonObjectSubscript operator[](TKey) const; // TKey = const std::string&, const String& template - typename TypeTraits::EnableIf< - !TypeTraits::IsArray::value, - const JsonObjectSubscript >::type - operator[](const TString& key) const { + const JsonObjectSubscript operator[]( + const TString& key) const { return JsonObjectSubscript(*const_cast(this), key); } @@ -79,10 +75,8 @@ class JsonObject : public Internals::JsonPrintable, // const JsonObjectSubscript operator[](TKey) const; // TKey = const char*, const char[N], const FlashStringHelper* template - const JsonObjectSubscript operator[]( - const TString* key) const { - return JsonObjectSubscript(*const_cast(this), - key); + const JsonObjectSubscript operator[](TString* key) const { + return JsonObjectSubscript(*const_cast(this), key); } // Sets the specified key with the specified value. @@ -90,43 +84,35 @@ class JsonObject : public Internals::JsonPrintable, // bool set(TKey, TValue); // TKey = const std::string&, const String& // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - typename TypeTraits::EnableIf::value && - !TypeTraits::IsArray::value, - bool>::type - set(const TString& key, const TValue& value) { + bool set(const TString& key, const TValue& value) { return set_impl(key, value); } // // bool set(TKey, TValue); // TKey = const std::string&, const String& - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template - typename TypeTraits::EnableIf::value, - bool>::type - set(const TString& key, const TValue* value) { - return set_impl(key, value); + bool set(const TString& key, TValue* value) { + return set_impl(key, value); } // - // bool set(TKey, TValue); - // TKey = const char*, const char[N], const FlashStringHelper* + // bool set(TKey, const TValue&); + // TKey = char*, const char*, const FlashStringHelper* // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - typename TypeTraits::EnableIf::value, bool>::type - set(const TString* key, const TValue& value) { - return set_impl(key, value); + bool set(TString* key, const TValue& value) { + return set_impl(key, value); } // // bool set(TKey, TValue); - // TKey = const char*, const char[N], const FlashStringHelper* - // TValue = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template - bool set(const TString* key, const TValue* value) { - return set_impl(key, value); + bool set(TString* key, TValue* value) { + return set_impl(key, value); } // // bool set(TKey, TValue, uint8_t decimals); @@ -134,8 +120,7 @@ class JsonObject : public Internals::JsonPrintable, // TValue = float, double template DEPRECATED("Second argument is not supported anymore") - typename TypeTraits::EnableIf::value && - !TypeTraits::IsArray::value, + typename TypeTraits::EnableIf::value, bool>::type set(const TString& key, TValue value, uint8_t) { return set_impl(key, @@ -143,41 +128,35 @@ class JsonObject : public Internals::JsonPrintable, } // // bool set(TKey, TValue, uint8_t decimals); - // TKey = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, const FlashStringHelper* // TValue = float, double template DEPRECATED("Second argument is not supported anymore") typename TypeTraits::EnableIf::value, bool>::type - set(const TString* key, TValue value, uint8_t) { - return set_impl(key, - JsonVariant(value)); + set(TString* key, TValue value, uint8_t) { + return set_impl(key, JsonVariant(value)); } // Gets the value associated with the specified key. // - // TValue get(TKey); + // TValue get(TKey) const; // TKey = const std::string&, const String& // TValue = bool, char, long, int, short, float, double, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - typename TypeTraits::EnableIf< - !TypeTraits::IsArray::value, - typename Internals::JsonVariantAs::type>::type - get(const TString& key) const { + typename Internals::JsonVariantAs::type get( + const TString& key) const { return get_impl(key); } // - // TValue get(TKey); - // TKey = const char*, const char[N], const FlashStringHelper* + // TValue get(TKey) const; + // TKey = char*, const char*, const FlashStringHelper* // TValue = bool, char, long, int, short, float, double, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - typename Internals::JsonVariantAs::type get( - const TString* key) const { - return get_impl(key); + typename Internals::JsonVariantAs::type get(TString* key) const { + return get_impl(key); } // Checks the type of the value associated with the specified key. @@ -186,23 +165,19 @@ class JsonObject : public Internals::JsonPrintable, // bool is(TKey) const; // TKey = const std::string&, const String& // TValue = bool, char, long, int, short, float, double, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - typename TypeTraits::EnableIf::value, - bool>::type - is(const TString& key) const { + bool is(const TString& key) const { return is_impl(key); } // // bool is(TKey) const; - // TKey = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, const FlashStringHelper* // TValue = bool, char, long, int, short, float, double, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template - bool is(const TString* key) const { - return is_impl(key); + bool is(TString* key) const { + return is_impl(key); } // Creates and adds a JsonArray. @@ -210,16 +185,14 @@ class JsonObject : public Internals::JsonPrintable, // JsonArray& createNestedArray(TKey); // TKey = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - JsonArray&>::type - createNestedArray(const TString& key) { + JsonArray& createNestedArray(const TString& key) { return createNestedArray_impl(key); } // JsonArray& createNestedArray(TKey); - // TKey = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, char[], const char[], const FlashStringHelper* template - JsonArray& createNestedArray(const TString* key) { - return createNestedArray_impl(key); + JsonArray& createNestedArray(TString* key) { + return createNestedArray_impl(key); } // Creates and adds a JsonObject. @@ -227,17 +200,15 @@ class JsonObject : public Internals::JsonPrintable, // JsonObject& createNestedObject(TKey); // TKey = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - JsonObject&>::type - createNestedObject(const TString& key) { + JsonObject& createNestedObject(const TString& key) { return createNestedObject_impl(key); } // // JsonObject& createNestedObject(TKey); - // TKey = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, char[], const char[], const FlashStringHelper* template - JsonObject& createNestedObject(const TString* key) { - return createNestedObject_impl(key); + JsonObject& createNestedObject(TString* key) { + return createNestedObject_impl(key); } // Tells weither the specified key is present and associated with a value. @@ -245,17 +216,15 @@ class JsonObject : public Internals::JsonPrintable, // bool containsKey(TKey); // TKey = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - bool>::type - containsKey(const TString& key) const { + bool containsKey(const TString& key) const { return findKey(key) != end(); } // // bool containsKey(TKey); - // TKey = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, char[], const char[], const FlashStringHelper* template - bool containsKey(const TString* key) const { - return findKey(key) != end(); + bool containsKey(TString* key) const { + return findKey(key) != end(); } // Removes the specified key and the associated value. @@ -263,17 +232,15 @@ class JsonObject : public Internals::JsonPrintable, // void remove(TKey); // TKey = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - void>::type - remove(const TString& key) { + void remove(const TString& key) { remove(findKey(key)); } // // void remove(TKey); - // TKey = const char*, const char[N], const FlashStringHelper* + // TKey = char*, const char*, char[], const char[], const FlashStringHelper* template - void remove(const TString* key) { - remove(findKey(key)); + void remove(TString* key) { + remove(findKey(key)); } // // void remove(iterator) @@ -318,10 +285,10 @@ class JsonObject : public Internals::JsonPrintable, if (it == end()) return false; bool key_ok = - Internals::ValueSetter::set(_buffer, it->key, key); + Internals::ValueSaver::save(_buffer, it->key, key); if (!key_ok) return false; } - return Internals::ValueSetter::set(_buffer, it->value, value); + return Internals::ValueSaver::save(_buffer, it->value, value); } template diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index 1657cf77c..57544e65c 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -31,10 +31,9 @@ class JsonObjectSubscript // Set the specified value // - // operator=(TValue); + // operator=(const TValue&); // TValue = bool, char, long, int, short, float, double, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template FORCE_INLINE typename TypeTraits::EnableIf::value, @@ -45,7 +44,7 @@ class JsonObjectSubscript } // // operator=(TValue); - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template FORCE_INLINE this_type& operator=(const TValue* src) { _object.set(_key, src); @@ -68,10 +67,9 @@ class JsonObjectSubscript // Sets the specified value. // - // bool set(TValue); + // bool set(const TValue&); // TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant, - // const std::string&, const String&, - // const JsonArray&, const JsonObject& + // std::string, String, JsonArray, JsonObject template FORCE_INLINE typename TypeTraits::EnableIf::value, @@ -81,7 +79,7 @@ class JsonObjectSubscript } // // bool set(TValue); - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char, const FlashStringHelper* template FORCE_INLINE bool set(const TValue* value) { return _object.set(_key, value); diff --git a/src/ArduinoJson/Polyfills/attributes.hpp b/src/ArduinoJson/Polyfills/attributes.hpp index 2c4e7e6c4..b49091ddc 100644 --- a/src/ArduinoJson/Polyfills/attributes.hpp +++ b/src/ArduinoJson/Polyfills/attributes.hpp @@ -6,7 +6,7 @@ #ifdef _MSC_VER // Visual Studio -#define FORCE_INLINE __forceinline +#define FORCE_INLINE // __forceinline causes C4714 when returning std::string #define NO_INLINE __declspec(noinline) #define DEPRECATED(msg) __declspec(deprecated(msg)) diff --git a/src/ArduinoJson/StringTraits/CharPointer.hpp b/src/ArduinoJson/StringTraits/CharPointer.hpp index b41e47dab..9231d6c41 100644 --- a/src/ArduinoJson/StringTraits/CharPointer.hpp +++ b/src/ArduinoJson/StringTraits/CharPointer.hpp @@ -33,6 +33,7 @@ struct CharPointerTraits { return strcmp(reinterpret_cast(str), expected) == 0; } + // TODO: remove template static char* duplicate(const TChar* str, Buffer* buffer) { if (!str) return NULL; @@ -44,12 +45,46 @@ struct CharPointerTraits { static const bool has_append = false; static const bool has_equals = true; - static const bool should_duplicate = false; }; +// const char*, const unsigned char*, const signed char* template struct StringTraits::value>::type> - : CharPointerTraits {}; + TypeTraits::IsChar::value && + TypeTraits::IsConst::value>::type> + : CharPointerTraits { + // Just save the pointer + template + static typename TypeTraits::EnableIf::value, + bool>::type + save(const TChar* source, Destination& dest, Buffer*) { + dest = reinterpret_cast(source); + return true; + } +}; + +// char*, unsigned char*, signed char* +template +struct StringTraits::value && + !TypeTraits::IsConst::value>::type> + : CharPointerTraits { + // Make a copy of the string + template + static typename TypeTraits::EnableIf::value, + bool>::type + save(const TChar* source, Destination& dest, Buffer* buffer) { + if (source) { + size_t size = strlen(reinterpret_cast(source)) + 1; + void* dup = buffer->alloc(size); + if (!dup) return false; + memcpy(dup, source, size); + dest = reinterpret_cast(dup); + } else { + dest = reinterpret_cast(source); + } + return true; + } +}; } } diff --git a/src/ArduinoJson/StringTraits/FlashString.hpp b/src/ArduinoJson/StringTraits/FlashString.hpp index 2530ceeef..d706f35a4 100644 --- a/src/ArduinoJson/StringTraits/FlashString.hpp +++ b/src/ArduinoJson/StringTraits/FlashString.hpp @@ -34,6 +34,7 @@ struct StringTraits { return strcmp_P(expected, (const char*)str) == 0; } + // TODO: remove template static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) { if (!str) return NULL; @@ -43,9 +44,22 @@ struct StringTraits { return static_cast(dup); } + template + static bool save(const __FlashStringHelper* source, Destination& dest, + Buffer* buffer) { + if (source) { + size_t size = strlen_P((const char*)source) + 1; + void* dup = buffer->alloc(size); + if (dup != NULL) memcpy_P(dup, (const char*)source, size); + dest = reinterpret_cast(dup); + } else { + dest = reinterpret_cast(source); + } + return true; + } + static const bool has_append = false; static const bool has_equals = true; - static const bool should_duplicate = true; }; } } diff --git a/src/ArduinoJson/StringTraits/StdString.hpp b/src/ArduinoJson/StringTraits/StdString.hpp index d7b14b208..719f76472 100644 --- a/src/ArduinoJson/StringTraits/StdString.hpp +++ b/src/ArduinoJson/StringTraits/StdString.hpp @@ -19,6 +19,7 @@ namespace Internals { template struct StdStringTraits { + // TODO: remove template static char* duplicate(const TString& str, Buffer* buffer) { if (!str.c_str()) return NULL; // <- Arduino string can return NULL @@ -28,6 +29,21 @@ struct StdStringTraits { return static_cast(dup); } + template + static bool save(const TString& str, Destination& dest, Buffer* buffer) { + // Arduino's String::c_str() can return NULL + if (str.c_str()) { + size_t size = str.length() + 1; + void* dup = buffer->alloc(size); + if (!dup) return false; + memcpy(dup, str.c_str(), size); + dest = reinterpret_cast(dup); + } else { + dest = str.c_str(); + } + return true; + } + struct Reader : CharPointerTraits::Reader { Reader(const TString& str) : CharPointerTraits::Reader(str.c_str()) {} }; @@ -46,7 +62,6 @@ struct StdStringTraits { static const bool has_append = true; static const bool has_equals = true; - static const bool should_duplicate = true; }; #if ARDUINOJSON_ENABLE_ARDUINO_STRING diff --git a/src/ArduinoJson/StringTraits/StringTraits.hpp b/src/ArduinoJson/StringTraits/StringTraits.hpp index eec04dc53..568a42215 100644 --- a/src/ArduinoJson/StringTraits/StringTraits.hpp +++ b/src/ArduinoJson/StringTraits/StringTraits.hpp @@ -9,6 +9,7 @@ #include "../TypeTraits/EnableIf.hpp" #include "../TypeTraits/IsBaseOf.hpp" #include "../TypeTraits/IsChar.hpp" +#include "../TypeTraits/IsConst.hpp" #include "../TypeTraits/RemoveReference.hpp" namespace ArduinoJson { diff --git a/test/JsonArray/CMakeLists.txt b/test/JsonArray/CMakeLists.txt index 7d48a1ac8..ec0e5206b 100644 --- a/test/JsonArray/CMakeLists.txt +++ b/test/JsonArray/CMakeLists.txt @@ -13,6 +13,7 @@ add_executable(JsonArrayTests printTo.cpp remove.cpp set.cpp + size.cpp subscript.cpp ) diff --git a/test/JsonArray/add.cpp b/test/JsonArray/add.cpp index c344457c8..1a39833fc 100644 --- a/test/JsonArray/add.cpp +++ b/test/JsonArray/add.cpp @@ -9,11 +9,6 @@ TEST_CASE("JsonArray::add()") { DynamicJsonBuffer _jsonBuffer; JsonArray& _array = _jsonBuffer.createArray(); - SECTION("SizeIncreased_WhenValuesAreAdded") { - _array.add("hello"); - REQUIRE(1U == _array.size()); - } - SECTION("int") { _array.add(123); REQUIRE(123 == _array[0].as()); @@ -38,7 +33,7 @@ TEST_CASE("JsonArray::add()") { SECTION("const char*") { const char* str = "hello"; _array.add(str); - REQUIRE(str == _array[0].as()); + REQUIRE(str == _array[0].as()); REQUIRE(_array[0].is()); REQUIRE_FALSE(_array[0].is()); } @@ -82,4 +77,22 @@ TEST_CASE("JsonArray::add()") { REQUIRE(str == _array[0]); } + + SECTION("should not duplicate const char*") { + _array.add("world"); + const size_t expectedSize = JSON_ARRAY_SIZE(1); + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate char*") { + _array.add(const_cast("world")); + const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate std::string") { + _array.add(std::string("world")); + const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } } diff --git a/test/JsonArray/set.cpp b/test/JsonArray/set.cpp index 77e737d13..901f9054a 100644 --- a/test/JsonArray/set.cpp +++ b/test/JsonArray/set.cpp @@ -12,11 +12,6 @@ TEST_CASE("JsonArray::set()") { JsonArray& _array = _jsonBuffer.createArray(); _array.add(0); - SECTION("SizeIsUnchanged") { - _array.set(0, "hello"); - REQUIRE(1U == _array.size()); - } - SECTION("int") { _array.set(0, 123); REQUIRE(123 == _array[0].as()); @@ -82,4 +77,22 @@ TEST_CASE("JsonArray::set()") { REQUIRE_THAT(_array[0].as(), Equals("hello")); } + + SECTION("should not duplicate const char*") { + _array.set(0, "world"); + const size_t expectedSize = JSON_ARRAY_SIZE(1); + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate char*") { + _array.set(0, const_cast("world")); + const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate std::string") { + _array.set(0, std::string("world")); + const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } } diff --git a/test/JsonArray/size.cpp b/test/JsonArray/size.cpp new file mode 100644 index 000000000..c45fe30ea --- /dev/null +++ b/test/JsonArray/size.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("JsonArray::size()") { + DynamicJsonBuffer _jsonBuffer; + JsonArray& _array = _jsonBuffer.createArray(); + + SECTION("increases after add()") { + _array.add("hello"); + REQUIRE(1U == _array.size()); + + _array.add("world"); + REQUIRE(2U == _array.size()); + } + + SECTION("remains the same after set()") { + _array.add("hello"); + REQUIRE(1U == _array.size()); + + _array.set(0, "hello"); + REQUIRE(1U == _array.size()); + } + + SECTION("remains the same after assigment") { + _array.add("hello"); + REQUIRE(1U == _array.size()); + + _array[0] = "hello"; + REQUIRE(1U == _array.size()); + } +} diff --git a/test/JsonArray/subscript.cpp b/test/JsonArray/subscript.cpp index f1551c15b..69893c53c 100644 --- a/test/JsonArray/subscript.cpp +++ b/test/JsonArray/subscript.cpp @@ -11,11 +11,6 @@ TEST_CASE("JsonArray::operator[]") { JsonArray& _array = _jsonBuffer.createArray(); _array.add(0); - SECTION("SizeIsUnchanged") { - _array[0] = "hello"; - REQUIRE(1U == _array.size()); - } - SECTION("int") { _array[0] = 123; REQUIRE(123 == _array[0].as()); @@ -103,4 +98,22 @@ TEST_CASE("JsonArray::operator[]") { REQUIRE(str == _array[0]); } + + SECTION("should not duplicate const char*") { + _array[0] = "world"; + const size_t expectedSize = JSON_ARRAY_SIZE(1); + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate char*") { + _array[0] = const_cast("world"); + const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate std::string") { + _array[0] = std::string("world"); + const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } } diff --git a/test/JsonObject/CMakeLists.txt b/test/JsonObject/CMakeLists.txt index a1b079696..93e8f0ded 100644 --- a/test/JsonObject/CMakeLists.txt +++ b/test/JsonObject/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(JsonObjectTests printTo.cpp remove.cpp set.cpp + size.cpp subscript.cpp ) diff --git a/test/JsonObject/set.cpp b/test/JsonObject/set.cpp index b70de49d6..d5ae48b21 100644 --- a/test/JsonObject/set.cpp +++ b/test/JsonObject/set.cpp @@ -10,17 +10,6 @@ TEST_CASE("JsonObject::set()") { DynamicJsonBuffer jb; JsonObject& _object = jb.createObject(); - SECTION("SizeIncreased_WhenValuesAreAdded") { - _object.set("hello", 42); - REQUIRE(1 == _object.size()); - } - - SECTION("SizeUntouched_WhenSameValueIsAdded") { - _object["hello"] = 1; - _object["hello"] = 2; - REQUIRE(1 == _object.size()); - } - SECTION("int") { _object.set("hello", 123); @@ -91,17 +80,59 @@ TEST_CASE("JsonObject::set()") { REQUIRE(42 == _object["a"]); } - SECTION("ShouldReturnTrue_WhenAllocationSucceeds") { + SECTION("returns true when allocation succeeds") { StaticJsonBuffer jsonBuffer; JsonObject& obj = jsonBuffer.createObject(); REQUIRE(true == obj.set(std::string("hello"), std::string("world"))); } - SECTION("ShouldReturnFalse_WhenAllocationFails") { + SECTION("returns false when allocation fails") { StaticJsonBuffer jsonBuffer; JsonObject& obj = jsonBuffer.createObject(); REQUIRE(false == obj.set(std::string("hello"), std::string("world"))); } + + SECTION("should not duplicate const char*") { + _object.set("hello", "world"); + const size_t expectedSize = JSON_OBJECT_SIZE(1); + REQUIRE(expectedSize == jb.size()); + } + + SECTION("should duplicate char* value") { + _object.set("hello", const_cast("world")); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == jb.size()); + } + + SECTION("should duplicate char* key") { + _object.set(const_cast("hello"), "world"); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == jb.size()); + } + + SECTION("should duplicate char* key&value") { + _object.set(const_cast("hello"), const_cast("world")); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; + REQUIRE(expectedSize <= jb.size()); + } + + SECTION("should duplicate std::string value") { + _object.set("hello", std::string("world")); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == jb.size()); + } + + SECTION("should duplicate std::string key") { + _object.set(std::string("hello"), "world"); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == jb.size()); + } + + SECTION("should duplicate std::string key&value") { + _object.set(std::string("hello"), std::string("world")); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; + REQUIRE(expectedSize <= jb.size()); + } } diff --git a/test/JsonObject/size.cpp b/test/JsonObject/size.cpp new file mode 100644 index 000000000..eae888342 --- /dev/null +++ b/test/JsonObject/size.cpp @@ -0,0 +1,23 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include +#include + +TEST_CASE("JsonObject::size()") { + DynamicJsonBuffer jb; + JsonObject& _object = jb.createObject(); + + SECTION("increases when values are added") { + _object.set("hello", 42); + REQUIRE(1 == _object.size()); + } + + SECTION("doesn't increase when the smae key is added twice") { + _object["hello"] = 1; + _object["hello"] = 2; + REQUIRE(1 == _object.size()); + } +} diff --git a/test/JsonObject/subscript.cpp b/test/JsonObject/subscript.cpp index 23710570e..d08e8c77d 100644 --- a/test/JsonObject/subscript.cpp +++ b/test/JsonObject/subscript.cpp @@ -9,17 +9,6 @@ TEST_CASE("JsonObject::operator[]") { DynamicJsonBuffer _jsonBuffer; JsonObject& _object = _jsonBuffer.createObject(); - SECTION("SizeIncreased_WhenValuesAreAdded") { - _object["hello"] = 1; - REQUIRE(1 == _object.size()); - } - - SECTION("SizeUntouched_WhenSameValueIsAdded") { - _object["hello"] = 1; - _object["hello"] = 2; - REQUIRE(1 == _object.size()); - } - SECTION("int") { _object["hello"] = 123; @@ -113,9 +102,51 @@ TEST_CASE("JsonObject::operator[]") { REQUIRE(42 == _object["a"]); } - SECTION("KeyAsCharArray") { // issue #423 + SECTION("char key[]") { // issue #423 char key[] = "hello"; _object[key] = 42; REQUIRE(42 == _object[key]); } + + SECTION("should not duplicate const char*") { + _object["hello"] = "world"; + const size_t expectedSize = JSON_OBJECT_SIZE(1); + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate char* value") { + _object["hello"] = const_cast("world"); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate char* key") { + _object[const_cast("hello")] = "world"; + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate char* key&value") { + _object[const_cast("hello")] = const_cast("world"); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; + REQUIRE(expectedSize <= _jsonBuffer.size()); + } + + SECTION("should duplicate std::string value") { + _object["hello"] = std::string("world"); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate std::string key") { + _object[std::string("hello")] = "world"; + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate std::string key&value") { + _object[std::string("hello")] = std::string("world"); + const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; + REQUIRE(expectedSize <= _jsonBuffer.size()); + } } diff --git a/test/Misc/TypeTraits.cpp b/test/Misc/TypeTraits.cpp index 1619591a2..6f170eb0b 100644 --- a/test/Misc/TypeTraits.cpp +++ b/test/Misc/TypeTraits.cpp @@ -36,4 +36,9 @@ TEST_CASE("TypeTraits") { REQUIRE((IsString::value)); REQUIRE_FALSE((IsString::value)); } + + SECTION("IsConst") { + REQUIRE_FALSE((IsConst::value)); + REQUIRE((IsConst::value)); + } } From ae0b7a3ebde568c047de0a49770b5515e2ba5479 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sun, 14 Jan 2018 13:49:37 +0100 Subject: [PATCH 0005/1079] Changed the return type of `strdup()` to `const char*` (issue #658) --- CHANGELOG.md | 1 + src/ArduinoJson/JsonBuffer.hpp | 8 ++++---- test/DynamicJsonBuffer/strdup.cpp | 4 ++-- test/Misc/std_string.cpp | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 867227fd2..62dbdf4bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ HEAD ---- * Changed the rules of string duplication (issue #658) +* Changed the return type of `strdup()` to `const char*` to prevent double duplication > ### New rules for string duplication > diff --git a/src/ArduinoJson/JsonBuffer.hpp b/src/ArduinoJson/JsonBuffer.hpp index 5a42a7d00..36775cb1a 100644 --- a/src/ArduinoJson/JsonBuffer.hpp +++ b/src/ArduinoJson/JsonBuffer.hpp @@ -38,19 +38,19 @@ class JsonBuffer : Internals::NonCopyable { // Duplicates a string // - // char* strdup(TValue); + // const char* strdup(TValue); // TValue = const std::string&, const String&, template typename TypeTraits::EnableIf::value, - char *>::type + const char *>::type strdup(const TString &src) { return Internals::StringTraits::duplicate(src, this); } // - // char* strdup(TValue); + // const char* strdup(TValue); // TValue = const char*, const char[N], const FlashStringHelper* template - char *strdup(const TString *src) { + const char *strdup(const TString *src) { return Internals::StringTraits::duplicate(src, this); } diff --git a/test/DynamicJsonBuffer/strdup.cpp b/test/DynamicJsonBuffer/strdup.cpp index 9feea4219..f6fb3b1c6 100644 --- a/test/DynamicJsonBuffer/strdup.cpp +++ b/test/DynamicJsonBuffer/strdup.cpp @@ -10,14 +10,14 @@ TEST_CASE("DynamicJsonBuffer::strdup()") { SECTION("Should return a copy") { char original[] = "hello"; - char* copy = buffer.strdup(original); + const char* copy = buffer.strdup(original); strcpy(original, "world"); REQUIRE(std::string("hello") == copy); } SECTION("Given NULL, return NULL") { const char* original = NULL; - char* copy = buffer.strdup(original); + const char* copy = buffer.strdup(original); REQUIRE(0 == copy); } } diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index 00b76e839..2cfa3a3c4 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -243,7 +243,7 @@ TEST_CASE("std::string") { SECTION("JsonBuffer_strdup") { std::string original("hello"); - char *copy = jb.strdup(original); + const char *copy = jb.strdup(original); original[0] = 'w'; REQUIRE(std::string("hello") == copy); } From 0612eef69b737f34c137da0628a360c7f926fea4 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sun, 14 Jan 2018 14:02:10 +0100 Subject: [PATCH 0006/1079] Marked `strdup()` as deprecated (issue #658) --- CHANGELOG.md | 1 + src/ArduinoJson/JsonBuffer.hpp | 11 +++++---- test/DynamicJsonBuffer/CMakeLists.txt | 1 - test/DynamicJsonBuffer/strdup.cpp | 23 ------------------ test/Misc/deprecated.cpp | 34 +++++++++++++++++++++++++++ test/Misc/std_string.cpp | 7 ------ test/Misc/unsigned_char.cpp | 10 -------- test/Misc/vla.cpp | 12 ---------- 8 files changed, 41 insertions(+), 58 deletions(-) delete mode 100644 test/DynamicJsonBuffer/strdup.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 62dbdf4bf..099333801 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ HEAD * Changed the rules of string duplication (issue #658) * Changed the return type of `strdup()` to `const char*` to prevent double duplication +* Marked `strdup()` as deprecated > ### New rules for string duplication > diff --git a/src/ArduinoJson/JsonBuffer.hpp b/src/ArduinoJson/JsonBuffer.hpp index 36775cb1a..192d8b386 100644 --- a/src/ArduinoJson/JsonBuffer.hpp +++ b/src/ArduinoJson/JsonBuffer.hpp @@ -41,17 +41,18 @@ class JsonBuffer : Internals::NonCopyable { // const char* strdup(TValue); // TValue = const std::string&, const String&, template + DEPRECATED("char* are duplicated, you don't need strdup() anymore") typename TypeTraits::EnableIf::value, - const char *>::type - strdup(const TString &src) { + const char *>::type strdup(const TString &src) { return Internals::StringTraits::duplicate(src, this); } // // const char* strdup(TValue); - // TValue = const char*, const char[N], const FlashStringHelper* + // TValue = char*, const char*, const FlashStringHelper* template - const char *strdup(const TString *src) { - return Internals::StringTraits::duplicate(src, this); + DEPRECATED("char* are duplicated, you don't need strdup() anymore") + const char *strdup(TString *src) { + return Internals::StringTraits::duplicate(src, this); } // Allocates n bytes in the JsonBuffer. diff --git a/test/DynamicJsonBuffer/CMakeLists.txt b/test/DynamicJsonBuffer/CMakeLists.txt index f028ccc4f..9030f3760 100644 --- a/test/DynamicJsonBuffer/CMakeLists.txt +++ b/test/DynamicJsonBuffer/CMakeLists.txt @@ -9,7 +9,6 @@ add_executable(DynamicJsonBufferTests no_memory.cpp size.cpp startString.cpp - strdup.cpp ) target_link_libraries(DynamicJsonBufferTests catch) diff --git a/test/DynamicJsonBuffer/strdup.cpp b/test/DynamicJsonBuffer/strdup.cpp deleted file mode 100644 index f6fb3b1c6..000000000 --- a/test/DynamicJsonBuffer/strdup.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("DynamicJsonBuffer::strdup()") { - DynamicJsonBuffer buffer; - - SECTION("Should return a copy") { - char original[] = "hello"; - const char* copy = buffer.strdup(original); - strcpy(original, "world"); - REQUIRE(std::string("hello") == copy); - } - - SECTION("Given NULL, return NULL") { - const char* original = NULL; - const char* copy = buffer.strdup(original); - REQUIRE(0 == copy); - } -} diff --git a/test/Misc/deprecated.cpp b/test/Misc/deprecated.cpp index bc7f97ba8..8fa4fe28d 100644 --- a/test/Misc/deprecated.cpp +++ b/test/Misc/deprecated.cpp @@ -104,3 +104,37 @@ TEST_CASE("Deprecated functions") { REQUIRE(123.45 == obj["hello"].as()); } } + +TEST_CASE("DynamicJsonBuffer::strdup()") { + DynamicJsonBuffer buffer; + + SECTION("char*") { + char original[] = "hello"; + const char* copy = buffer.strdup(original); + strcpy(original, "world"); + REQUIRE(std::string("hello") == copy); + } + + SECTION("unsigned char*") { + unsigned char value[] = "world"; + + DynamicJsonBuffer jsonBuffer; + const char* dup = jsonBuffer.strdup(value); + + REQUIRE(static_cast(value) != static_cast(dup)); + REQUIRE(std::string("world") == dup); + } + + SECTION("std::string") { + std::string original("hello"); + const char* copy = buffer.strdup(original); + original[0] = 'w'; + REQUIRE(std::string("hello") == copy); + } + + SECTION("NULL") { + const char* original = NULL; + const char* copy = buffer.strdup(original); + REQUIRE(0 == copy); + } +} diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index 2cfa3a3c4..aeb188ddf 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -240,11 +240,4 @@ TEST_CASE("std::string") { REQUIRE(sizeBefore == sizeAfter); } - - SECTION("JsonBuffer_strdup") { - std::string original("hello"); - const char *copy = jb.strdup(original); - original[0] = 'w'; - REQUIRE(std::string("hello") == copy); - } } diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 5d7a47e02..ce1c474af 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -259,14 +259,4 @@ TEST_CASE("unsigned char string") { REQUIRE(std::string("world") == arr[0]); } - - SECTION("JsonBuffer::strdup()") { - unsigned char value[] = "world"; - - DynamicJsonBuffer jsonBuffer; - const char* dup = jsonBuffer.strdup(value); - - REQUIRE(static_cast(value) != static_cast(dup)); - REQUIRE(std::string("world") == dup); - } } diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 1e5ee1e24..e9d1cb676 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -327,17 +327,5 @@ TEST_CASE("Variable Length Array") { REQUIRE(std::string("world") == arr[0]); } - - SECTION("JsonBuffer_strdup") { - int i = 16; - char vla[i]; - strcpy(vla, "world"); - - DynamicJsonBuffer jsonBuffer; - const char* dup = jsonBuffer.strdup(vla); - - REQUIRE(static_cast(vla) != static_cast(dup)); - REQUIRE(std::string("world") == dup); - } } #endif From fbfdca1de9ada1623d45d48609cf19da1e5cbb31 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 15 Jan 2018 10:22:04 +0100 Subject: [PATCH 0007/1079] Added campaign information in links --- README.md | 18 +++++++++--------- SUPPORT.md | 4 ++-- library.json | 1 + library.properties | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 141425469..f9e08ff89 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things). * [100% code coverage](https://coveralls.io/github/bblanchon/ArduinoJson) * [Header-only library](https://en.wikipedia.org/wiki/Header-only) * [MIT License](https://en.wikipedia.org/wiki/MIT_License) -* [Comprehensive documentation](https://arduinojson.org?utm_source=readme) +* [Comprehensive documentation](https://arduinojson.org?utm_source=github&utm_medium=readme) ## Compatibility @@ -69,7 +69,7 @@ double latitude = root["data"][0]; double longitude = root["data"][1]; ``` -See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_source=readme) +See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_source=github&utm_medium=readme) ### Serialization @@ -91,20 +91,20 @@ root.printTo(Serial); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} ``` -See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=readme) +See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=github&utm_medium=readme) ## Documentation -The documentation is available on [arduinojson.org](https://arduinojson.org/?utm_source=readme), here are some shortcuts: +The documentation is available on [arduinojson.org](https://arduinojson.org/?utm_source=github&utm_medium=readme), here are some shortcuts: -* The [Examples](https://arduinojson.org/example/?utm_source=readme) show how to use the library in various situations. -* The [API Reference](https://arduinojson.org/api/?utm_source=readme) contains the description of each class and function. -* The [FAQ](https://arduinojson.org/faq/?utm_source=readme) has the answer to virtually every question. -* The [ArduinoJson Assistant](https://arduinojson.org/assistant/?utm_source=readme) writes programs for you! +* The [Examples](https://arduinojson.org/example/?utm_source=github&utm_medium=readme) show how to use the library in various situations. +* The [API Reference](https://arduinojson.org/api/?utm_source=github&utm_medium=readme) contains the description of each class and function. +* The [FAQ](https://arduinojson.org/faq/?utm_source=github&utm_medium=readme) has the answer to virtually every question. +* The [ArduinoJson Assistant](https://arduinojson.org/assistant/?utm_source=github&utm_medium=readme) writes programs for you! --- Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)! What? You don't like it but you *love* it? -We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=readme), so you can help and learn at the same time! \ No newline at end of file +We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time! \ No newline at end of file diff --git a/SUPPORT.md b/SUPPORT.md index 900e4d2a0..c47e1b1ba 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -6,8 +6,8 @@ We'll be very happy to help you, but first please read the following. ## Before asking for help -1. Read the [FAQ](https://arduinojson.org/faq/) -2. Search in the [API Reference](https://arduinojson.org/api/) +1. Read the [FAQ](https://arduinojson.org/faq/?utm_source=github&utm_medium=support) +2. Search in the [API Reference](https://arduinojson.org/api/?utm_source=github&utm_medium=support) If you did not find the answer, please create a [new issue on GitHub](https://github.com/bblanchon/ArduinoJson/issues/new). diff --git a/library.json b/library.json index 274804e51..d4233e917 100644 --- a/library.json +++ b/library.json @@ -2,6 +2,7 @@ "name": "ArduinoJson", "keywords": "json, rest, http, web", "description": "An elegant and efficient JSON library for embedded systems", + "homepage": "https://arduinojson.org/?utm_source=meta&utm_medium=library.json", "repository": { "type": "git", "url": "https://github.com/bblanchon/ArduinoJson.git" diff --git a/library.properties b/library.properties index cf03e3de2..4293010e8 100644 --- a/library.properties +++ b/library.properties @@ -5,5 +5,5 @@ maintainer=Benoit Blanchon sentence=An efficient and elegant JSON library for Arduino. paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ fixed allocation, ✔ zero-copy, ✔ streams, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation. category=Data Processing -url=https://arduinojson.org/ +url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties architectures=* From 7e4fcb0868c9da02f49283ea06dadeeee498765d Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 15 Jan 2018 10:24:51 +0100 Subject: [PATCH 0008/1079] Add `repository` and `license` in `library.properties` (closes #662) --- library.properties | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library.properties b/library.properties index 4293010e8..703b1bdd4 100644 --- a/library.properties +++ b/library.properties @@ -7,3 +7,5 @@ paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ fixed category=Data Processing url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties architectures=* +repository=https://github.com/bblanchon/ArduinoJson.git +license=MIT From bae179ed67cf466766c9af160102bfccdd9a003f Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 18 Jan 2018 09:43:37 +0100 Subject: [PATCH 0009/1079] `RawJson()` accepts any kind of string and obeys to duplication rules --- CHANGELOG.md | 14 ++--- examples/ProgmemExample/ProgmemExample.ino | 3 ++ examples/StringExample/StringExample.ino | 3 ++ src/ArduinoJson/Data/ValueSaver.hpp | 26 ++++++++-- src/ArduinoJson/JsonObjectSubscript.hpp | 2 +- src/ArduinoJson/JsonVariant.hpp | 2 +- src/ArduinoJson/JsonVariantComparisons.hpp | 9 ++-- src/ArduinoJson/RawJson.hpp | 34 +++++++++++-- .../Serialization/JsonPrintable.hpp | 6 +-- .../StringTraits/ArduinoStream.hpp | 3 ++ src/ArduinoJson/StringTraits/CharPointer.hpp | 51 +++++-------------- src/ArduinoJson/StringTraits/FlashString.hpp | 26 ++++------ src/ArduinoJson/StringTraits/StdStream.hpp | 3 ++ src/ArduinoJson/StringTraits/StdString.hpp | 22 +++----- src/ArduinoJson/StringTraits/StringTraits.hpp | 20 ++------ test/JsonArray/add.cpp | 14 ++++- test/JsonArray/printTo.cpp | 18 +++++-- test/Misc/CMakeLists.txt | 1 + test/Misc/StringTraits.cpp | 22 ++++++++ test/Misc/TypeTraits.cpp | 7 --- 20 files changed, 163 insertions(+), 123 deletions(-) create mode 100644 test/Misc/StringTraits.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 099333801..211424248 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,17 +5,19 @@ HEAD ---- * Changed the rules of string duplication (issue #658) +* `RawJson()` accepts any kind of string and obeys to the same rules for duplication * Changed the return type of `strdup()` to `const char*` to prevent double duplication * Marked `strdup()` as deprecated > ### New rules for string duplication > -> | type | duplication | -> |:-------------|:------------| -> | const char* | no | -> | char* | ~~no~~ yes | -> | String | yes | -> | std::string | yes | +> | type | duplication | +> |:---------------------------|:------------| +> | const char* | no | +> | char* | ~~no~~ yes | +> | String | yes | +> | std::string | yes | +> | const __FlashStringHelper* | yes | > > These new rules make `JsonBuffer::strdup()` useless. diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index 287c5067e..15be8ed1c 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -37,6 +37,9 @@ void setup() { // JsonBuffer. root["sensor"] = F("gps"); + // It works with RawJson too: + root["sensor"] = RawJson(F("\"gps\"")); + // You can compare the content of a JsonVariant to a Flash String if (root["sensor"] == F("gps")) { // ... diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index d070d551a..d5994ffb2 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -40,6 +40,9 @@ void setup() { // WARNING: the content of the String will be duplicated in the JsonBuffer. root["sensor"] = sensor; + // It works with RawJson too: + root["sensor"] = RawJson(sensor); + // You can also concatenate strings // WARNING: the content of the String will be duplicated in the JsonBuffer. root[String("sen") + "sor"] = String("gp") + "s"; diff --git a/src/ArduinoJson/Data/ValueSaver.hpp b/src/ArduinoJson/Data/ValueSaver.hpp index 0a9e18838..0e996e6a1 100644 --- a/src/ArduinoJson/Data/ValueSaver.hpp +++ b/src/ArduinoJson/Data/ValueSaver.hpp @@ -23,11 +23,29 @@ struct ValueSaver { template struct ValueSaver::value>::type> { + StringTraits::should_duplicate>::type> { template - static bool save(JsonBuffer* buffer, Destination& destination, - Source source) { - return StringTraits::save(source, destination, buffer); + static bool save(JsonBuffer* buffer, Destination& dest, Source source) { + if (!StringTraits::is_null(source)) { + typename StringTraits::duplicate_t dup = + StringTraits::duplicate(source, buffer); + if (!dup) return false; + dest = dup; + } else { + dest = reinterpret_cast(0); + } + return true; + } +}; + +// const char*, const signed char*, const unsigned char* +template +struct ValueSaver::should_duplicate>::type> { + template + static bool save(JsonBuffer*, Destination& dest, Char* source) { + dest = reinterpret_cast(source); + return true; } }; } diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index 57544e65c..ede6bdcf1 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -46,7 +46,7 @@ class JsonObjectSubscript // operator=(TValue); // TValue = char*, const char*, const FlashStringHelper* template - FORCE_INLINE this_type& operator=(const TValue* src) { + FORCE_INLINE this_type& operator=(TValue* src) { _object.set(_key, src); return *this; } diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index f2d7ff95b..415af172e 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -117,7 +117,7 @@ class JsonVariant : public JsonVariantBase { } // Create a JsonVariant containing an unparsed string - JsonVariant(RawJson value) { + JsonVariant(Internals::RawJsonString value) { _type = Internals::JSON_UNPARSED; _content.asString = value; } diff --git a/src/ArduinoJson/JsonVariantComparisons.hpp b/src/ArduinoJson/JsonVariantComparisons.hpp index 156d0db32..74eeae438 100644 --- a/src/ArduinoJson/JsonVariantComparisons.hpp +++ b/src/ArduinoJson/JsonVariantComparisons.hpp @@ -104,7 +104,7 @@ class JsonVariantComparisons { } template - typename TypeTraits::EnableIf::value, + typename TypeTraits::EnableIf::has_equals, bool>::type equals(const TString &comparand) const { const char *value = as(); @@ -112,9 +112,10 @@ class JsonVariantComparisons { } template - typename TypeTraits::EnableIf::value && - !TypeTraits::IsString::value, - bool>::type + typename TypeTraits::EnableIf< + !TypeTraits::IsVariant::value && + !Internals::StringTraits::has_equals, + bool>::type equals(const TComparand &comparand) const { return as() == comparand; } diff --git a/src/ArduinoJson/RawJson.hpp b/src/ArduinoJson/RawJson.hpp index 5477278fd..4beb980ee 100644 --- a/src/ArduinoJson/RawJson.hpp +++ b/src/ArduinoJson/RawJson.hpp @@ -6,15 +6,41 @@ namespace ArduinoJson { +namespace Internals { // A special type of data that can be used to insert pregenerated JSON portions. -class RawJson { +template +class RawJsonString { public: - explicit RawJson(const char* str) : _str(str) {} - operator const char*() const { + explicit RawJsonString(T str) : _str(str) {} + operator T() const { return _str; } private: - const char* _str; + T _str; }; + +template +struct StringTraits, void> { + static bool is_null(RawJsonString source) { + return StringTraits::is_null(static_cast(source)); + } + + typedef RawJsonString duplicate_t; + + template + static duplicate_t duplicate(RawJsonString source, Buffer* buffer) { + return duplicate_t(StringTraits::duplicate(source, buffer)); + } + + static const bool has_append = false; + static const bool has_equals = false; + static const bool should_duplicate = StringTraits::should_duplicate; +}; +} + +template +inline Internals::RawJsonString RawJson(T str) { + return Internals::RawJsonString(str); +} } diff --git a/src/ArduinoJson/Serialization/JsonPrintable.hpp b/src/ArduinoJson/Serialization/JsonPrintable.hpp index 9ea4bfb4a..650cff543 100644 --- a/src/ArduinoJson/Serialization/JsonPrintable.hpp +++ b/src/ArduinoJson/Serialization/JsonPrintable.hpp @@ -29,8 +29,7 @@ template class JsonPrintable { public: template - typename TypeTraits::EnableIf::value, - size_t>::type + typename TypeTraits::EnableIf::has_append, size_t>::type printTo(Print &print) const { JsonWriter writer(print); JsonSerializer >::serialize(downcast(), writer); @@ -79,8 +78,7 @@ class JsonPrintable { } template - typename TypeTraits::EnableIf::value, - size_t>::type + typename TypeTraits::EnableIf::has_append, size_t>::type prettyPrintTo(Print &print) const { IndentedPrint indentedPrint(print); return prettyPrintTo(indentedPrint); diff --git a/src/ArduinoJson/StringTraits/ArduinoStream.hpp b/src/ArduinoJson/StringTraits/ArduinoStream.hpp index 0fe08100b..80d383db6 100644 --- a/src/ArduinoJson/StringTraits/ArduinoStream.hpp +++ b/src/ArduinoJson/StringTraits/ArduinoStream.hpp @@ -43,6 +43,9 @@ struct ArduinoStreamTraits { return c; } }; + + static const bool has_append = false; + static const bool has_equals = false; }; template diff --git a/src/ArduinoJson/StringTraits/CharPointer.hpp b/src/ArduinoJson/StringTraits/CharPointer.hpp index 9231d6c41..20864f707 100644 --- a/src/ArduinoJson/StringTraits/CharPointer.hpp +++ b/src/ArduinoJson/StringTraits/CharPointer.hpp @@ -33,58 +33,31 @@ struct CharPointerTraits { return strcmp(reinterpret_cast(str), expected) == 0; } - // TODO: remove + static bool is_null(const TChar* str) { + return !str; + } + + typedef const char* duplicate_t; + template - static char* duplicate(const TChar* str, Buffer* buffer) { + static duplicate_t duplicate(const TChar* str, Buffer* buffer) { if (!str) return NULL; size_t size = strlen(reinterpret_cast(str)) + 1; void* dup = buffer->alloc(size); if (dup != NULL) memcpy(dup, str, size); - return static_cast(dup); + return static_cast(dup); } static const bool has_append = false; static const bool has_equals = true; -}; - -// const char*, const unsigned char*, const signed char* -template -struct StringTraits::value && - TypeTraits::IsConst::value>::type> - : CharPointerTraits { - // Just save the pointer - template - static typename TypeTraits::EnableIf::value, - bool>::type - save(const TChar* source, Destination& dest, Buffer*) { - dest = reinterpret_cast(source); - return true; - } + static const bool should_duplicate = !TypeTraits::IsConst::value; }; // char*, unsigned char*, signed char* +// const char*, const unsigned char*, const signed char* template struct StringTraits::value && - !TypeTraits::IsConst::value>::type> - : CharPointerTraits { - // Make a copy of the string - template - static typename TypeTraits::EnableIf::value, - bool>::type - save(const TChar* source, Destination& dest, Buffer* buffer) { - if (source) { - size_t size = strlen(reinterpret_cast(source)) + 1; - void* dup = buffer->alloc(size); - if (!dup) return false; - memcpy(dup, source, size); - dest = reinterpret_cast(dup); - } else { - dest = reinterpret_cast(source); - } - return true; - } -}; + TypeTraits::IsChar::value>::type> + : CharPointerTraits {}; } } diff --git a/src/ArduinoJson/StringTraits/FlashString.hpp b/src/ArduinoJson/StringTraits/FlashString.hpp index d706f35a4..95f555d20 100644 --- a/src/ArduinoJson/StringTraits/FlashString.hpp +++ b/src/ArduinoJson/StringTraits/FlashString.hpp @@ -34,32 +34,24 @@ struct StringTraits { return strcmp_P(expected, (const char*)str) == 0; } - // TODO: remove + static bool is_null(const __FlashStringHelper* str) { + return !str; + } + + typedef const char* duplicate_t; + template - static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) { + static duplicate_t duplicate(const __FlashStringHelper* str, Buffer* buffer) { if (!str) return NULL; size_t size = strlen_P((const char*)str) + 1; void* dup = buffer->alloc(size); if (dup != NULL) memcpy_P(dup, (const char*)str, size); - return static_cast(dup); - } - - template - static bool save(const __FlashStringHelper* source, Destination& dest, - Buffer* buffer) { - if (source) { - size_t size = strlen_P((const char*)source) + 1; - void* dup = buffer->alloc(size); - if (dup != NULL) memcpy_P(dup, (const char*)source, size); - dest = reinterpret_cast(dup); - } else { - dest = reinterpret_cast(source); - } - return true; + return static_cast(dup); } static const bool has_append = false; static const bool has_equals = true; + static const bool should_duplicate = true; }; } } diff --git a/src/ArduinoJson/StringTraits/StdStream.hpp b/src/ArduinoJson/StringTraits/StdStream.hpp index ef2033916..3a410aeb8 100644 --- a/src/ArduinoJson/StringTraits/StdStream.hpp +++ b/src/ArduinoJson/StringTraits/StdStream.hpp @@ -42,6 +42,9 @@ struct StdStreamTraits { return _stream.eof() ? '\0' : static_cast(_stream.get()); } }; + + static const bool has_append = false; + static const bool has_equals = false; }; template diff --git a/src/ArduinoJson/StringTraits/StdString.hpp b/src/ArduinoJson/StringTraits/StdString.hpp index 719f76472..39124dac8 100644 --- a/src/ArduinoJson/StringTraits/StdString.hpp +++ b/src/ArduinoJson/StringTraits/StdString.hpp @@ -19,29 +19,20 @@ namespace Internals { template struct StdStringTraits { - // TODO: remove + typedef const char* duplicate_t; + template - static char* duplicate(const TString& str, Buffer* buffer) { + static duplicate_t duplicate(const TString& str, Buffer* buffer) { if (!str.c_str()) return NULL; // <- Arduino string can return NULL size_t size = str.length() + 1; void* dup = buffer->alloc(size); if (dup != NULL) memcpy(dup, str.c_str(), size); - return static_cast(dup); + return static_cast(dup); } - template - static bool save(const TString& str, Destination& dest, Buffer* buffer) { + static bool is_null(const TString& str) { // Arduino's String::c_str() can return NULL - if (str.c_str()) { - size_t size = str.length() + 1; - void* dup = buffer->alloc(size); - if (!dup) return false; - memcpy(dup, str.c_str(), size); - dest = reinterpret_cast(dup); - } else { - dest = str.c_str(); - } - return true; + return !str.c_str(); } struct Reader : CharPointerTraits::Reader { @@ -62,6 +53,7 @@ struct StdStringTraits { static const bool has_append = true; static const bool has_equals = true; + static const bool should_duplicate = true; }; #if ARDUINOJSON_ENABLE_ARDUINO_STRING diff --git a/src/ArduinoJson/StringTraits/StringTraits.hpp b/src/ArduinoJson/StringTraits/StringTraits.hpp index 568a42215..dd5694b2e 100644 --- a/src/ArduinoJson/StringTraits/StringTraits.hpp +++ b/src/ArduinoJson/StringTraits/StringTraits.hpp @@ -16,7 +16,10 @@ namespace ArduinoJson { namespace Internals { template -struct StringTraits {}; +struct StringTraits { + static const bool has_append = false; + static const bool has_equals = false; +}; template struct StringTraits : StringTraits {}; @@ -31,18 +34,3 @@ struct StringTraits : StringTraits {}; #include "FlashString.hpp" #include "StdStream.hpp" #include "StdString.hpp" - -namespace ArduinoJson { -namespace TypeTraits { -template -struct IsString { - static const bool value = false; -}; - -template -struct IsString::has_equals>::type> { - static const bool value = Internals::StringTraits::has_equals; -}; -} -} diff --git a/test/JsonArray/add.cpp b/test/JsonArray/add.cpp index 1a39833fc..2e10754ee 100644 --- a/test/JsonArray/add.cpp +++ b/test/JsonArray/add.cpp @@ -84,7 +84,7 @@ TEST_CASE("JsonArray::add()") { REQUIRE(expectedSize == _jsonBuffer.size()); } - SECTION("should duplicate char*") { + SECTION("should duplicate char*") { _array.add(const_cast("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; REQUIRE(expectedSize == _jsonBuffer.size()); @@ -95,4 +95,16 @@ TEST_CASE("JsonArray::add()") { const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; REQUIRE(expectedSize == _jsonBuffer.size()); } + + SECTION("should not duplicate RawJson(const char*)") { + _array.add(RawJson("{}")); + const size_t expectedSize = JSON_ARRAY_SIZE(1); + REQUIRE(expectedSize == _jsonBuffer.size()); + } + + SECTION("should duplicate RawJson(char*)") { + _array.add(RawJson(const_cast("{}"))); + const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3; + REQUIRE(expectedSize == _jsonBuffer.size()); + } } diff --git a/test/JsonArray/printTo.cpp b/test/JsonArray/printTo.cpp index 73f14ac62..6b7f003c6 100644 --- a/test/JsonArray/printTo.cpp +++ b/test/JsonArray/printTo.cpp @@ -8,10 +8,10 @@ static void check(JsonArray &array, std::string expected) { std::string actual; size_t actualLen = array.printTo(actual); - size_t measuredLen = array.measureLength(); - CHECK(actualLen == expected.size()); - CHECK(measuredLen == expected.size()); REQUIRE(expected == actual); + REQUIRE(actualLen == expected.size()); + size_t measuredLen = array.measureLength(); + REQUIRE(measuredLen == expected.size()); } TEST_CASE("JsonArray::printTo()") { @@ -67,12 +67,22 @@ TEST_CASE("JsonArray::printTo()") { check(array, "[1,2]"); } - SECTION("RawJson") { + SECTION("RawJson(const char*)") { array.add(RawJson("{\"key\":\"value\"}")); check(array, "[{\"key\":\"value\"}]"); } + SECTION("RawJson(char*)") { + DynamicJsonBuffer jb2; + JsonArray &arr = jb2.createArray(); + + char tmp[] = "{\"key\":\"value\"}"; + arr.add(RawJson(tmp)); + + check(arr, "[{\"key\":\"value\"}]"); + } + SECTION("OneIntegerOverCapacity") { array.add(1); array.add(2); diff --git a/test/Misc/CMakeLists.txt b/test/Misc/CMakeLists.txt index 5b5726010..0b54bd7bd 100644 --- a/test/Misc/CMakeLists.txt +++ b/test/Misc/CMakeLists.txt @@ -8,6 +8,7 @@ add_executable(MiscTests std_stream.cpp std_string.cpp StringBuilder.cpp + StringTraits.cpp TypeTraits.cpp unsigned_char.cpp vla.cpp diff --git a/test/Misc/StringTraits.cpp b/test/Misc/StringTraits.cpp new file mode 100644 index 000000000..db18648ca --- /dev/null +++ b/test/Misc/StringTraits.cpp @@ -0,0 +1,22 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +using namespace ArduinoJson::Internals; + +template +bool should_duplicate() { + return StringTraits::should_duplicate; +} + +TEST_CASE("StringTraits") { + SECTION("should_duplicate") { + REQUIRE(false == should_duplicate()); + REQUIRE(true == should_duplicate()); + REQUIRE(true == should_duplicate >()); + REQUIRE(false == should_duplicate >()); + } +} diff --git a/test/Misc/TypeTraits.cpp b/test/Misc/TypeTraits.cpp index 6f170eb0b..2f8e7e8cc 100644 --- a/test/Misc/TypeTraits.cpp +++ b/test/Misc/TypeTraits.cpp @@ -4,7 +4,6 @@ #include #include -#include using namespace ArduinoJson::TypeTraits; @@ -31,12 +30,6 @@ TEST_CASE("TypeTraits") { REQUIRE(static_cast(IsVariant::value)); } - SECTION("IsString") { - REQUIRE((IsString::value)); - REQUIRE((IsString::value)); - REQUIRE_FALSE((IsString::value)); - } - SECTION("IsConst") { REQUIRE_FALSE((IsConst::value)); REQUIRE((IsConst::value)); From e390587e91c67cf929b1f6f56488be9016fe6f93 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 19 Jan 2018 08:32:15 +0100 Subject: [PATCH 0010/1079] Kept only two namespaces ArduinoJson and ArduinoJson::Internals --- src/ArduinoJson/Data/ValueSaver.hpp | 8 +- .../Deserialization/JsonParser.hpp | 9 +- .../Deserialization/JsonParserImpl.hpp | 3 +- src/ArduinoJson/DynamicJsonBuffer.hpp | 5 +- src/ArduinoJson/JsonArray.hpp | 9 +- src/ArduinoJson/JsonArraySubscript.hpp | 36 ++++--- src/ArduinoJson/JsonBuffer.hpp | 4 +- src/ArduinoJson/JsonBufferBase.hpp | 14 +-- src/ArduinoJson/JsonObject.hpp | 33 +++--- src/ArduinoJson/JsonObjectSubscript.hpp | 18 ++-- src/ArduinoJson/JsonVariant.hpp | 102 +++++++++--------- src/ArduinoJson/JsonVariantBase.hpp | 6 +- src/ArduinoJson/JsonVariantCasts.hpp | 2 + src/ArduinoJson/JsonVariantComparisons.hpp | 30 +++--- src/ArduinoJson/JsonVariantImpl.hpp | 8 +- src/ArduinoJson/JsonVariantOr.hpp | 2 + src/ArduinoJson/JsonVariantSubscripts.hpp | 28 ++--- src/ArduinoJson/Polyfills/ctype.hpp | 2 +- src/ArduinoJson/Polyfills/isFloat.hpp | 2 +- src/ArduinoJson/Polyfills/isInteger.hpp | 2 +- src/ArduinoJson/Polyfills/math.hpp | 2 +- src/ArduinoJson/Polyfills/parseFloat.hpp | 4 +- src/ArduinoJson/Polyfills/parseInteger.hpp | 2 +- src/ArduinoJson/Serialization/FloatParts.hpp | 2 +- .../Serialization/JsonPrintable.hpp | 12 +-- .../Serialization/JsonSerializer.hpp | 7 +- src/ArduinoJson/Serialization/JsonWriter.hpp | 4 +- src/ArduinoJson/StaticJsonBuffer.hpp | 7 +- .../StringTraits/ArduinoStream.hpp | 10 +- src/ArduinoJson/StringTraits/CharPointer.hpp | 5 +- src/ArduinoJson/StringTraits/StdStream.hpp | 10 +- src/ArduinoJson/TypeTraits/EnableIf.hpp | 2 +- src/ArduinoJson/TypeTraits/FloatTraits.hpp | 2 +- src/ArduinoJson/TypeTraits/IsArray.hpp | 2 +- src/ArduinoJson/TypeTraits/IsBaseOf.hpp | 2 +- src/ArduinoJson/TypeTraits/IsChar.hpp | 2 +- src/ArduinoJson/TypeTraits/IsConst.hpp | 2 +- .../TypeTraits/IsFloatingPoint.hpp | 2 +- src/ArduinoJson/TypeTraits/IsIntegral.hpp | 8 +- src/ArduinoJson/TypeTraits/IsSame.hpp | 2 +- .../TypeTraits/IsSignedIntegral.hpp | 16 ++- .../TypeTraits/IsUnsignedIntegral.hpp | 16 ++- src/ArduinoJson/TypeTraits/IsVariant.hpp | 2 +- src/ArduinoJson/TypeTraits/RemoveConst.hpp | 2 +- .../TypeTraits/RemoveReference.hpp | 2 +- test/DynamicJsonBuffer/alloc.cpp | 2 + test/DynamicJsonBuffer/no_memory.cpp | 2 + test/Misc/TypeTraits.cpp | 2 +- test/Polyfills/isFloat.cpp | 2 +- test/Polyfills/isInteger.cpp | 2 +- test/Polyfills/parseFloat.cpp | 2 +- test/Polyfills/parseInteger.cpp | 2 +- test/StaticJsonBuffer/startString.cpp | 2 + 53 files changed, 241 insertions(+), 225 deletions(-) diff --git a/src/ArduinoJson/Data/ValueSaver.hpp b/src/ArduinoJson/Data/ValueSaver.hpp index 0e996e6a1..9750f1ac5 100644 --- a/src/ArduinoJson/Data/ValueSaver.hpp +++ b/src/ArduinoJson/Data/ValueSaver.hpp @@ -22,8 +22,8 @@ struct ValueSaver { }; template -struct ValueSaver::should_duplicate>::type> { +struct ValueSaver< + Source, typename EnableIf::should_duplicate>::type> { template static bool save(JsonBuffer* buffer, Destination& dest, Source source) { if (!StringTraits::is_null(source)) { @@ -40,8 +40,8 @@ struct ValueSaver -struct ValueSaver::should_duplicate>::type> { +struct ValueSaver< + Char*, typename EnableIf::should_duplicate>::type> { template static bool save(JsonBuffer*, Destination& dest, Char* source) { dest = reinterpret_cast(source); diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index bd26a15c8..2f6e6de16 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -71,7 +71,7 @@ class JsonParser { template struct JsonParserBuilder { - typedef typename Internals::StringTraits::Reader InputReader; + typedef typename StringTraits::Reader InputReader; typedef JsonParser TParser; static TParser makeParser(TJsonBuffer *buffer, TString &json, @@ -81,10 +81,9 @@ struct JsonParserBuilder { }; template -struct JsonParserBuilder< - TJsonBuffer, TChar *, - typename TypeTraits::EnableIf::value>::type> { - typedef typename Internals::StringTraits::Reader TReader; +struct JsonParserBuilder::value>::type> { + typedef typename StringTraits::Reader TReader; typedef StringWriter TWriter; typedef JsonParser TParser; diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 3921225bb..76253b252 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -141,8 +141,7 @@ inline bool ArduinoJson::Internals::JsonParser::parseObjectTo( template inline const char * ArduinoJson::Internals::JsonParser::parseString() { - typename TypeTraits::RemoveReference::type::String str = - _writer.startString(); + typename RemoveReference::type::String str = _writer.startString(); skipSpacesAndComments(_reader); char c = _reader.current(); diff --git a/src/ArduinoJson/DynamicJsonBuffer.hpp b/src/ArduinoJson/DynamicJsonBuffer.hpp index fc8270f00..bdbd5dd90 100644 --- a/src/ArduinoJson/DynamicJsonBuffer.hpp +++ b/src/ArduinoJson/DynamicJsonBuffer.hpp @@ -19,6 +19,7 @@ #endif namespace ArduinoJson { +namespace Internals { class DefaultAllocator { public: void* allocate(size_t size) { @@ -151,6 +152,7 @@ class DynamicJsonBufferBase Block* _head; size_t _nextBlockCapacity; }; +} #if defined(__clang__) #pragma clang diagnostic pop @@ -163,5 +165,6 @@ class DynamicJsonBufferBase // Implements a JsonBuffer with dynamic memory allocation. // You are strongly encouraged to consider using StaticJsonBuffer which is much // more suitable for embedded systems. -typedef DynamicJsonBufferBase DynamicJsonBuffer; +typedef Internals::DynamicJsonBufferBase + DynamicJsonBuffer; } diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 3c3ff36ba..2acd2a1a5 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -26,7 +26,9 @@ namespace ArduinoJson { // Forward declarations class JsonObject; class JsonBuffer; +namespace Internals { class JsonArraySubscript; +} // An array of JsonVariant. // @@ -47,10 +49,10 @@ class JsonArray : public Internals::JsonPrintable, : Internals::List(buffer) {} // Gets the value at the specified index - const JsonArraySubscript operator[](size_t index) const; + const Internals::JsonArraySubscript operator[](size_t index) const; // Gets or sets the value at specified index - JsonArraySubscript operator[](size_t index); + Internals::JsonArraySubscript operator[](size_t index); // Adds the specified value at the end of the array. // @@ -97,8 +99,7 @@ class JsonArray : public Internals::JsonPrintable, // bool set(size_t index, TValue value, uint8_t decimals); // TValue = float, double template - typename TypeTraits::EnableIf::value, - bool>::type + typename Internals::EnableIf::value, bool>::type set(size_t index, T value, uint8_t decimals) { return set_impl(index, JsonVariant(value, decimals)); } diff --git a/src/ArduinoJson/JsonArraySubscript.hpp b/src/ArduinoJson/JsonArraySubscript.hpp index da9807fb1..afb4dc1ec 100644 --- a/src/ArduinoJson/JsonArraySubscript.hpp +++ b/src/ArduinoJson/JsonArraySubscript.hpp @@ -13,6 +13,7 @@ #endif namespace ArduinoJson { +namespace Internals { class JsonArraySubscript : public JsonVariantBase { public: FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index) @@ -47,7 +48,7 @@ class JsonArraySubscript : public JsonVariantBase { } template - FORCE_INLINE typename Internals::JsonVariantAs::type as() const { + FORCE_INLINE typename JsonVariantAs::type as() const { return _array.get(_index); } @@ -86,21 +87,6 @@ class JsonArraySubscript : public JsonVariantBase { const size_t _index; }; -#if ARDUINOJSON_ENABLE_STD_STREAM -inline std::ostream& operator<<(std::ostream& os, - const JsonArraySubscript& source) { - return source.printTo(os); -} -#endif - -inline JsonArraySubscript JsonArray::operator[](size_t index) { - return JsonArraySubscript(*this, index); -} - -inline const JsonArraySubscript JsonArray::operator[](size_t index) const { - return JsonArraySubscript(*const_cast(this), index); -} - template inline JsonArraySubscript JsonVariantSubscripts::operator[]( size_t index) { @@ -113,7 +99,23 @@ inline const JsonArraySubscript JsonVariantSubscripts::operator[]( return impl()->template as()[index]; } -} // namespace ArduinoJson +#if ARDUINOJSON_ENABLE_STD_STREAM +inline std::ostream& operator<<(std::ostream& os, + const JsonArraySubscript& source) { + return source.printTo(os); +} +#endif +} + +inline Internals::JsonArraySubscript JsonArray::operator[](size_t index) { + return Internals::JsonArraySubscript(*this, index); +} + +inline const Internals::JsonArraySubscript JsonArray::operator[]( + size_t index) const { + return Internals::JsonArraySubscript(*const_cast(this), index); +} +} #ifdef _MSC_VER #pragma warning(pop) diff --git a/src/ArduinoJson/JsonBuffer.hpp b/src/ArduinoJson/JsonBuffer.hpp index 192d8b386..26101e086 100644 --- a/src/ArduinoJson/JsonBuffer.hpp +++ b/src/ArduinoJson/JsonBuffer.hpp @@ -42,8 +42,8 @@ class JsonBuffer : Internals::NonCopyable { // TValue = const std::string&, const String&, template DEPRECATED("char* are duplicated, you don't need strdup() anymore") - typename TypeTraits::EnableIf::value, - const char *>::type strdup(const TString &src) { + typename Internals::EnableIf::value, + const char *>::type strdup(const TString &src) { return Internals::StringTraits::duplicate(src, this); } // diff --git a/src/ArduinoJson/JsonBufferBase.hpp b/src/ArduinoJson/JsonBufferBase.hpp index 08be31fbe..1e771bfdb 100644 --- a/src/ArduinoJson/JsonBufferBase.hpp +++ b/src/ArduinoJson/JsonBufferBase.hpp @@ -7,6 +7,7 @@ #include "Deserialization/JsonParser.hpp" namespace ArduinoJson { +namespace Internals { template class JsonBufferBase : public JsonBuffer { public: @@ -25,8 +26,8 @@ class JsonBufferBase : public JsonBuffer { // JsonArray& parseArray(TString); // TString = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - JsonArray &>::type + typename Internals::EnableIf::value, + JsonArray &>::type parseArray(const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(that(), json, nestingLimit).parseArray(); @@ -62,8 +63,8 @@ class JsonBufferBase : public JsonBuffer { // JsonObject& parseObject(TString); // TString = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - JsonObject &>::type + typename Internals::EnableIf::value, + JsonObject &>::type parseObject(const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(that(), json, nestingLimit).parseObject(); @@ -91,8 +92,8 @@ class JsonBufferBase : public JsonBuffer { // JsonVariant parse(TString); // TString = const std::string&, const String& template - typename TypeTraits::EnableIf::value, - JsonVariant>::type + typename Internals::EnableIf::value, + JsonVariant>::type parse(const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(that(), json, nestingLimit).parseVariant(); @@ -123,3 +124,4 @@ class JsonBufferBase : public JsonBuffer { } }; } +} diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 8bd8105bf..c03bfa51d 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -26,6 +26,10 @@ namespace ArduinoJson { // Forward declarations class JsonArray; class JsonBuffer; +namespace Internals { +template +class JsonObjectSubscript; +} // A dictionary of JsonVariant indexed by string (char*) // @@ -50,15 +54,16 @@ class JsonObject : public Internals::JsonPrintable, // JsonObjectSubscript operator[](TKey) // TKey = const std::string&, const String& template - JsonObjectSubscript operator[](const TString& key) { - return JsonObjectSubscript(*this, key); + Internals::JsonObjectSubscript operator[]( + const TString& key) { + return Internals::JsonObjectSubscript(*this, key); } // // JsonObjectSubscript operator[](TKey) // TKey = char*, const char*, char[], const char[N], const FlashStringHelper* template - JsonObjectSubscript operator[](TString* key) { - return JsonObjectSubscript(*this, key); + Internals::JsonObjectSubscript operator[](TString* key) { + return Internals::JsonObjectSubscript(*this, key); } // Gets the value associated with the specified key. @@ -66,17 +71,19 @@ class JsonObject : public Internals::JsonPrintable, // const JsonObjectSubscript operator[](TKey) const; // TKey = const std::string&, const String& template - const JsonObjectSubscript operator[]( + const Internals::JsonObjectSubscript operator[]( const TString& key) const { - return JsonObjectSubscript(*const_cast(this), - key); + return Internals::JsonObjectSubscript( + *const_cast(this), key); } // // const JsonObjectSubscript operator[](TKey) const; // TKey = const char*, const char[N], const FlashStringHelper* template - const JsonObjectSubscript operator[](TString* key) const { - return JsonObjectSubscript(*const_cast(this), key); + const Internals::JsonObjectSubscript operator[]( + TString* key) const { + return Internals::JsonObjectSubscript( + *const_cast(this), key); } // Sets the specified key with the specified value. @@ -120,8 +127,8 @@ class JsonObject : public Internals::JsonPrintable, // TValue = float, double template DEPRECATED("Second argument is not supported anymore") - typename TypeTraits::EnableIf::value, - bool>::type + typename Internals::EnableIf::value, + bool>::type set(const TString& key, TValue value, uint8_t) { return set_impl(key, JsonVariant(value)); @@ -132,8 +139,8 @@ class JsonObject : public Internals::JsonPrintable, // TValue = float, double template DEPRECATED("Second argument is not supported anymore") - typename TypeTraits::EnableIf::value, - bool>::type + typename Internals::EnableIf::value, + bool>::type set(TString* key, TValue value, uint8_t) { return set_impl(key, JsonVariant(value)); } diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index ede6bdcf1..6ac476370 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -14,6 +14,7 @@ #endif namespace ArduinoJson { +namespace Internals { template class JsonObjectSubscript @@ -35,10 +36,8 @@ class JsonObjectSubscript // TValue = bool, char, long, int, short, float, double, // std::string, String, JsonArray, JsonObject template - FORCE_INLINE - typename TypeTraits::EnableIf::value, - this_type&>::type - operator=(const TValue& src) { + FORCE_INLINE typename EnableIf::value, this_type&>::type + operator=(const TValue& src) { _object.set(_key, src); return *this; } @@ -56,7 +55,7 @@ class JsonObjectSubscript } template - FORCE_INLINE typename Internals::JsonVariantAs::type as() const { + FORCE_INLINE typename JsonVariantAs::type as() const { return _object.get(_key); } @@ -71,10 +70,8 @@ class JsonObjectSubscript // TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant, // std::string, String, JsonArray, JsonObject template - FORCE_INLINE - typename TypeTraits::EnableIf::value, - bool>::type - set(const TValue& value) { + FORCE_INLINE typename EnableIf::value, bool>::type set( + const TValue& value) { return _object.set(_key, value); } // @@ -105,7 +102,8 @@ inline std::ostream& operator<<(std::ostream& os, return source.printTo(os); } #endif -} // namespace ArduinoJson +} +} #ifdef _MSC_VER #pragma warning(pop) diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index 415af172e..8326cbe86 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -36,7 +36,7 @@ class JsonObject; // - a char, short, int or a long (signed or unsigned) // - a string (const char*) // - a reference to a JsonArray or JsonObject -class JsonVariant : public JsonVariantBase { +class JsonVariant : public Internals::JsonVariantBase { template friend class Internals::JsonSerializer; @@ -56,8 +56,8 @@ class JsonVariant : public JsonVariantBase { // JsonVariant(double value); // JsonVariant(float value); template - JsonVariant(T value, typename TypeTraits::EnableIf< - TypeTraits::IsFloatingPoint::value>::type * = 0) { + JsonVariant(T value, typename Internals::EnableIf< + Internals::IsFloatingPoint::value>::type * = 0) { using namespace Internals; _type = JSON_FLOAT; _content.asFloat = static_cast(value); @@ -65,8 +65,8 @@ class JsonVariant : public JsonVariantBase { template DEPRECATED("Second argument is not supported anymore") JsonVariant(T value, uint8_t, - typename TypeTraits::EnableIf< - TypeTraits::IsFloatingPoint::value>::type * = 0) { + typename Internals::EnableIf< + Internals::IsFloatingPoint::value>::type * = 0) { using namespace Internals; _type = JSON_FLOAT; _content.asFloat = static_cast(value); @@ -79,9 +79,11 @@ class JsonVariant : public JsonVariantBase { // JsonVariant(signed long) // JsonVariant(signed char) template - JsonVariant(T value, typename TypeTraits::EnableIf< - TypeTraits::IsSignedIntegral::value || - TypeTraits::IsSame::value>::type * = 0) { + JsonVariant( + T value, + typename Internals::EnableIf::value || + Internals::IsSame::value>::type * = + 0) { using namespace Internals; if (value >= 0) { _type = JSON_POSITIVE_INTEGER; @@ -96,8 +98,8 @@ class JsonVariant : public JsonVariantBase { // JsonVariant(unsigned long) template JsonVariant(T value, - typename TypeTraits::EnableIf< - TypeTraits::IsUnsignedIntegral::value>::type * = 0) { + typename Internals::EnableIf< + Internals::IsUnsignedIntegral::value>::type * = 0) { using namespace Internals; _type = JSON_POSITIVE_INTEGER; _content.asInteger = static_cast(value); @@ -110,7 +112,7 @@ class JsonVariant : public JsonVariantBase { template JsonVariant( const TChar *value, - typename TypeTraits::EnableIf::value>::type * = + typename Internals::EnableIf::value>::type * = 0) { _type = Internals::JSON_STRING; _content.asString = reinterpret_cast(value); @@ -144,14 +146,13 @@ class JsonVariant : public JsonVariantBase { // unsigned int as() const; // unsigned long as() const; template - const typename TypeTraits::EnableIf::value, T>::type + const typename Internals::EnableIf::value, T>::type as() const { return variantAsInteger(); } // bool as() const template - const typename TypeTraits::EnableIf::value, - T>::type + const typename Internals::EnableIf::value, T>::type as() const { return variantAsInteger() != 0; } @@ -159,8 +160,8 @@ class JsonVariant : public JsonVariantBase { // double as() const; // float as() const; template - const typename TypeTraits::EnableIf::value, - T>::type + const typename Internals::EnableIf::value, + T>::type as() const { return variantAsFloat(); } @@ -168,9 +169,9 @@ class JsonVariant : public JsonVariantBase { // const char* as() const; // const char* as() const; template - typename TypeTraits::EnableIf::value || - TypeTraits::IsSame::value, - const char *>::type + typename Internals::EnableIf::value || + Internals::IsSame::value, + const char *>::type as() const { return variantAsString(); } @@ -178,7 +179,7 @@ class JsonVariant : public JsonVariantBase { // std::string as() const; // String as() const; template - typename TypeTraits::EnableIf::has_append, T>::type + typename Internals::EnableIf::has_append, T>::type as() const { const char *cstr = variantAsString(); if (cstr) return T(cstr); @@ -190,9 +191,9 @@ class JsonVariant : public JsonVariantBase { // JsonArray& as const; // JsonArray& as const; template - typename TypeTraits::EnableIf< - TypeTraits::IsSame::type, - JsonArray>::value, + typename Internals::EnableIf< + Internals::IsSame::type, + JsonArray>::value, JsonArray &>::type as() const { return variantAsArray(); @@ -200,9 +201,9 @@ class JsonVariant : public JsonVariantBase { // // const JsonArray& as const; template - typename TypeTraits::EnableIf< - TypeTraits::IsSame::type, - const JsonArray>::value, + typename Internals::EnableIf< + Internals::IsSame::type, + const JsonArray>::value, const JsonArray &>::type as() const { return variantAsArray(); @@ -211,9 +212,9 @@ class JsonVariant : public JsonVariantBase { // JsonObject& as const; // JsonObject& as const; template - typename TypeTraits::EnableIf< - TypeTraits::IsSame::type, - JsonObject>::value, + typename Internals::EnableIf< + Internals::IsSame::type, + JsonObject>::value, JsonObject &>::type as() const { return variantAsObject(); @@ -222,9 +223,9 @@ class JsonVariant : public JsonVariantBase { // JsonObject& as const; // JsonObject& as const; template - typename TypeTraits::EnableIf< - TypeTraits::IsSame::type, - const JsonObject>::value, + typename Internals::EnableIf< + Internals::IsSame::type, + const JsonObject>::value, const JsonObject &>::type as() const { return variantAsObject(); @@ -232,8 +233,8 @@ class JsonVariant : public JsonVariantBase { // // JsonVariant as const; template - typename TypeTraits::EnableIf::value, - T>::type + typename Internals::EnableIf::value, + T>::type as() const { return *this; } @@ -251,23 +252,22 @@ class JsonVariant : public JsonVariantBase { // bool is() const; // bool is() const; template - typename TypeTraits::EnableIf::value, bool>::type - is() const { + typename Internals::EnableIf::value, bool>::type is() + const { return variantIsInteger(); } // // bool is() const; // bool is() const; template - typename TypeTraits::EnableIf::value, - bool>::type + typename Internals::EnableIf::value, bool>::type is() const { return variantIsFloat(); } // // bool is() const template - typename TypeTraits::EnableIf::value, bool>::type + typename Internals::EnableIf::value, bool>::type is() const { return variantIsBoolean(); } @@ -275,9 +275,9 @@ class JsonVariant : public JsonVariantBase { // bool is() const; // bool is() const; template - typename TypeTraits::EnableIf::value || - TypeTraits::IsSame::value, - bool>::type + typename Internals::EnableIf::value || + Internals::IsSame::value, + bool>::type is() const { return variantIsString(); } @@ -286,11 +286,10 @@ class JsonVariant : public JsonVariantBase { // bool is const; // bool is const; template - typename TypeTraits::EnableIf< - TypeTraits::IsSame< - typename TypeTraits::RemoveConst< - typename TypeTraits::RemoveReference::type>::type, - JsonArray>::value, + typename Internals::EnableIf< + Internals::IsSame::type>::type, + JsonArray>::value, bool>::type is() const { return variantIsArray(); @@ -300,11 +299,10 @@ class JsonVariant : public JsonVariantBase { // bool is const; // bool is const; template - typename TypeTraits::EnableIf< - TypeTraits::IsSame< - typename TypeTraits::RemoveConst< - typename TypeTraits::RemoveReference::type>::type, - JsonObject>::value, + typename Internals::EnableIf< + Internals::IsSame::type>::type, + JsonObject>::value, bool>::type is() const { return variantIsObject(); diff --git a/src/ArduinoJson/JsonVariantBase.hpp b/src/ArduinoJson/JsonVariantBase.hpp index 8c669eb54..44acf2e14 100644 --- a/src/ArduinoJson/JsonVariantBase.hpp +++ b/src/ArduinoJson/JsonVariantBase.hpp @@ -11,12 +11,14 @@ #include "Serialization/JsonPrintable.hpp" namespace ArduinoJson { +namespace Internals { template -class JsonVariantBase : public Internals::JsonPrintable, +class JsonVariantBase : public JsonPrintable, public JsonVariantCasts, public JsonVariantComparisons, public JsonVariantOr, public JsonVariantSubscripts, - public TypeTraits::JsonVariantTag {}; + public JsonVariantTag {}; +} } diff --git a/src/ArduinoJson/JsonVariantCasts.hpp b/src/ArduinoJson/JsonVariantCasts.hpp index 85a96de4a..68f5bd7dd 100644 --- a/src/ArduinoJson/JsonVariantCasts.hpp +++ b/src/ArduinoJson/JsonVariantCasts.hpp @@ -8,6 +8,7 @@ #include "Polyfills/attributes.hpp" namespace ArduinoJson { +namespace Internals { template class JsonVariantCasts { @@ -55,3 +56,4 @@ class JsonVariantCasts { } }; } +} diff --git a/src/ArduinoJson/JsonVariantComparisons.hpp b/src/ArduinoJson/JsonVariantComparisons.hpp index 74eeae438..cae533729 100644 --- a/src/ArduinoJson/JsonVariantComparisons.hpp +++ b/src/ArduinoJson/JsonVariantComparisons.hpp @@ -9,6 +9,7 @@ #include "TypeTraits/IsVariant.hpp" namespace ArduinoJson { +namespace Internals { template class JsonVariantComparisons { @@ -20,10 +21,8 @@ class JsonVariantComparisons { } template - friend - typename TypeTraits::EnableIf::value, - bool>::type - operator==(TComparand comparand, const JsonVariantComparisons &variant) { + friend typename EnableIf::value, bool>::type + operator==(TComparand comparand, const JsonVariantComparisons &variant) { return variant.equals(comparand); } @@ -34,10 +33,8 @@ class JsonVariantComparisons { } template - friend - typename TypeTraits::EnableIf::value, - bool>::type - operator!=(TComparand comparand, const JsonVariantComparisons &variant) { + friend typename EnableIf::value, bool>::type + operator!=(TComparand comparand, const JsonVariantComparisons &variant) { return !variant.equals(comparand); } @@ -94,7 +91,7 @@ class JsonVariantComparisons { } template - const typename Internals::JsonVariantAs::type as() const { + const typename JsonVariantAs::type as() const { return impl()->template as(); } @@ -104,18 +101,16 @@ class JsonVariantComparisons { } template - typename TypeTraits::EnableIf::has_equals, - bool>::type - equals(const TString &comparand) const { + typename EnableIf::has_equals, bool>::type equals( + const TString &comparand) const { const char *value = as(); - return Internals::StringTraits::equals(comparand, value); + return StringTraits::equals(comparand, value); } template - typename TypeTraits::EnableIf< - !TypeTraits::IsVariant::value && - !Internals::StringTraits::has_equals, - bool>::type + typename EnableIf::value && + !StringTraits::has_equals, + bool>::type equals(const TComparand &comparand) const { return as() == comparand; } @@ -140,3 +135,4 @@ class JsonVariantComparisons { } }; } +} diff --git a/src/ArduinoJson/JsonVariantImpl.hpp b/src/ArduinoJson/JsonVariantImpl.hpp index 1ebec9813..31f96ce1a 100644 --- a/src/ArduinoJson/JsonVariantImpl.hpp +++ b/src/ArduinoJson/JsonVariantImpl.hpp @@ -58,7 +58,7 @@ inline T JsonVariant::variantAsInteger() const { return T(~_content.asInteger + 1); case JSON_STRING: case JSON_UNPARSED: - return Polyfills::parseInteger(_content.asString); + return parseInteger(_content.asString); default: return T(_content.asFloat); } @@ -86,7 +86,7 @@ inline T JsonVariant::variantAsFloat() const { return -static_cast(_content.asInteger); case JSON_STRING: case JSON_UNPARSED: - return Polyfills::parseFloat(_content.asString); + return parseFloat(_content.asString); default: return static_cast(_content.asFloat); } @@ -106,7 +106,7 @@ inline bool JsonVariant::variantIsInteger() const { using namespace Internals; return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER || - (_type == JSON_UNPARSED && Polyfills::isInteger(_content.asString)); + (_type == JSON_UNPARSED && isInteger(_content.asString)); } inline bool JsonVariant::variantIsFloat() const { @@ -114,7 +114,7 @@ inline bool JsonVariant::variantIsFloat() const { return _type == JSON_FLOAT || _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER || - (_type == JSON_UNPARSED && Polyfills::isFloat(_content.asString)); + (_type == JSON_UNPARSED && isFloat(_content.asString)); } #if ARDUINOJSON_ENABLE_STD_STREAM diff --git a/src/ArduinoJson/JsonVariantOr.hpp b/src/ArduinoJson/JsonVariantOr.hpp index 895737ba7..cad5626ab 100644 --- a/src/ArduinoJson/JsonVariantOr.hpp +++ b/src/ArduinoJson/JsonVariantOr.hpp @@ -8,6 +8,7 @@ #include "Polyfills/attributes.hpp" namespace ArduinoJson { +namespace Internals { template class JsonVariantOr { @@ -34,3 +35,4 @@ class JsonVariantOr { } }; } +} diff --git a/src/ArduinoJson/JsonVariantSubscripts.hpp b/src/ArduinoJson/JsonVariantSubscripts.hpp index 210f26113..279ee019f 100644 --- a/src/ArduinoJson/JsonVariantSubscripts.hpp +++ b/src/ArduinoJson/JsonVariantSubscripts.hpp @@ -10,6 +10,7 @@ #include "TypeTraits/EnableIf.hpp" namespace ArduinoJson { +namespace Internals { // Forward declarations. class JsonArraySubscript; @@ -41,19 +42,18 @@ class JsonVariantSubscripts { // const JsonObjectSubscript operator[](TKey) const; // TKey = const std::string&, const String& template - FORCE_INLINE typename TypeTraits::EnableIf< - Internals::StringTraits::has_equals, - const JsonObjectSubscript >::type - operator[](const TString &key) const { + FORCE_INLINE + typename EnableIf::has_equals, + const JsonObjectSubscript >::type + operator[](const TString &key) const { return impl()->template as()[key]; } // // const JsonObjectSubscript operator[](TKey) const; // TKey = const std::string&, const String& template - FORCE_INLINE typename TypeTraits::EnableIf< - Internals::StringTraits::has_equals, - JsonObjectSubscript >::type + FORCE_INLINE typename EnableIf::has_equals, + JsonObjectSubscript >::type operator[](const TString &key) { return impl()->template as()[key]; } @@ -61,9 +61,8 @@ class JsonVariantSubscripts { // JsonObjectSubscript operator[](TKey); // TKey = const char*, const char[N], const FlashStringHelper* template - FORCE_INLINE typename TypeTraits::EnableIf< - Internals::StringTraits::has_equals, - JsonObjectSubscript >::type + FORCE_INLINE typename EnableIf::has_equals, + JsonObjectSubscript >::type operator[](const TString *key) { return impl()->template as()[key]; } @@ -71,10 +70,10 @@ class JsonVariantSubscripts { // JsonObjectSubscript operator[](TKey); // TKey = const char*, const char[N], const FlashStringHelper* template - FORCE_INLINE typename TypeTraits::EnableIf< - Internals::StringTraits::has_equals, - const JsonObjectSubscript >::type - operator[](const TString *key) const { + FORCE_INLINE + typename EnableIf::has_equals, + const JsonObjectSubscript >::type + operator[](const TString *key) const { return impl()->template as()[key]; } @@ -84,3 +83,4 @@ class JsonVariantSubscripts { } }; } +} diff --git a/src/ArduinoJson/Polyfills/ctype.hpp b/src/ArduinoJson/Polyfills/ctype.hpp index 0e0f973e8..2d52703cd 100644 --- a/src/ArduinoJson/Polyfills/ctype.hpp +++ b/src/ArduinoJson/Polyfills/ctype.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace Polyfills { +namespace Internals { inline bool isdigit(char c) { return '0' <= c && c <= '9'; diff --git a/src/ArduinoJson/Polyfills/isFloat.hpp b/src/ArduinoJson/Polyfills/isFloat.hpp index c89f8c4b0..973b89fe9 100644 --- a/src/ArduinoJson/Polyfills/isFloat.hpp +++ b/src/ArduinoJson/Polyfills/isFloat.hpp @@ -8,7 +8,7 @@ #include "./ctype.hpp" namespace ArduinoJson { -namespace Polyfills { +namespace Internals { inline bool isFloat(const char* s) { if (!s) return false; diff --git a/src/ArduinoJson/Polyfills/isInteger.hpp b/src/ArduinoJson/Polyfills/isInteger.hpp index d63fdfba4..21f166897 100644 --- a/src/ArduinoJson/Polyfills/isInteger.hpp +++ b/src/ArduinoJson/Polyfills/isInteger.hpp @@ -7,7 +7,7 @@ #include "./ctype.hpp" namespace ArduinoJson { -namespace Polyfills { +namespace Internals { inline bool isInteger(const char* s) { if (!s) return false; diff --git a/src/ArduinoJson/Polyfills/math.hpp b/src/ArduinoJson/Polyfills/math.hpp index 3c631631a..48773edd2 100644 --- a/src/ArduinoJson/Polyfills/math.hpp +++ b/src/ArduinoJson/Polyfills/math.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace Polyfills { +namespace Internals { template bool isNaN(T x) { return x != x; diff --git a/src/ArduinoJson/Polyfills/parseFloat.hpp b/src/ArduinoJson/Polyfills/parseFloat.hpp index 54034c5cf..49b0f6fcd 100644 --- a/src/ArduinoJson/Polyfills/parseFloat.hpp +++ b/src/ArduinoJson/Polyfills/parseFloat.hpp @@ -9,11 +9,11 @@ #include "./math.hpp" namespace ArduinoJson { -namespace Polyfills { +namespace Internals { template inline T parseFloat(const char* s) { - typedef TypeTraits::FloatTraits traits; + typedef FloatTraits traits; typedef typename traits::mantissa_type mantissa_t; typedef typename traits::exponent_type exponent_t; diff --git a/src/ArduinoJson/Polyfills/parseInteger.hpp b/src/ArduinoJson/Polyfills/parseInteger.hpp index a1feb2aa1..e8f197494 100644 --- a/src/ArduinoJson/Polyfills/parseInteger.hpp +++ b/src/ArduinoJson/Polyfills/parseInteger.hpp @@ -10,7 +10,7 @@ #include "./ctype.hpp" namespace ArduinoJson { -namespace Polyfills { +namespace Internals { template T parseInteger(const char *s) { if (!s) return 0; // NULL diff --git a/src/ArduinoJson/Serialization/FloatParts.hpp b/src/ArduinoJson/Serialization/FloatParts.hpp index aceaa6384..c14e3b553 100644 --- a/src/ArduinoJson/Serialization/FloatParts.hpp +++ b/src/ArduinoJson/Serialization/FloatParts.hpp @@ -56,7 +56,7 @@ struct FloatParts { } static int16_t normalize(TFloat& value) { - typedef TypeTraits::FloatTraits traits; + typedef FloatTraits traits; int16_t powersOf10 = 0; int8_t index = sizeof(TFloat) == 8 ? 8 : 5; diff --git a/src/ArduinoJson/Serialization/JsonPrintable.hpp b/src/ArduinoJson/Serialization/JsonPrintable.hpp index 650cff543..43d413a85 100644 --- a/src/ArduinoJson/Serialization/JsonPrintable.hpp +++ b/src/ArduinoJson/Serialization/JsonPrintable.hpp @@ -29,8 +29,8 @@ template class JsonPrintable { public: template - typename TypeTraits::EnableIf::has_append, size_t>::type - printTo(Print &print) const { + typename EnableIf::has_append, size_t>::type printTo( + Print &print) const { JsonWriter writer(print); JsonSerializer >::serialize(downcast(), writer); return writer.bytesWritten(); @@ -55,8 +55,8 @@ class JsonPrintable { } template - typename TypeTraits::EnableIf::has_append, size_t>::type - printTo(TString &str) const { + typename EnableIf::has_append, size_t>::type printTo( + TString &str) const { DynamicStringBuilder sb(str); return printTo(sb); } @@ -78,14 +78,14 @@ class JsonPrintable { } template - typename TypeTraits::EnableIf::has_append, size_t>::type + typename EnableIf::has_append, size_t>::type prettyPrintTo(Print &print) const { IndentedPrint indentedPrint(print); return prettyPrintTo(indentedPrint); } template - typename TypeTraits::EnableIf::has_append, size_t>::type + typename EnableIf::has_append, size_t>::type prettyPrintTo(TString &str) const { DynamicStringBuilder sb(str); return prettyPrintTo(sb); diff --git a/src/ArduinoJson/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Serialization/JsonSerializer.hpp index c431ac839..0cb537f7d 100644 --- a/src/ArduinoJson/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Serialization/JsonSerializer.hpp @@ -9,14 +9,15 @@ namespace ArduinoJson { class JsonArray; -class JsonArraySubscript; class JsonObject; -template -class JsonObjectSubscript; class JsonVariant; namespace Internals { +class JsonArraySubscript; +template +class JsonObjectSubscript; + template class JsonSerializer { public: diff --git a/src/ArduinoJson/Serialization/JsonWriter.hpp b/src/ArduinoJson/Serialization/JsonWriter.hpp index 62027e9f1..146d51dcb 100644 --- a/src/ArduinoJson/Serialization/JsonWriter.hpp +++ b/src/ArduinoJson/Serialization/JsonWriter.hpp @@ -79,14 +79,14 @@ class JsonWriter { template void writeFloat(TFloat value) { - if (Polyfills::isNaN(value)) return writeRaw("NaN"); + if (isNaN(value)) return writeRaw("NaN"); if (value < 0.0) { writeRaw('-'); value = -value; } - if (Polyfills::isInfinity(value)) return writeRaw("Infinity"); + if (isInfinity(value)) return writeRaw("Infinity"); FloatParts parts(value); diff --git a/src/ArduinoJson/StaticJsonBuffer.hpp b/src/ArduinoJson/StaticJsonBuffer.hpp index c68eb7125..267d9d018 100644 --- a/src/ArduinoJson/StaticJsonBuffer.hpp +++ b/src/ArduinoJson/StaticJsonBuffer.hpp @@ -7,6 +7,7 @@ #include "JsonBufferBase.hpp" namespace ArduinoJson { +namespace Internals { class StaticJsonBufferBase : public JsonBufferBase { public: @@ -90,6 +91,7 @@ class StaticJsonBufferBase : public JsonBufferBase { size_t _capacity; size_t _size; }; +} #if defined(__clang__) #pragma clang diagnostic push @@ -105,9 +107,10 @@ class StaticJsonBufferBase : public JsonBufferBase { // The template paramenter CAPACITY specifies the capacity of the buffer in // bytes. template -class StaticJsonBuffer : public StaticJsonBufferBase { +class StaticJsonBuffer : public Internals::StaticJsonBufferBase { public: - explicit StaticJsonBuffer() : StaticJsonBufferBase(_buffer, CAPACITY) {} + explicit StaticJsonBuffer() + : Internals::StaticJsonBufferBase(_buffer, CAPACITY) {} private: char _buffer[CAPACITY]; diff --git a/src/ArduinoJson/StringTraits/ArduinoStream.hpp b/src/ArduinoJson/StringTraits/ArduinoStream.hpp index 80d383db6..5db0852b8 100644 --- a/src/ArduinoJson/StringTraits/ArduinoStream.hpp +++ b/src/ArduinoJson/StringTraits/ArduinoStream.hpp @@ -49,11 +49,11 @@ struct ArduinoStreamTraits { }; template -struct StringTraits::type>::value>::type> +struct StringTraits< + TStream, + // match any type that is derived from Stream: + typename EnableIf< + IsBaseOf::type>::value>::type> : ArduinoStreamTraits {}; } } diff --git a/src/ArduinoJson/StringTraits/CharPointer.hpp b/src/ArduinoJson/StringTraits/CharPointer.hpp index 20864f707..a9f30f786 100644 --- a/src/ArduinoJson/StringTraits/CharPointer.hpp +++ b/src/ArduinoJson/StringTraits/CharPointer.hpp @@ -50,14 +50,13 @@ struct CharPointerTraits { static const bool has_append = false; static const bool has_equals = true; - static const bool should_duplicate = !TypeTraits::IsConst::value; + static const bool should_duplicate = !IsConst::value; }; // char*, unsigned char*, signed char* // const char*, const unsigned char*, const signed char* template -struct StringTraits::value>::type> +struct StringTraits::value>::type> : CharPointerTraits {}; } } diff --git a/src/ArduinoJson/StringTraits/StdStream.hpp b/src/ArduinoJson/StringTraits/StdStream.hpp index 3a410aeb8..227c74406 100644 --- a/src/ArduinoJson/StringTraits/StdStream.hpp +++ b/src/ArduinoJson/StringTraits/StdStream.hpp @@ -48,11 +48,11 @@ struct StdStreamTraits { }; template -struct StringTraits::type>::value>::type> +struct StringTraits< + TStream, + // match any type that is derived from std::istream: + typename EnableIf::type>::value>::type> : StdStreamTraits {}; } } diff --git a/src/ArduinoJson/TypeTraits/EnableIf.hpp b/src/ArduinoJson/TypeTraits/EnableIf.hpp index c07b217f0..83fc5e07f 100644 --- a/src/ArduinoJson/TypeTraits/EnableIf.hpp +++ b/src/ArduinoJson/TypeTraits/EnableIf.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that return the type T if Condition is true. template diff --git a/src/ArduinoJson/TypeTraits/FloatTraits.hpp b/src/ArduinoJson/TypeTraits/FloatTraits.hpp index d7acd05ee..5044807a6 100644 --- a/src/ArduinoJson/TypeTraits/FloatTraits.hpp +++ b/src/ArduinoJson/TypeTraits/FloatTraits.hpp @@ -10,7 +10,7 @@ #include "../Polyfills/math.hpp" namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { template struct FloatTraits {}; diff --git a/src/ArduinoJson/TypeTraits/IsArray.hpp b/src/ArduinoJson/TypeTraits/IsArray.hpp index c65d00ebb..259923115 100644 --- a/src/ArduinoJson/TypeTraits/IsArray.hpp +++ b/src/ArduinoJson/TypeTraits/IsArray.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that return the type T without the const modifier template diff --git a/src/ArduinoJson/TypeTraits/IsBaseOf.hpp b/src/ArduinoJson/TypeTraits/IsBaseOf.hpp index 30e51b5d3..bf24e965e 100644 --- a/src/ArduinoJson/TypeTraits/IsBaseOf.hpp +++ b/src/ArduinoJson/TypeTraits/IsBaseOf.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that returns true if Derived inherits from TBase is an // integral type. diff --git a/src/ArduinoJson/TypeTraits/IsChar.hpp b/src/ArduinoJson/TypeTraits/IsChar.hpp index 8e210d76d..d97cec213 100644 --- a/src/ArduinoJson/TypeTraits/IsChar.hpp +++ b/src/ArduinoJson/TypeTraits/IsChar.hpp @@ -7,7 +7,7 @@ #include "IsSame.hpp" namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that returns true if T is a charater template diff --git a/src/ArduinoJson/TypeTraits/IsConst.hpp b/src/ArduinoJson/TypeTraits/IsConst.hpp index 295d03c84..512ee5ca0 100644 --- a/src/ArduinoJson/TypeTraits/IsConst.hpp +++ b/src/ArduinoJson/TypeTraits/IsConst.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that return the type T without the const modifier template diff --git a/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp b/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp index 7e3d305b5..e41a6824c 100644 --- a/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp +++ b/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp @@ -7,7 +7,7 @@ #include "IsSame.hpp" namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that returns true if T is a floating point type template diff --git a/src/ArduinoJson/TypeTraits/IsIntegral.hpp b/src/ArduinoJson/TypeTraits/IsIntegral.hpp index a319f5cc8..17ae5f284 100644 --- a/src/ArduinoJson/TypeTraits/IsIntegral.hpp +++ b/src/ArduinoJson/TypeTraits/IsIntegral.hpp @@ -9,14 +9,14 @@ #include "IsUnsignedIntegral.hpp" namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that returns true if T is an integral type. template struct IsIntegral { - static const bool value = TypeTraits::IsSignedIntegral::value || - TypeTraits::IsUnsignedIntegral::value || - TypeTraits::IsSame::value; + static const bool value = IsSignedIntegral::value || + IsUnsignedIntegral::value || + IsSame::value; // CAUTION: differs from std::is_integral as it doesn't include bool }; diff --git a/src/ArduinoJson/TypeTraits/IsSame.hpp b/src/ArduinoJson/TypeTraits/IsSame.hpp index bbf3ec17c..06567c93b 100644 --- a/src/ArduinoJson/TypeTraits/IsSame.hpp +++ b/src/ArduinoJson/TypeTraits/IsSame.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that returns true if types T and U are the same. template diff --git a/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp b/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp index 8b590087f..7334eb9c7 100644 --- a/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp +++ b/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp @@ -8,23 +8,21 @@ #include "IsSame.hpp" namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that returns true if T is an integral type. template struct IsSignedIntegral { - static const bool value = TypeTraits::IsSame::value || - TypeTraits::IsSame::value || - TypeTraits::IsSame::value || - TypeTraits::IsSame::value || + static const bool value = + IsSame::value || IsSame::value || + IsSame::value || IsSame::value || #if ARDUINOJSON_USE_LONG_LONG - TypeTraits::IsSame::value || + IsSame::value || #endif - #if ARDUINOJSON_USE_INT64 - TypeTraits::IsSame::value || + IsSame::value || #endif - false; + false; }; } } diff --git a/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp b/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp index 0e43ab01f..938423f5c 100644 --- a/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp +++ b/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp @@ -8,23 +8,21 @@ #include "IsSame.hpp" namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that returns true if T is an integral type. template struct IsUnsignedIntegral { - static const bool value = TypeTraits::IsSame::value || - TypeTraits::IsSame::value || - TypeTraits::IsSame::value || - TypeTraits::IsSame::value || + static const bool value = + IsSame::value || IsSame::value || + IsSame::value || IsSame::value || #if ARDUINOJSON_USE_LONG_LONG - TypeTraits::IsSame::value || + IsSame::value || #endif - #if ARDUINOJSON_USE_INT64 - TypeTraits::IsSame::value || + IsSame::value || #endif - false; + false; }; } } diff --git a/src/ArduinoJson/TypeTraits/IsVariant.hpp b/src/ArduinoJson/TypeTraits/IsVariant.hpp index 85a5e3fef..f8b299f7a 100644 --- a/src/ArduinoJson/TypeTraits/IsVariant.hpp +++ b/src/ArduinoJson/TypeTraits/IsVariant.hpp @@ -7,7 +7,7 @@ #include "IsBaseOf.hpp" namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { class JsonVariantTag {}; diff --git a/src/ArduinoJson/TypeTraits/RemoveConst.hpp b/src/ArduinoJson/TypeTraits/RemoveConst.hpp index f9714bd3b..39d4cb5a5 100644 --- a/src/ArduinoJson/TypeTraits/RemoveConst.hpp +++ b/src/ArduinoJson/TypeTraits/RemoveConst.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that return the type T without the const modifier template diff --git a/src/ArduinoJson/TypeTraits/RemoveReference.hpp b/src/ArduinoJson/TypeTraits/RemoveReference.hpp index 8d5a929fb..395a12889 100644 --- a/src/ArduinoJson/TypeTraits/RemoveReference.hpp +++ b/src/ArduinoJson/TypeTraits/RemoveReference.hpp @@ -5,7 +5,7 @@ #pragma once namespace ArduinoJson { -namespace TypeTraits { +namespace Internals { // A meta-function that return the type T without the reference modifier. template diff --git a/test/DynamicJsonBuffer/alloc.cpp b/test/DynamicJsonBuffer/alloc.cpp index 54b7842ca..c45e6866a 100644 --- a/test/DynamicJsonBuffer/alloc.cpp +++ b/test/DynamicJsonBuffer/alloc.cpp @@ -6,6 +6,8 @@ #include #include +using namespace ArduinoJson::Internals; + static bool isAligned(void* ptr) { const size_t mask = sizeof(void*) - 1; size_t addr = reinterpret_cast(ptr); diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index 013b17414..824d968c3 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -5,6 +5,8 @@ #include #include +using namespace ArduinoJson::Internals; + struct NoMemoryAllocator { void* allocate(size_t) { return NULL; diff --git a/test/Misc/TypeTraits.cpp b/test/Misc/TypeTraits.cpp index 2f8e7e8cc..8d730b219 100644 --- a/test/Misc/TypeTraits.cpp +++ b/test/Misc/TypeTraits.cpp @@ -5,7 +5,7 @@ #include #include -using namespace ArduinoJson::TypeTraits; +using namespace ArduinoJson::Internals; TEST_CASE("TypeTraits") { SECTION("IsBaseOf") { diff --git a/test/Polyfills/isFloat.cpp b/test/Polyfills/isFloat.cpp index 033f91548..225d52214 100644 --- a/test/Polyfills/isFloat.cpp +++ b/test/Polyfills/isFloat.cpp @@ -5,7 +5,7 @@ #include #include -using namespace ArduinoJson::Polyfills; +using namespace ArduinoJson::Internals; TEST_CASE("isFloat()") { SECTION("Input is NULL") { diff --git a/test/Polyfills/isInteger.cpp b/test/Polyfills/isInteger.cpp index 64f5937e0..f0bec4ae2 100644 --- a/test/Polyfills/isInteger.cpp +++ b/test/Polyfills/isInteger.cpp @@ -5,7 +5,7 @@ #include #include -using namespace ArduinoJson::Polyfills; +using namespace ArduinoJson::Internals; TEST_CASE("isInteger()") { SECTION("Null") { diff --git a/test/Polyfills/parseFloat.cpp b/test/Polyfills/parseFloat.cpp index c57bc413a..362e46d6f 100644 --- a/test/Polyfills/parseFloat.cpp +++ b/test/Polyfills/parseFloat.cpp @@ -5,7 +5,7 @@ #include #include -using namespace ArduinoJson::Polyfills; +using namespace ArduinoJson::Internals; template void check(const char* input, T expected) { diff --git a/test/Polyfills/parseInteger.cpp b/test/Polyfills/parseInteger.cpp index 50e5eedbe..3d25bdb25 100644 --- a/test/Polyfills/parseInteger.cpp +++ b/test/Polyfills/parseInteger.cpp @@ -6,7 +6,7 @@ #include #include -using namespace ArduinoJson::Polyfills; +using namespace ArduinoJson::Internals; template void check(const char* input, T expected) { diff --git a/test/StaticJsonBuffer/startString.cpp b/test/StaticJsonBuffer/startString.cpp index 5bfce16a4..282823b70 100644 --- a/test/StaticJsonBuffer/startString.cpp +++ b/test/StaticJsonBuffer/startString.cpp @@ -5,6 +5,8 @@ #include #include +using namespace ArduinoJson::Internals; + TEST_CASE("StaticJsonBuffer::startString()") { SECTION("WorksWhenBufferIsBigEnough") { StaticJsonBuffer<6> jsonBuffer; From cf5396aaed6d16d1fb4e73b82ce6606938591043 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 19 Jan 2018 15:35:19 +0100 Subject: [PATCH 0011/1079] Set version to 5.13.0 --- CHANGELOG.md | 4 ++-- appveyor.yml | 2 +- library.json | 2 +- library.properties | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 211424248..3646765e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ ArduinoJson: change log ======================= -HEAD ----- +v5.13.0 +------- * Changed the rules of string duplication (issue #658) * `RawJson()` accepts any kind of string and obeys to the same rules for duplication diff --git a/appveyor.yml b/appveyor.yml index e5916bc14..9c70fe8c4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 5.12.0.{build} +version: 5.13.0.{build} environment: matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 diff --git a/library.json b/library.json index d4233e917..4b326c661 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/bblanchon/ArduinoJson.git" }, - "version": "5.12.0", + "version": "5.13.0", "authors": { "name": "Benoit Blanchon", "url": "https://blog.benoitblanchon.fr" diff --git a/library.properties b/library.properties index 703b1bdd4..a22864584 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ArduinoJson -version=5.12.0 +version=5.13.0 author=Benoit Blanchon maintainer=Benoit Blanchon sentence=An efficient and elegant JSON library for Arduino. From b4eece01f873a752367a37339078836d5ef05566 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 9 Feb 2018 09:05:29 +0100 Subject: [PATCH 0012/1079] Fixed `JsonVariant::operator|(int)` to accept double (fixes #675) --- CHANGELOG.md | 5 +++++ src/ArduinoJson/JsonVariantOr.hpp | 20 +++++++++++++++++--- test/JsonVariant/or.cpp | 6 ++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3646765e5..276beb93b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ ArduinoJson: change log ======================= +HEAD +---- + +* Fixed `JsonVariant::operator|(int)` that returned the default value if the variant contained a double (issue #675) + v5.13.0 ------- diff --git a/src/ArduinoJson/JsonVariantOr.hpp b/src/ArduinoJson/JsonVariantOr.hpp index cad5626ab..d8022fcb2 100644 --- a/src/ArduinoJson/JsonVariantOr.hpp +++ b/src/ArduinoJson/JsonVariantOr.hpp @@ -6,6 +6,8 @@ #include "Data/JsonVariantAs.hpp" #include "Polyfills/attributes.hpp" +#include "TypeTraits/EnableIf.hpp" +#include "TypeTraits/IsIntegral.hpp" namespace ArduinoJson { namespace Internals { @@ -15,7 +17,8 @@ class JsonVariantOr { public: // Returns the default value if the JsonVariant is undefined of incompatible template - T operator|(const T &defaultValue) const { + typename EnableIf::value, T>::type operator|( + const T &defaultValue) const { if (impl()->template is()) return impl()->template as(); else @@ -29,10 +32,21 @@ class JsonVariantOr { return value ? value : defaultValue; } + // Returns the default value if the JsonVariant is undefined of incompatible + // Special case for integers: we also accept double + template + typename EnableIf::value, Integer>::type operator|( + const Integer &defaultValue) const { + if (impl()->template is()) + return impl()->template as(); + else + return defaultValue; + } + private: const TImpl *impl() const { return static_cast(this); } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/test/JsonVariant/or.cpp b/test/JsonVariant/or.cpp index 51687deaf..84349463d 100644 --- a/test/JsonVariant/or.cpp +++ b/test/JsonVariant/or.cpp @@ -51,6 +51,12 @@ TEST_CASE("JsonVariant::operator|()") { REQUIRE(result == 0); } + SECTION("double | int") { + JsonVariant variant = 42.0; + int result = variant | 666; + REQUIRE(result == 42); + } + SECTION("bool | bool") { JsonVariant variant = false; bool result = variant | true; From d9b1e7e810e678a6ca7198bf36f4ce78689c6659 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 16 Feb 2018 11:04:07 +0100 Subject: [PATCH 0013/1079] Allowed non-quoted key to contain underscores (fixes #665) --- CHANGELOG.md | 1 + .../Deserialization/JsonParser.hpp | 12 +- .../Deserialization/JsonParserImpl.hpp | 2 +- test/JsonBuffer/parseObject.cpp | 291 +++++++++--------- 4 files changed, 161 insertions(+), 145 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 276beb93b..52189081b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ HEAD ---- * Fixed `JsonVariant::operator|(int)` that returned the default value if the variant contained a double (issue #675) +* Allowed non-quoted key to contain underscores (issue #665) v5.13.0 ------- diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index 2f6e6de16..c348e759a 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -50,13 +50,13 @@ class JsonParser { inline bool parseObjectTo(JsonVariant *destination); inline bool parseStringTo(JsonVariant *destination); - static inline bool isInRange(char c, char min, char max) { + static inline bool isBetween(char c, char min, char max) { return min <= c && c <= max; } - static inline bool isLetterOrNumber(char c) { - return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') || - isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.'; + 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) { @@ -99,5 +99,5 @@ inline typename JsonParserBuilder::TParser makeParser( return JsonParserBuilder::makeParser(buffer, json, nestingLimit); } -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 76253b252..33ad42e9e 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -167,7 +167,7 @@ ArduinoJson::Internals::JsonParser::parseString() { } } else { // no quotes for (;;) { - if (!isLetterOrNumber(c)) break; + if (!canBeInNonQuotedString(c)) break; _reader.move(); str.append(c); c = _reader.current(); diff --git a/test/JsonBuffer/parseObject.cpp b/test/JsonBuffer/parseObject.cpp index 1af6bde1a..3a4067c56 100644 --- a/test/JsonBuffer/parseObject.cpp +++ b/test/JsonBuffer/parseObject.cpp @@ -8,148 +8,163 @@ TEST_CASE("JsonBuffer::parseObject()") { DynamicJsonBuffer jb; - SECTION("EmptyObject") { + SECTION("An empty object") { JsonObject& obj = jb.parseObject("{}"); REQUIRE(obj.success()); REQUIRE(obj.size() == 0); } - SECTION("MissingOpeningBrace") { - JsonObject& obj = jb.parseObject("}"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("MissingClosingBrace") { - JsonObject& obj = jb.parseObject("{"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("MissingColonAndValue") { - JsonObject& obj = jb.parseObject("{\"key\"}"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("MissingQuotesAndColonAndValue") { - JsonObject& obj = jb.parseObject("{key}"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("OneString") { - JsonObject& obj = jb.parseObject("{\"key\":\"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("OneStringSingleQuotes") { - JsonObject& obj = jb.parseObject("{'key':'value'}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("OneStringNoQuotes") { - JsonObject& obj = jb.parseObject("{key:value}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("OneStringSpaceBeforeKey") { - JsonObject& obj = jb.parseObject("{ \"key\":\"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("OneStringSpaceAfterKey") { - JsonObject& obj = jb.parseObject("{\"key\" :\"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("OneStringSpaceBeforeValue") { - JsonObject& obj = jb.parseObject("{\"key\": \"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("OneStringSpaceAfterValue") { - JsonObject& obj = jb.parseObject("{\"key\":\"value\" }"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("TwoStrings") { - JsonObject& obj = - jb.parseObject("{\"key1\":\"value1\",\"key2\":\"value2\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == "value1"); - REQUIRE(obj["key2"] == "value2"); - } - - SECTION("TwoStringsSpaceBeforeComma") { - JsonObject& obj = - jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == "value1"); - REQUIRE(obj["key2"] == "value2"); - } - - SECTION("TwoStringsSpaceAfterComma") { - JsonObject& obj = - jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == "value1"); - REQUIRE(obj["key2"] == "value2"); - } - - SECTION("EndingWithAComma") { - JsonObject& obj = jb.parseObject("{\"key1\":\"value1\",}"); - REQUIRE_FALSE(obj.success()); - REQUIRE(obj.size() == 0); - } - - SECTION("TwoIntergers") { - JsonObject& obj = jb.parseObject("{\"key1\":42,\"key2\":-42}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == 42); - REQUIRE(obj["key2"] == -42); - } - - SECTION("TwoDoubles") { - JsonObject& obj = jb.parseObject("{\"key1\":12.345,\"key2\":-7E89}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == 12.345); - REQUIRE(obj["key2"] == -7E89); - } - - SECTION("TwoBooleans") { - JsonObject& obj = jb.parseObject("{\"key1\":true,\"key2\":false}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == true); - REQUIRE(obj["key2"] == false); - } - - SECTION("TwoNulls") { - JsonObject& obj = jb.parseObject("{\"key1\":null,\"key2\":null}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"].as() == 0); - REQUIRE(obj["key2"].as() == 0); - } - - SECTION("NullForKey") { - JsonObject& obj = jb.parseObject("null:\"value\"}"); - REQUIRE_FALSE(obj.success()); + SECTION("Quotes") { + SECTION("Double quotes") { + JsonObject& obj = jb.parseObject("{\"key\":\"value\"}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("Single quotes") { + JsonObject& obj = jb.parseObject("{'key':'value'}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("No quotes") { + JsonObject& obj = jb.parseObject("{key:value}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("No quotes, allow underscore in key") { + JsonObject& obj = jb.parseObject("{_k_e_y_:42}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["_k_e_y_"] == 42); + } + } + + SECTION("Spaces") { + SECTION("Before the key") { + JsonObject& obj = jb.parseObject("{ \"key\":\"value\"}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("After the key") { + JsonObject& obj = jb.parseObject("{\"key\" :\"value\"}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("Before the value") { + JsonObject& obj = jb.parseObject("{\"key\": \"value\"}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("After the value") { + JsonObject& obj = jb.parseObject("{\"key\":\"value\" }"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("Before the colon") { + JsonObject& obj = + jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == "value1"); + REQUIRE(obj["key2"] == "value2"); + } + + SECTION("After the colon") { + JsonObject& obj = + jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == "value1"); + REQUIRE(obj["key2"] == "value2"); + } + } + + SECTION("Values types") { + SECTION("String") { + JsonObject& obj = + jb.parseObject("{\"key1\":\"value1\",\"key2\":\"value2\"}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == "value1"); + REQUIRE(obj["key2"] == "value2"); + } + + SECTION("Integer") { + JsonObject& obj = jb.parseObject("{\"key1\":42,\"key2\":-42}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == 42); + REQUIRE(obj["key2"] == -42); + } + + SECTION("Double") { + JsonObject& obj = jb.parseObject("{\"key1\":12.345,\"key2\":-7E89}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == 12.345); + REQUIRE(obj["key2"] == -7E89); + } + + SECTION("Booleans") { + JsonObject& obj = jb.parseObject("{\"key1\":true,\"key2\":false}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == true); + REQUIRE(obj["key2"] == false); + } + + SECTION("Null") { + JsonObject& obj = jb.parseObject("{\"key1\":null,\"key2\":null}"); + REQUIRE(obj.success()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"].as() == 0); + REQUIRE(obj["key2"].as() == 0); + } + } + + SECTION("Misc") { + SECTION("The opening brace is missing") { + JsonObject& obj = jb.parseObject("}"); + REQUIRE_FALSE(obj.success()); + } + + SECTION("The closing brace is missing") { + JsonObject& obj = jb.parseObject("{"); + REQUIRE_FALSE(obj.success()); + } + + SECTION("A quoted key without value") { + JsonObject& obj = jb.parseObject("{\"key\"}"); + REQUIRE_FALSE(obj.success()); + } + + SECTION("A non-quoted key without value") { + JsonObject& obj = jb.parseObject("{key}"); + REQUIRE_FALSE(obj.success()); + } + + SECTION("A dangling comma") { + JsonObject& obj = jb.parseObject("{\"key1\":\"value1\",}"); + REQUIRE_FALSE(obj.success()); + REQUIRE(obj.size() == 0); + } + + SECTION("null as a key") { + JsonObject& obj = jb.parseObject("null:\"value\"}"); + REQUIRE_FALSE(obj.success()); + } } } From 689ae5c08de46a5ef5f1e40bd6339ca3f1449099 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 19 Feb 2018 08:54:37 +0100 Subject: [PATCH 0014/1079] Set version to 5.13.1 --- CHANGELOG.md | 4 ++-- appveyor.yml | 2 +- library.json | 2 +- library.properties | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52189081b..9fb7ecf94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ ArduinoJson: change log ======================= -HEAD ----- +v5.13.1 +------- * Fixed `JsonVariant::operator|(int)` that returned the default value if the variant contained a double (issue #675) * Allowed non-quoted key to contain underscores (issue #665) diff --git a/appveyor.yml b/appveyor.yml index 9c70fe8c4..f5d79b189 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 5.13.0.{build} +version: 5.13.1.{build} environment: matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 diff --git a/library.json b/library.json index 4b326c661..eb790b928 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/bblanchon/ArduinoJson.git" }, - "version": "5.13.0", + "version": "5.13.1", "authors": { "name": "Benoit Blanchon", "url": "https://blog.benoitblanchon.fr" diff --git a/library.properties b/library.properties index a22864584..97e2f03a7 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ArduinoJson -version=5.13.0 +version=5.13.1 author=Benoit Blanchon maintainer=Benoit Blanchon sentence=An efficient and elegant JSON library for Arduino. From baf5adcf33cf7f49dfd78cf2c3e94e7394200535 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 26 Feb 2018 16:00:44 +0100 Subject: [PATCH 0015/1079] Set version to 6.0.0 --- appveyor.yml | 2 +- library.json | 2 +- library.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f5d79b189..b6b178c9b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 5.13.1.{build} +version: 6.0.0.{build} environment: matrix: - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 diff --git a/library.json b/library.json index eb790b928..4951ee337 100644 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/bblanchon/ArduinoJson.git" }, - "version": "5.13.1", + "version": "6.0.0", "authors": { "name": "Benoit Blanchon", "url": "https://blog.benoitblanchon.fr" diff --git a/library.properties b/library.properties index 97e2f03a7..b1e2aaacd 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=ArduinoJson -version=5.13.1 +version=6.0.0 author=Benoit Blanchon maintainer=Benoit Blanchon sentence=An efficient and elegant JSON library for Arduino. From 7a2a64803ab507cc7397a3215aaa90a8c9e711d4 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 26 Feb 2018 16:05:16 +0100 Subject: [PATCH 0016/1079] Don't use JsonBuffer to create or parse objects and arrays. * Added DynamicJsonArray and StaticJsonArray * Added DynamicJsonObject and StaticJsonObject * Added DynamicJsonVariant and StaticJsonVariant * Added deserializeJson() * Removed JsonBuffer::parseArray(), parseObject() and parse() * Removed JsonBuffer::createArray() and createObject() --- CHANGELOG.md | 53 +++ README.md | 11 +- examples/JsonConfigFile/JsonConfigFile.ino | 13 +- .../JsonGeneratorExample.ino | 21 +- examples/JsonHttpClient/JsonHttpClient.ino | 6 +- .../JsonParserExample/JsonParserExample.ino | 18 +- examples/JsonServer/JsonServer.ino | 9 +- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 9 +- examples/ProgmemExample/ProgmemExample.ino | 9 +- examples/StringExample/StringExample.ino | 6 +- keywords.txt | 2 - src/ArduinoJson.hpp | 10 +- src/ArduinoJson/Data/List.hpp | 10 +- .../Deserialization/JsonParser.hpp | 12 +- .../Deserialization/JsonParserImpl.hpp | 54 +-- src/ArduinoJson/DynamicJsonArray.hpp | 27 ++ src/ArduinoJson/DynamicJsonBuffer.hpp | 9 +- src/ArduinoJson/DynamicJsonObject.hpp | 27 ++ src/ArduinoJson/DynamicJsonVariant.hpp | 40 ++ src/ArduinoJson/JsonArray.hpp | 19 +- src/ArduinoJson/JsonArrayImpl.hpp | 16 +- src/ArduinoJson/JsonBuffer.hpp | 14 +- src/ArduinoJson/JsonBufferBase.hpp | 127 ----- src/ArduinoJson/JsonBufferImpl.hpp | 17 - src/ArduinoJson/JsonObject.hpp | 15 +- src/ArduinoJson/JsonObjectImpl.hpp | 14 +- src/ArduinoJson/JsonVariant.hpp | 12 +- src/ArduinoJson/StaticJsonArray.hpp | 27 ++ src/ArduinoJson/StaticJsonBuffer.hpp | 15 +- src/ArduinoJson/StaticJsonObject.hpp | 27 ++ src/ArduinoJson/StaticJsonVariant.hpp | 39 ++ src/ArduinoJson/TypeTraits/Max.hpp | 24 + src/ArduinoJson/deserializeJson.hpp | 40 ++ test/CMakeLists.txt | 4 +- test/DynamicJsonBuffer/CMakeLists.txt | 2 - test/DynamicJsonBuffer/createArray.cpp | 28 -- test/DynamicJsonBuffer/createObject.cpp | 22 - test/DynamicJsonBuffer/no_memory.cpp | 30 +- test/IntegrationTests/gbathree.cpp | 7 +- test/IntegrationTests/round_trip.cpp | 8 +- test/JsonArray/add.cpp | 21 +- test/JsonArray/basics.cpp | 3 +- test/JsonArray/copyFrom.cpp | 12 +- test/JsonArray/copyTo.cpp | 11 +- test/JsonArray/iterator.cpp | 4 +- test/JsonArray/prettyPrintTo.cpp | 3 +- test/JsonArray/printTo.cpp | 10 +- test/JsonArray/remove.cpp | 3 +- test/JsonArray/set.cpp | 17 +- test/JsonArray/size.cpp | 3 +- test/JsonArray/subscript.cpp | 17 +- test/JsonBuffer/CMakeLists.txt | 14 - test/JsonBuffer/nested.cpp | 63 --- test/JsonBuffer/parseArray.cpp | 318 ------------- test/JsonBuffer/parseObject.cpp | 170 ------- test/JsonObject/basics.cpp | 3 +- test/JsonObject/containsKey.cpp | 3 +- test/JsonObject/get.cpp | 3 +- test/JsonObject/iterator.cpp | 3 +- test/JsonObject/prettyPrintTo.cpp | 3 +- test/JsonObject/printTo.cpp | 16 +- test/JsonObject/remove.cpp | 6 +- test/JsonObject/set.cpp | 31 +- test/JsonObject/size.cpp | 3 +- test/JsonObject/subscript.cpp | 25 +- test/JsonParser/CMakeLists.txt | 15 + test/JsonParser/JsonArray.cpp | 346 ++++++++++++++ test/JsonParser/JsonObject.cpp | 197 ++++++++ .../parse.cpp => JsonParser/JsonVariant.cpp} | 54 ++- test/JsonParser/StaticJsonArray.cpp | 79 ++++ test/JsonParser/StaticJsonObject.cpp | 69 +++ .../nestingLimit.cpp | 8 +- test/JsonVariant/as.cpp | 19 +- test/JsonVariant/compare.cpp | 27 +- test/JsonVariant/copy.cpp | 5 +- test/JsonVariant/is.cpp | 3 +- test/JsonVariant/set_get.cpp | 5 +- test/JsonVariant/subscript.cpp | 15 +- test/JsonVariant/success.cpp | 8 +- test/Misc/deprecated.cpp | 22 +- test/Misc/std_stream.cpp | 30 +- test/Misc/std_string.cpp | 445 +++++++++--------- test/Misc/unsigned_char.cpp | 84 ++-- test/Misc/vla.cpp | 86 ++-- test/StaticJsonBuffer/CMakeLists.txt | 4 - test/StaticJsonBuffer/createArray.cpp | 45 -- test/StaticJsonBuffer/createObject.cpp | 56 --- test/StaticJsonBuffer/parseArray.cpp | 71 --- test/StaticJsonBuffer/parseObject.cpp | 62 --- 89 files changed, 1647 insertions(+), 1726 deletions(-) create mode 100644 src/ArduinoJson/DynamicJsonArray.hpp create mode 100644 src/ArduinoJson/DynamicJsonObject.hpp create mode 100644 src/ArduinoJson/DynamicJsonVariant.hpp delete mode 100644 src/ArduinoJson/JsonBufferBase.hpp delete mode 100644 src/ArduinoJson/JsonBufferImpl.hpp create mode 100644 src/ArduinoJson/StaticJsonArray.hpp create mode 100644 src/ArduinoJson/StaticJsonObject.hpp create mode 100644 src/ArduinoJson/StaticJsonVariant.hpp create mode 100644 src/ArduinoJson/TypeTraits/Max.hpp create mode 100644 src/ArduinoJson/deserializeJson.hpp delete mode 100644 test/DynamicJsonBuffer/createArray.cpp delete mode 100644 test/DynamicJsonBuffer/createObject.cpp delete mode 100644 test/JsonBuffer/CMakeLists.txt delete mode 100644 test/JsonBuffer/nested.cpp delete mode 100644 test/JsonBuffer/parseArray.cpp delete mode 100644 test/JsonBuffer/parseObject.cpp create mode 100644 test/JsonParser/CMakeLists.txt create mode 100644 test/JsonParser/JsonArray.cpp create mode 100644 test/JsonParser/JsonObject.cpp rename test/{JsonBuffer/parse.cpp => JsonParser/JsonVariant.cpp} (56%) create mode 100644 test/JsonParser/StaticJsonArray.cpp create mode 100644 test/JsonParser/StaticJsonObject.cpp rename test/{JsonBuffer => JsonParser}/nestingLimit.cpp (87%) delete mode 100644 test/StaticJsonBuffer/createArray.cpp delete mode 100644 test/StaticJsonBuffer/createObject.cpp delete mode 100644 test/StaticJsonBuffer/parseArray.cpp delete mode 100644 test/StaticJsonBuffer/parseObject.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fb7ecf94..84e7ddfba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,59 @@ ArduinoJson: change log ======================= +HEAD +---- + +* Added DynamicJsonArray and StaticJsonArray +* Added DynamicJsonObject and StaticJsonObject +* Added DynamicJsonVariant and StaticJsonVariant +* Added deserializeJson() +* Removed JsonBuffer::parseArray(), parseObject() and parse() +* Removed JsonBuffer::createArray() and createObject() + +> ### BREAKING CHANGES +> +> #### Deserialization +> +> Old code: +> +> ```c++ +> DynamicJsonBuffer jb; +> JsonObject& obj = jb.parseObject(json); +> if (obj.success()) { +> +> } +> ``` +> +> New code: +> +> ```c++ +> DynamicJsonObject obj; +> bool success = deserializeJson(obj, json); +> if (success) { +> +> } +> ``` +> +> #### Serialization +> +> Old code: +> +> ```c++ +> DynamicJsonBuffer jb; +> JsonObject& obj = jb.createObject(); +> obj["key"] = "value"; +> obj.printTo(Serial); +> ``` +> +> New code: +> +> ```c++ +> DynamicJsonObject obj; +> obj["key"] = "value"; +> obj.printTo(Serial); +> ``` + v5.13.1 ------- diff --git a/README.md b/README.md index f9e08ff89..7a398aca7 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,8 @@ Here is a program that parses a JSON document with ArduinoJson. ```c++ char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; -StaticJsonBuffer<200> jsonBuffer; - -JsonObject& root = jsonBuffer.parseObject(json); +DynamicJsonObject root; +derserializeJson(root, json); const char* sensor = root["sensor"]; long time = root["time"]; @@ -76,9 +75,7 @@ See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_ Here is a program that generates a JSON document with ArduinoJson: ```c++ -StaticJsonBuffer<200> jsonBuffer; - -JsonObject& root = jsonBuffer.createObject(); +DynamicJsonObject root; root["sensor"] = "gps"; root["time"] = 1351824120; @@ -107,4 +104,4 @@ The documentation is available on [arduinojson.org](https://arduinojson.org/?utm Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)! What? You don't like it but you *love* it? -We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time! \ No newline at end of file +We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time! diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index ce6dca3e6..299447fc8 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -32,12 +32,12 @@ void loadConfiguration(const char *filename, Config &config) { // Allocate the memory pool on the stack. // Don't forget to change the capacity to match your JSON document. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonBuffer<512> jsonBuffer; + StaticJsonObject<512> root; // Parse the root object - JsonObject &root = jsonBuffer.parseObject(file); + bool success = deserializeJson(root, file); - if (!root.success()) + if (!success) Serial.println(F("Failed to read file, using default configuration")); // Copy values from the JsonObject to the Config @@ -65,10 +65,7 @@ void saveConfiguration(const char *filename, const Config &config) { // Allocate the memory pool on the stack // Don't forget to change the capacity to match your JSON document. // Use https://arduinojson.org/assistant/ to compute the capacity. - StaticJsonBuffer<256> jsonBuffer; - - // Parse the root object - JsonObject &root = jsonBuffer.createObject(); + StaticJsonObject<256> root; // Set the values root["hostname"] = config.hostname; @@ -141,4 +138,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a case study of a project that has // a complex configuration with nested members. // Contrary to this example, the project in the book uses the SPIFFS filesystem. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index fad41ef2f..4903b1144 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -11,24 +11,17 @@ void setup() { Serial.begin(9600); while (!Serial) continue; - // Memory pool for JSON object tree. + // Root JSON object // - // Inside the brackets, 200 is the size of the 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. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonBuffer<200> jsonBuffer; + StaticJsonObject<200> root; - // StaticJsonBuffer allocates memory on the stack, it can be - // replaced by DynamicJsonBuffer which allocates in the heap. + // StaticJsonObject allocates memory on the stack, it can be + // replaced by DynamicJsonObject which allocates in the heap. // - // DynamicJsonBuffer jsonBuffer(200); - - // Create the root of the object tree. - // - // It's a reference to the JsonObject, the actual bytes are inside the - // JsonBuffer with all the other nodes of the object tree. - // Memory is freed when jsonBuffer goes out of scope. - JsonObject& root = jsonBuffer.createObject(); + // DynamicJsonObject root(200); // Add values in the object // @@ -78,4 +71,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on serialization. // It begins with a simple example, like the one above, and then adds more // features like serializing directly to a file or an HTTP request. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index 6e5c05efc..8ce57a7f7 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -73,10 +73,10 @@ void setup() { // Allocate JsonBuffer // Use arduinojson.org/assistant to compute the capacity. const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; - DynamicJsonBuffer jsonBuffer(capacity); + DynamicJsonObject root(capacity); // Parse JSON object - JsonObject& root = jsonBuffer.parseObject(client); + bool success = deserializeJson(root, client); if (!root.success()) { Serial.println(F("Parsing failed!")); return; @@ -109,4 +109,4 @@ void loop() { // showing how to parse the response from Yahoo Weather. In the last chapter, // it shows how to parse the huge documents from OpenWeatherMap // and Weather Underground. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index a9b3ee912..6c8063a5f 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -11,17 +11,17 @@ void setup() { Serial.begin(9600); while (!Serial) continue; - // Memory pool for JSON object tree. + // Root JSON object // - // Inside the brackets, 200 is the size of the 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. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonBuffer<200> jsonBuffer; + StaticJsonObject<200> root; - // StaticJsonBuffer allocates memory on the stack, it can be - // replaced by DynamicJsonBuffer which allocates in the heap. + // StaticJsonObject allocates memory on the stack, it can be + // replaced by DynamicJsonObject which allocates in the heap. // - // DynamicJsonBuffer jsonBuffer(200); + // DynamicJsonObject root(200); // JSON input string. // @@ -36,10 +36,10 @@ void setup() { // 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. - JsonObject& root = jsonBuffer.parseObject(json); + bool success = deserializeJson(root, json); // Test if parsing succeeds. - if (!root.success()) { + if (!success) { Serial.println("parseObject() failed"); return; } @@ -75,4 +75,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on deserialization. // It begins with a simple example, like the one above, and then adds more // features like deserializing directly from a file or an HTTP request. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index 229e289ac..ded6d5aba 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -51,12 +51,9 @@ void loop() { // Read the request (we ignore the content in this example) while (client.available()) client.read(); - // Allocate JsonBuffer + // Allocate the root JsonObject // Use arduinojson.org/assistant to compute the capacity. - StaticJsonBuffer<500> jsonBuffer; - - // Create the root object - JsonObject& root = jsonBuffer.createObject(); + StaticJsonObject<500> root; // Create the "analog" array JsonArray& analogValues = root.createNestedArray("analog"); @@ -106,4 +103,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on serialization. // It begins with a simple example, then adds more features like serializing // directly to a file or an HTTP client. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index eb9f19a66..3f912c68f 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -43,12 +43,9 @@ void setup() { } void loop() { - // Allocate JsonBuffer + // Allocate the root JsonObject // Use arduinojson.org/assistant to compute the capacity. - StaticJsonBuffer<500> jsonBuffer; - - // Create the root object - JsonObject& root = jsonBuffer.createObject(); + StaticJsonObject<500> root; // Create the "analog" array JsonArray& analogValues = root.createNestedArray("analog"); @@ -98,4 +95,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a tutorial on serialization. // It begins with a simple example, then adds more features like serializing // directly to a file or any stream. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index 15be8ed1c..87740bb42 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -14,14 +14,13 @@ void setup() { #ifdef PROGMEM // <- check that Flash strings are supported - DynamicJsonBuffer jsonBuffer; + DynamicJsonObject root; // You can use a Flash String as your JSON input. // WARNING: the content of the Flash String will be duplicated in the // JsonBuffer. - JsonObject& root = - jsonBuffer.parseObject(F("{\"sensor\":\"gps\",\"time\":1351824120," - "\"data\":[48.756080,2.302038]}")); + deserializeJson(root, F("{\"sensor\":\"gps\",\"time\":1351824120," + "\"data\":[48.756080,2.302038]}")); // You can use a Flash String to get an element of a JsonObject // No duplication is done. @@ -67,4 +66,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a quick C++ course that explains // how your microcontroller stores strings in memory. It also tells why you // should not abuse Flash strings with ArduinoJson. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index d5994ffb2..1ffed4581 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -11,13 +11,13 @@ #include void setup() { - DynamicJsonBuffer jsonBuffer; + DynamicJsonObject root; // You can use a String as your JSON input. // WARNING: the content of the String will be duplicated in the JsonBuffer. String input = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; - JsonObject& root = jsonBuffer.parseObject(input); + deserializeJson(root, input); // You can use a String to get an element of a JsonObject // No duplication is done. @@ -71,4 +71,4 @@ void loop() { // The book "Mastering ArduinoJson" contains a quick C++ course that explains // how your microcontroller stores strings in memory. On several occasions, it // shows how you can avoid String in your program. -// Please check it out at: https://arduinojson.org/book/ \ No newline at end of file +// Please check it out at: https://arduinojson.org/book/ diff --git a/keywords.txt b/keywords.txt index 833cddb73..1bb6f1405 100644 --- a/keywords.txt +++ b/keywords.txt @@ -4,10 +4,8 @@ JsonVariant KEYWORD1 StaticJsonBuffer KEYWORD1 DynamicJsonBuffer KEYWORD1 add KEYWORD2 -createArray KEYWORD2 createNestedArray KEYWORD2 createNestedObject KEYWORD2 -createObject KEYWORD2 parseArray KEYWORD2 parseObject KEYWORD2 prettyPrintTo KEYWORD2 diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 445a2c8a6..83830e2d9 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -4,14 +4,18 @@ #pragma once +#include "ArduinoJson/DynamicJsonArray.hpp" #include "ArduinoJson/DynamicJsonBuffer.hpp" -#include "ArduinoJson/JsonArray.hpp" -#include "ArduinoJson/JsonObject.hpp" +#include "ArduinoJson/DynamicJsonObject.hpp" +#include "ArduinoJson/DynamicJsonVariant.hpp" +#include "ArduinoJson/StaticJsonArray.hpp" #include "ArduinoJson/StaticJsonBuffer.hpp" +#include "ArduinoJson/StaticJsonObject.hpp" +#include "ArduinoJson/StaticJsonVariant.hpp" +#include "ArduinoJson/deserializeJson.hpp" #include "ArduinoJson/Deserialization/JsonParserImpl.hpp" #include "ArduinoJson/JsonArrayImpl.hpp" -#include "ArduinoJson/JsonBufferImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp" #include "ArduinoJson/JsonVariantImpl.hpp" #include "ArduinoJson/Serialization/JsonSerializerImpl.hpp" diff --git a/src/ArduinoJson/Data/List.hpp b/src/ArduinoJson/Data/List.hpp index 506308cc3..f1e9b07b4 100644 --- a/src/ArduinoJson/Data/List.hpp +++ b/src/ArduinoJson/Data/List.hpp @@ -27,7 +27,7 @@ class List { // When buffer is NULL, the List is not able to grow and success() returns // false. This is used to identify bad memory allocations and parsing // failures. - explicit List(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} + explicit List(JsonBuffer *buf) : _buffer(buf), _firstNode(NULL) {} // Returns true if the object is valid // Would return false in the following situation: @@ -84,11 +84,15 @@ class List { } } + JsonBuffer &buffer() const { + return *_buffer; + } + protected: JsonBuffer *_buffer; private: node_type *_firstNode; }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index c348e759a..b30abddc0 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -24,15 +24,9 @@ class JsonParser { _reader(reader), _writer(writer), _nestingLimit(nestingLimit) {} - - JsonArray &parseArray(); - JsonObject &parseObject(); - - JsonVariant parseVariant() { - JsonVariant result; - parseAnythingTo(&result); - return result; - } + bool parse(JsonArray &destination); + bool parse(JsonObject &destination); + bool parse(JsonVariant &destination); private: JsonParser &operator=(const JsonParser &); // non-copiable diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 33ad42e9e..19ca8b7a2 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -46,11 +46,8 @@ ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( } template -inline ArduinoJson::JsonArray & -ArduinoJson::Internals::JsonParser::parseArray() { - // Create an empty array - JsonArray &array = _buffer->createArray(); - +inline bool ArduinoJson::Internals::JsonParser::parse( + JsonArray &array) { // Check opening braket if (!eat('[')) goto ERROR_MISSING_BRACKET; if (eat(']')) goto SUCCESS_EMPTY_ARRAY; @@ -69,31 +66,18 @@ ArduinoJson::Internals::JsonParser::parseArray() { SUCCESS_EMPTY_ARRAY: SUCCES_NON_EMPTY_ARRAY: - return array; + return true; ERROR_INVALID_VALUE: ERROR_MISSING_BRACKET: ERROR_MISSING_COMMA: ERROR_NO_MEMORY: - return JsonArray::invalid(); -} - -template -inline bool ArduinoJson::Internals::JsonParser::parseArrayTo( - JsonVariant *destination) { - JsonArray &array = parseArray(); - if (!array.success()) return false; - - *destination = array; - return true; + return false; } template -inline ArduinoJson::JsonObject & -ArduinoJson::Internals::JsonParser::parseObject() { - // Create an empty object - JsonObject &object = _buffer->createObject(); - +inline bool ArduinoJson::Internals::JsonParser::parse( + JsonObject &object) { // Check opening brace if (!eat('{')) goto ERROR_MISSING_BRACE; if (eat('}')) goto SUCCESS_EMPTY_OBJECT; @@ -117,7 +101,7 @@ ArduinoJson::Internals::JsonParser::parseObject() { SUCCESS_EMPTY_OBJECT: SUCCESS_NON_EMPTY_OBJECT: - return object; + return true; ERROR_INVALID_KEY: ERROR_INVALID_VALUE: @@ -125,17 +109,31 @@ ArduinoJson::Internals::JsonParser::parseObject() { ERROR_MISSING_COLON: ERROR_MISSING_COMMA: ERROR_NO_MEMORY: - return JsonObject::invalid(); + return false; } template -inline bool ArduinoJson::Internals::JsonParser::parseObjectTo( +inline bool ArduinoJson::Internals::JsonParser::parse( + JsonVariant &variant) { + return parseAnythingTo(&variant); +} + +template +inline bool ArduinoJson::Internals::JsonParser::parseArrayTo( JsonVariant *destination) { - JsonObject &object = parseObject(); - if (!object.success()) return false; + JsonArray *array = new (_buffer) JsonArray(_buffer); + if (!array) return false; + *destination = array; + return parse(*array); +} +template +inline bool ArduinoJson::Internals::JsonParser::parseObjectTo( + JsonVariant *destination) { + JsonObject *object = new (_buffer) JsonObject(_buffer); + if (!object) return false; *destination = object; - return true; + return parse(*object); } template diff --git a/src/ArduinoJson/DynamicJsonArray.hpp b/src/ArduinoJson/DynamicJsonArray.hpp new file mode 100644 index 000000000..216402f10 --- /dev/null +++ b/src/ArduinoJson/DynamicJsonArray.hpp @@ -0,0 +1,27 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "DynamicJsonBuffer.hpp" +#include "JsonArray.hpp" + +namespace ArduinoJson { +class DynamicJsonArray : public JsonArray { + DynamicJsonBuffer _buffer; + + public: + DynamicJsonArray() : JsonArray(&_buffer) {} + DynamicJsonArray(size_t capacity) + : JsonArray(&_buffer), _buffer(capacity - sizeof(JsonArray)) {} + + size_t memoryUsage() const { + return _buffer.size() + sizeof(JsonArray); + } + + DynamicJsonBuffer& buffer() { + return _buffer; + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonBuffer.hpp b/src/ArduinoJson/DynamicJsonBuffer.hpp index bdbd5dd90..9570e489a 100644 --- a/src/ArduinoJson/DynamicJsonBuffer.hpp +++ b/src/ArduinoJson/DynamicJsonBuffer.hpp @@ -4,7 +4,7 @@ #pragma once -#include "JsonBufferBase.hpp" +#include "JsonBuffer.hpp" #include @@ -31,8 +31,7 @@ class DefaultAllocator { }; template -class DynamicJsonBufferBase - : public JsonBufferBase > { +class DynamicJsonBufferBase : public JsonBuffer { struct Block; struct EmptyBlock { Block* next; @@ -152,7 +151,7 @@ class DynamicJsonBufferBase Block* _head; size_t _nextBlockCapacity; }; -} +} // namespace Internals #if defined(__clang__) #pragma clang diagnostic pop @@ -167,4 +166,4 @@ class DynamicJsonBufferBase // more suitable for embedded systems. typedef Internals::DynamicJsonBufferBase DynamicJsonBuffer; -} +} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonObject.hpp b/src/ArduinoJson/DynamicJsonObject.hpp new file mode 100644 index 000000000..c602e7915 --- /dev/null +++ b/src/ArduinoJson/DynamicJsonObject.hpp @@ -0,0 +1,27 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "DynamicJsonBuffer.hpp" +#include "JsonObject.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; + } + + size_t memoryUsage() const { + return _buffer.size() + sizeof(JsonObject); + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonVariant.hpp b/src/ArduinoJson/DynamicJsonVariant.hpp new file mode 100644 index 000000000..32e228896 --- /dev/null +++ b/src/ArduinoJson/DynamicJsonVariant.hpp @@ -0,0 +1,40 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "DynamicJsonBuffer.hpp" +#include "JsonVariant.hpp" + +namespace ArduinoJson { + +class DynamicJsonVariant : public JsonVariant { + DynamicJsonBuffer _buffer; + + public: + DynamicJsonVariant() : JsonVariant() {} + + template + DynamicJsonVariant& operator=(const T& value) { + _buffer.clear(); + JsonVariant::operator=(value); + return *this; + } + + template + DynamicJsonVariant& operator=(const T* value) { + _buffer.clear(); + JsonVariant::operator=(value); + return *this; + } + + DynamicJsonBuffer& buffer() { + return _buffer; + } + + size_t memoryUsage() const { + return _buffer.size() + sizeof(JsonVariant); + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 2acd2a1a5..6ca712e2d 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -30,23 +30,14 @@ namespace Internals { class JsonArraySubscript; } -// An array of JsonVariant. -// -// The constructor is private, instances must be created via -// JsonBuffer::createArray() or JsonBuffer::parseArray(). -// A JsonArray can be serialized to a JSON string via JsonArray::printTo(). -// It can also be deserialized from a JSON string via JsonBuffer::parseArray(). class JsonArray : public Internals::JsonPrintable, public Internals::ReferenceType, public Internals::NonCopyable, public Internals::List, public Internals::JsonBufferAllocated { public: - // Create an empty JsonArray attached to the specified JsonBuffer. - // You should not call this constructor directly. - // Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray(). - explicit JsonArray(JsonBuffer *buffer) throw() - : Internals::List(buffer) {} + explicit JsonArray(JsonBuffer *buf) throw() + : Internals::List(buf) {} // Gets the value at the specified index const Internals::JsonArraySubscript operator[](size_t index) const; @@ -119,11 +110,9 @@ class JsonArray : public Internals::JsonPrintable, } // Creates a JsonArray and adds a reference at the end of the array. - // It's a shortcut for JsonBuffer::createArray() and JsonArray::add() JsonArray &createNestedArray(); // Creates a JsonObject and adds a reference at the end of the array. - // It's a shortcut for JsonBuffer::createObject() and JsonArray::add() JsonObject &createNestedObject(); // Removes element at specified index. @@ -223,5 +212,5 @@ struct JsonVariantDefault { return JsonArray::invalid(); } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonArrayImpl.hpp b/src/ArduinoJson/JsonArrayImpl.hpp index 924b7ea7a..d84a84764 100644 --- a/src/ArduinoJson/JsonArrayImpl.hpp +++ b/src/ArduinoJson/JsonArrayImpl.hpp @@ -11,16 +11,18 @@ namespace ArduinoJson { inline JsonArray &JsonArray::createNestedArray() { - if (!_buffer) return JsonArray::invalid(); - JsonArray &array = _buffer->createArray(); + JsonArray *array = new (_buffer) JsonArray(_buffer); + if (!array) return JsonArray::invalid(); + add(array); - return array; + return *array; } inline JsonObject &JsonArray::createNestedObject() { - if (!_buffer) return JsonObject::invalid(); - JsonObject &object = _buffer->createObject(); + JsonObject *object = new (_buffer) JsonObject(_buffer); + if (!object) return JsonObject::invalid(); + add(object); - return object; -} + return *object; } +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonBuffer.hpp b/src/ArduinoJson/JsonBuffer.hpp index 26101e086..f49f423ce 100644 --- a/src/ArduinoJson/JsonBuffer.hpp +++ b/src/ArduinoJson/JsonBuffer.hpp @@ -24,18 +24,6 @@ class JsonObject; // fixed memory allocation. class JsonBuffer : Internals::NonCopyable { public: - // Allocates an empty JsonArray. - // - // Returns a reference to the new JsonArray or JsonArray::invalid() if the - // allocation fails. - JsonArray &createArray(); - - // Allocates an empty JsonObject. - // - // Returns a reference to the new JsonObject or JsonObject::invalid() if the - // allocation fails. - JsonObject &createObject(); - // Duplicates a string // // const char* strdup(TValue); @@ -75,4 +63,4 @@ class JsonBuffer : Internals::NonCopyable { #endif } }; -} +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonBufferBase.hpp b/src/ArduinoJson/JsonBufferBase.hpp deleted file mode 100644 index 1e771bfdb..000000000 --- a/src/ArduinoJson/JsonBufferBase.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "Deserialization/JsonParser.hpp" - -namespace ArduinoJson { -namespace Internals { -template -class JsonBufferBase : public JsonBuffer { - public: - // Allocates and populate a JsonArray from a JSON string. - // - // The First argument is a pointer to the JSON string, the memory must be - // writable - // because the parser will insert null-terminators and replace escaped chars. - // - // The second argument set the nesting limit - // - // Returns a reference to the new JsonObject or JsonObject::invalid() if the - // allocation fails. - // With this overload, the JsonBuffer will make a copy of the string - // - // JsonArray& parseArray(TString); - // TString = const std::string&, const String& - template - typename Internals::EnableIf::value, - JsonArray &>::type - parseArray(const TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseArray(); - } - // - // JsonArray& parseArray(TString); - // TString = const char*, const char[N], const FlashStringHelper* - template - JsonArray &parseArray( - TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseArray(); - } - // - // JsonArray& parseArray(TString); - // TString = std::istream&, Stream& - template - JsonArray &parseArray( - TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseArray(); - } - - // Allocates and populate a JsonObject from a JSON string. - // - // The First argument is a pointer to the JSON string, the memory must be - // writable - // because the parser will insert null-terminators and replace escaped chars. - // - // The second argument set the nesting limit - // - // Returns a reference to the new JsonObject or JsonObject::invalid() if the - // allocation fails. - // - // JsonObject& parseObject(TString); - // TString = const std::string&, const String& - template - typename Internals::EnableIf::value, - JsonObject &>::type - parseObject(const TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseObject(); - } - // - // JsonObject& parseObject(TString); - // TString = const char*, const char[N], const FlashStringHelper* - template - JsonObject &parseObject( - TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseObject(); - } - // - // JsonObject& parseObject(TString); - // TString = std::istream&, Stream& - template - JsonObject &parseObject( - TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseObject(); - } - - // Generalized version of parseArray() and parseObject(), also works for - // integral types. - // - // JsonVariant parse(TString); - // TString = const std::string&, const String& - template - typename Internals::EnableIf::value, - JsonVariant>::type - parse(const TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseVariant(); - } - // - // JsonVariant parse(TString); - // TString = const char*, const char[N], const FlashStringHelper* - template - JsonVariant parse(TString *json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseVariant(); - } - // - // JsonVariant parse(TString); - // TString = std::istream&, Stream& - template - JsonVariant parse(TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(that(), json, nestingLimit).parseVariant(); - } - - protected: - ~JsonBufferBase() {} - - private: - TDerived *that() { - return static_cast(this); - } -}; -} -} diff --git a/src/ArduinoJson/JsonBufferImpl.hpp b/src/ArduinoJson/JsonBufferImpl.hpp deleted file mode 100644 index cdea374bb..000000000 --- a/src/ArduinoJson/JsonBufferImpl.hpp +++ /dev/null @@ -1,17 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "Deserialization/JsonParser.hpp" - -inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() { - JsonArray *ptr = new (this) JsonArray(this); - return ptr ? *ptr : JsonArray::invalid(); -} - -inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() { - JsonObject *ptr = new (this) JsonObject(this); - return ptr ? *ptr : JsonObject::invalid(); -} diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index c03bfa51d..1802e59f0 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -31,12 +31,6 @@ template class JsonObjectSubscript; } -// A dictionary of JsonVariant indexed by string (char*) -// -// The constructor is private, instances must be created via -// JsonBuffer::createObject() or JsonBuffer::parseObject(). -// A JsonObject can be serialized to a JSON string via JsonObject::printTo(). -// It can also be deserialized from a JSON string via JsonBuffer::parseObject(). class JsonObject : public Internals::JsonPrintable, public Internals::ReferenceType, public Internals::NonCopyable, @@ -45,9 +39,8 @@ class JsonObject : public Internals::JsonPrintable, public: // Create an empty JsonArray attached to the specified JsonBuffer. // You should not use this constructor directly. - // Instead, use JsonBuffer::createObject() or JsonBuffer.parseObject(). - explicit JsonObject(JsonBuffer* buffer) throw() - : Internals::List(buffer) {} + explicit JsonObject(JsonBuffer* buf) throw() + : Internals::List(buf) {} // Gets or sets the value associated with the specified key. // @@ -318,5 +311,5 @@ struct JsonVariantDefault { return JsonObject::invalid(); } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonObjectImpl.hpp b/src/ArduinoJson/JsonObjectImpl.hpp index e7689b507..eabed38a1 100644 --- a/src/ArduinoJson/JsonObjectImpl.hpp +++ b/src/ArduinoJson/JsonObjectImpl.hpp @@ -12,17 +12,17 @@ namespace ArduinoJson { template inline JsonArray &JsonObject::createNestedArray_impl(TStringRef key) { - if (!_buffer) return JsonArray::invalid(); - JsonArray &array = _buffer->createArray(); + JsonArray *array = new (_buffer) JsonArray(_buffer); + if (!array) return JsonArray::invalid(); set(key, array); - return array; + return *array; } template inline JsonObject &JsonObject::createNestedObject_impl(TStringRef key) { - if (!_buffer) return JsonObject::invalid(); - JsonObject &object = _buffer->createObject(); + JsonObject *object = new (_buffer) JsonObject(_buffer); + if (!object) return JsonObject::invalid(); set(key, object); - return object; -} + return *object; } +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index 8326cbe86..e5cb91486 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -134,6 +134,16 @@ class JsonVariant : public Internals::JsonVariantBase { // if the variant is converted back to a JsonObject& JsonVariant(const JsonObject &object); + JsonVariant(JsonArray *array) { + _content.asArray = array; + _type = Internals::JSON_ARRAY; + } + + JsonVariant(JsonObject *object) { + _content.asObject = object; + _type = Internals::JSON_OBJECT; + } + // Get the variant as the specified type. // // char as() const; @@ -352,4 +362,4 @@ DEPRECATED("Decimal places are ignored, use the double value instead") inline JsonVariant double_with_n_digits(double value, uint8_t) { return JsonVariant(value); } -} +} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonArray.hpp b/src/ArduinoJson/StaticJsonArray.hpp new file mode 100644 index 000000000..6ace2d694 --- /dev/null +++ b/src/ArduinoJson/StaticJsonArray.hpp @@ -0,0 +1,27 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "JsonArray.hpp" +#include "StaticJsonBuffer.hpp" + +namespace ArduinoJson { + +template +class StaticJsonArray : public JsonArray { + StaticJsonBuffer _buffer; + + public: + StaticJsonArray() : JsonArray(&_buffer) {} + + size_t memoryUsage() const { + return _buffer.size() + sizeof(JsonArray); + } + + Internals::StaticJsonBufferBase& buffer() { + return _buffer; + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonBuffer.hpp b/src/ArduinoJson/StaticJsonBuffer.hpp index 267d9d018..dd13dfa9d 100644 --- a/src/ArduinoJson/StaticJsonBuffer.hpp +++ b/src/ArduinoJson/StaticJsonBuffer.hpp @@ -4,12 +4,13 @@ #pragma once -#include "JsonBufferBase.hpp" +#include "JsonBuffer.hpp" +#include "TypeTraits/Max.hpp" namespace ArduinoJson { namespace Internals { -class StaticJsonBufferBase : public JsonBufferBase { +class StaticJsonBufferBase : public JsonBuffer { public: class String { public: @@ -91,7 +92,7 @@ class StaticJsonBufferBase : public JsonBufferBase { size_t _capacity; size_t _size; }; -} +} // namespace Internals #if defined(__clang__) #pragma clang diagnostic push @@ -108,14 +109,16 @@ class StaticJsonBufferBase : public JsonBufferBase { // bytes. template class StaticJsonBuffer : public Internals::StaticJsonBufferBase { + static const size_t ACTUAL_CAPACITY = Internals::Max<1, CAPACITY>::value; + public: explicit StaticJsonBuffer() - : Internals::StaticJsonBufferBase(_buffer, CAPACITY) {} + : Internals::StaticJsonBufferBase(_buffer, ACTUAL_CAPACITY) {} private: - char _buffer[CAPACITY]; + char _buffer[ACTUAL_CAPACITY]; }; -} +} // namespace ArduinoJson #if defined(__clang__) #pragma clang diagnostic pop diff --git a/src/ArduinoJson/StaticJsonObject.hpp b/src/ArduinoJson/StaticJsonObject.hpp new file mode 100644 index 000000000..c46a97a38 --- /dev/null +++ b/src/ArduinoJson/StaticJsonObject.hpp @@ -0,0 +1,27 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "JsonObject.hpp" +#include "StaticJsonBuffer.hpp" + +namespace ArduinoJson { + +template +class StaticJsonObject : public JsonObject { + StaticJsonBuffer _buffer; + + public: + StaticJsonObject() : JsonObject(&_buffer) {} + + size_t memoryUsage() const { + return _buffer.size() + sizeof(JsonObject); + } + + Internals::StaticJsonBufferBase& buffer() { + return _buffer; + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonVariant.hpp b/src/ArduinoJson/StaticJsonVariant.hpp new file mode 100644 index 000000000..e565b1850 --- /dev/null +++ b/src/ArduinoJson/StaticJsonVariant.hpp @@ -0,0 +1,39 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "JsonVariant.hpp" +#include "StaticJsonBuffer.hpp" + +namespace ArduinoJson { + +template +class StaticJsonVariant : public JsonVariant { + StaticJsonBuffer _buffer; + + public: + template + StaticJsonVariant& operator=(const T& value) { + _buffer.clear(); + JsonVariant::operator=(value); + return *this; + } + + template + StaticJsonVariant& operator=(const T* value) { + _buffer.clear(); + JsonVariant::operator=(value); + return *this; + } + + Internals::StaticJsonBufferBase& buffer() { + return _buffer; + } + + size_t memoryUsage() const { + return _buffer.size() + sizeof(JsonVariant); + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/Max.hpp b/src/ArduinoJson/TypeTraits/Max.hpp new file mode 100644 index 000000000..e046910d4 --- /dev/null +++ b/src/ArduinoJson/TypeTraits/Max.hpp @@ -0,0 +1,24 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +// A meta-function that returns the highest value +template Y)> +struct Max {}; + +template +struct Max { + static const size_t value = X; +}; + +template +struct Max { + static const size_t value = Y; +}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp new file mode 100644 index 000000000..c192c32bc --- /dev/null +++ b/src/ArduinoJson/deserializeJson.hpp @@ -0,0 +1,40 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "Deserialization/JsonParser.hpp" + +namespace ArduinoJson { +// bool deserializeJson(TDestination& destination, TString json); +// TDestination = JsonArray, JsonObject, JsonVariant +// TString = const std::string&, const String& +template +typename Internals::EnableIf::value, bool>::type +deserializeJson(TDestination &destination, const TString &json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + return Internals::makeParser(&destination.buffer(), json, nestingLimit) + .parse(destination); +} +// +// bool deserializeJson(TDestination& destination, TString json); +// TDestination = JsonArray, JsonObject, JsonVariant +// TString = const char*, const char[N], const FlashStringHelper* +template +bool deserializeJson(TDestination &destination, TString *json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + return Internals::makeParser(&destination.buffer(), json, nestingLimit) + .parse(destination); +} +// +// bool deserializeJson(TDestination& destination, TString json); +// TDestination = JsonArray, JsonObject, JsonVariant +// TString = std::istream&, Stream& +template +bool deserializeJson(TDestination &destination, TString &json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + return Internals::makeParser(&destination.buffer(), json, nestingLimit) + .parse(destination); +} +} // namespace ArduinoJson diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 4fee0ea1c..931a46128 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -67,10 +67,10 @@ endif() add_subdirectory(DynamicJsonBuffer) add_subdirectory(IntegrationTests) add_subdirectory(JsonArray) -add_subdirectory(JsonBuffer) add_subdirectory(JsonObject) +add_subdirectory(JsonParser) add_subdirectory(JsonVariant) add_subdirectory(JsonWriter) add_subdirectory(Misc) add_subdirectory(Polyfills) -add_subdirectory(StaticJsonBuffer) \ No newline at end of file +add_subdirectory(StaticJsonBuffer) diff --git a/test/DynamicJsonBuffer/CMakeLists.txt b/test/DynamicJsonBuffer/CMakeLists.txt index 9030f3760..c22c08011 100644 --- a/test/DynamicJsonBuffer/CMakeLists.txt +++ b/test/DynamicJsonBuffer/CMakeLists.txt @@ -4,8 +4,6 @@ add_executable(DynamicJsonBufferTests alloc.cpp - createArray.cpp - createObject.cpp no_memory.cpp size.cpp startString.cpp diff --git a/test/DynamicJsonBuffer/createArray.cpp b/test/DynamicJsonBuffer/createArray.cpp deleted file mode 100644 index 34ab07e97..000000000 --- a/test/DynamicJsonBuffer/createArray.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("DynamicJsonBuffer::createArray()") { - DynamicJsonBuffer jsonBuffer; - JsonArray &array = jsonBuffer.createArray(); - - SECTION("GrowsWithArray") { - REQUIRE(JSON_ARRAY_SIZE(0) == jsonBuffer.size()); - - array.add("hello"); - REQUIRE(JSON_ARRAY_SIZE(1) == jsonBuffer.size()); - - array.add("world"); - REQUIRE(JSON_ARRAY_SIZE(2) == jsonBuffer.size()); - } - - SECTION("CanAdd1000Values") { - for (size_t i = 1; i <= 1000; i++) { - array.add("hello"); - REQUIRE(array.size() == i); - } - } -} diff --git a/test/DynamicJsonBuffer/createObject.cpp b/test/DynamicJsonBuffer/createObject.cpp deleted file mode 100644 index 2193a659b..000000000 --- a/test/DynamicJsonBuffer/createObject.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("DynamicJsonBuffer::createObject()") { - DynamicJsonBuffer json; - - JsonObject &obj = json.createObject(); - REQUIRE(JSON_OBJECT_SIZE(0) == json.size()); - - obj["hello"] = 1; - REQUIRE(JSON_OBJECT_SIZE(1) == json.size()); - - obj["world"] = 2; - REQUIRE(JSON_OBJECT_SIZE(2) == json.size()); - - obj["world"] = 3; // <- same key, should not grow - REQUIRE(JSON_OBJECT_SIZE(2) == json.size()); -} diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index 824d968c3..be39c04d6 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -22,23 +22,25 @@ TEST_CASE("DynamicJsonBuffer no memory") { NoMemoryAllocator().deallocate(NULL); } - SECTION("createArray()") { - REQUIRE_FALSE(_jsonBuffer.createArray().success()); - } + // TODO: uncomment + // SECTION("parseArray()") { + // char json[] = "[{}]"; + // DynamicJsonArray arr; - SECTION("createObject()") { - REQUIRE_FALSE(_jsonBuffer.createObject().success()); - } + // bool success = deserializeJson(arr, json); - SECTION("parseArray()") { - char json[] = "[]"; - REQUIRE_FALSE(_jsonBuffer.parseArray(json).success()); - } + // REQUIRE(success == false); + // } - SECTION("parseObject()") { - char json[] = "{}"; - REQUIRE_FALSE(_jsonBuffer.parseObject(json).success()); - } + // TODO: uncomment + // SECTION("parseObject()") { + // char json[] = "{[]}"; + // DynamicJsonObject obj; + + // bool success = deserializeJson(obj, json); + + // REQUIRE(success == false); + // } SECTION("startString()") { DynamicJsonBufferBase::String str = diff --git a/test/IntegrationTests/gbathree.cpp b/test/IntegrationTests/gbathree.cpp index 9a5144251..0f12dbf22 100644 --- a/test/IntegrationTests/gbathree.cpp +++ b/test/IntegrationTests/gbathree.cpp @@ -6,9 +6,10 @@ #include TEST_CASE("Gbathree") { - DynamicJsonBuffer _buffer; + DynamicJsonObject _object; - const JsonObject& _object = _buffer.parseObject( + bool success = deserializeJson( + _object, "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" "baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":" @@ -21,7 +22,7 @@ TEST_CASE("Gbathree") { "[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); SECTION("Success") { - REQUIRE(_object.success()); + REQUIRE(success == true); } SECTION("ProtocolName") { diff --git a/test/IntegrationTests/round_trip.cpp b/test/IntegrationTests/round_trip.cpp index ec8c0b0cb..9dd49f938 100644 --- a/test/IntegrationTests/round_trip.cpp +++ b/test/IntegrationTests/round_trip.cpp @@ -6,13 +6,15 @@ #include void check(std::string originalJson) { - DynamicJsonBuffer jb; + DynamicJsonObject obj; std::string prettyJson; - jb.parseObject(originalJson).prettyPrintTo(prettyJson); + deserializeJson(obj, originalJson); + obj.prettyPrintTo(prettyJson); std::string finalJson; - jb.parseObject(prettyJson).printTo(finalJson); + deserializeJson(obj, originalJson); + obj.printTo(finalJson); REQUIRE(originalJson == finalJson); } diff --git a/test/JsonArray/add.cpp b/test/JsonArray/add.cpp index 2e10754ee..61f6ec6f6 100644 --- a/test/JsonArray/add.cpp +++ b/test/JsonArray/add.cpp @@ -6,8 +6,7 @@ #include TEST_CASE("JsonArray::add()") { - DynamicJsonBuffer _jsonBuffer; - JsonArray& _array = _jsonBuffer.createArray(); + DynamicJsonArray _array; SECTION("int") { _array.add(123); @@ -39,7 +38,7 @@ TEST_CASE("JsonArray::add()") { } SECTION("nested array") { - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; _array.add(arr); @@ -49,7 +48,7 @@ TEST_CASE("JsonArray::add()") { } SECTION("nested object") { - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; _array.add(obj); @@ -60,7 +59,7 @@ TEST_CASE("JsonArray::add()") { SECTION("array subscript") { const char* str = "hello"; - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add(str); _array.add(arr[0]); @@ -70,7 +69,7 @@ TEST_CASE("JsonArray::add()") { SECTION("object subscript") { const char* str = "hello"; - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; obj["x"] = str; _array.add(obj["x"]); @@ -81,30 +80,30 @@ TEST_CASE("JsonArray::add()") { SECTION("should not duplicate const char*") { _array.add("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should duplicate char*") { _array.add(const_cast("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should duplicate std::string") { _array.add(std::string("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should not duplicate RawJson(const char*)") { _array.add(RawJson("{}")); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should duplicate RawJson(char*)") { _array.add(RawJson(const_cast("{}"))); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } } diff --git a/test/JsonArray/basics.cpp b/test/JsonArray/basics.cpp index eada17e25..0e9d06177 100644 --- a/test/JsonArray/basics.cpp +++ b/test/JsonArray/basics.cpp @@ -6,8 +6,7 @@ #include TEST_CASE("JsonArray basics") { - DynamicJsonBuffer jb; - JsonArray& array = jb.createArray(); + DynamicJsonArray array; SECTION("SuccessIsTrue") { REQUIRE(array.success()); diff --git a/test/JsonArray/copyFrom.cpp b/test/JsonArray/copyFrom.cpp index 850301a7e..a881e53d5 100644 --- a/test/JsonArray/copyFrom.cpp +++ b/test/JsonArray/copyFrom.cpp @@ -7,8 +7,7 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("OneDimension") { - DynamicJsonBuffer jsonBuffer; - JsonArray& array = jsonBuffer.createArray(); + DynamicJsonArray array; char json[32]; int source[] = {1, 2, 3}; @@ -21,8 +20,7 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("OneDimension_JsonBufferTooSmall") { const size_t SIZE = JSON_ARRAY_SIZE(2); - StaticJsonBuffer jsonBuffer; - JsonArray& array = jsonBuffer.createArray(); + StaticJsonArray array; char json[32]; int source[] = {1, 2, 3}; @@ -34,8 +32,7 @@ TEST_CASE("JsonArray::copyFrom()") { } SECTION("TwoDimensions") { - DynamicJsonBuffer jsonBuffer; - JsonArray& array = jsonBuffer.createArray(); + DynamicJsonArray array; char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; @@ -49,8 +46,7 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("TwoDimensions_JsonBufferTooSmall") { const size_t SIZE = JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); - StaticJsonBuffer jsonBuffer; - JsonArray& array = jsonBuffer.createArray(); + StaticJsonArray array; char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; diff --git a/test/JsonArray/copyTo.cpp b/test/JsonArray/copyTo.cpp index 901505902..3a83a4616 100644 --- a/test/JsonArray/copyTo.cpp +++ b/test/JsonArray/copyTo.cpp @@ -6,11 +6,12 @@ #include TEST_CASE("JsonArray::copyTo()") { - DynamicJsonBuffer jsonBuffer; + DynamicJsonArray array; SECTION("BiggerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonArray& array = jsonBuffer.parseArray(json); + bool success = deserializeJson(array, json); + REQUIRE(success == true); int destination[4] = {0}; size_t result = array.copyTo(destination); @@ -24,7 +25,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("SmallerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonArray& array = jsonBuffer.parseArray(json); + bool success = deserializeJson(array, json); + REQUIRE(success == true); int destination[2] = {0}; size_t result = array.copyTo(destination); @@ -37,7 +39,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("TwoOneDimensionIntegerArray") { char json[] = "[[1,2],[3],[4]]"; - JsonArray& array = jsonBuffer.parseArray(json); + bool success = deserializeJson(array, json); + REQUIRE(success == true); int destination[3][2] = {{0}}; array.copyTo(destination); diff --git a/test/JsonArray/iterator.cpp b/test/JsonArray/iterator.cpp index fff819645..ef0c7785a 100644 --- a/test/JsonArray/iterator.cpp +++ b/test/JsonArray/iterator.cpp @@ -7,9 +7,7 @@ template static void run_iterator_test() { - StaticJsonBuffer jsonBuffer; - - JsonArray &array = jsonBuffer.createArray(); + StaticJsonArray array; array.add(12); array.add(34); diff --git a/test/JsonArray/prettyPrintTo.cpp b/test/JsonArray/prettyPrintTo.cpp index fc5c526da..af36a3207 100644 --- a/test/JsonArray/prettyPrintTo.cpp +++ b/test/JsonArray/prettyPrintTo.cpp @@ -15,8 +15,7 @@ static void check(JsonArray& array, std::string expected) { } TEST_CASE("JsonArray::prettyPrintTo()") { - DynamicJsonBuffer jb; - JsonArray& array = jb.createArray(); + DynamicJsonArray array; SECTION("Empty") { check(array, "[]"); diff --git a/test/JsonArray/printTo.cpp b/test/JsonArray/printTo.cpp index 6b7f003c6..82ebad9ae 100644 --- a/test/JsonArray/printTo.cpp +++ b/test/JsonArray/printTo.cpp @@ -15,8 +15,7 @@ static void check(JsonArray &array, std::string expected) { } TEST_CASE("JsonArray::printTo()") { - StaticJsonBuffer jb; - JsonArray &array = jb.createArray(); + StaticJsonArray array; SECTION("Empty") { check(array, "[]"); @@ -74,13 +73,10 @@ TEST_CASE("JsonArray::printTo()") { } SECTION("RawJson(char*)") { - DynamicJsonBuffer jb2; - JsonArray &arr = jb2.createArray(); - char tmp[] = "{\"key\":\"value\"}"; - arr.add(RawJson(tmp)); + array.add(RawJson(tmp)); - check(arr, "[{\"key\":\"value\"}]"); + check(array, "[{\"key\":\"value\"}]"); } SECTION("OneIntegerOverCapacity") { diff --git a/test/JsonArray/remove.cpp b/test/JsonArray/remove.cpp index 089358183..61ea011d7 100644 --- a/test/JsonArray/remove.cpp +++ b/test/JsonArray/remove.cpp @@ -6,8 +6,7 @@ #include TEST_CASE("JsonArray::remove()") { - DynamicJsonBuffer _jsonBuffer; - JsonArray& _array = _jsonBuffer.createArray(); + DynamicJsonArray _array; _array.add(1); _array.add(2); _array.add(3); diff --git a/test/JsonArray/set.cpp b/test/JsonArray/set.cpp index 901f9054a..f0f55016d 100644 --- a/test/JsonArray/set.cpp +++ b/test/JsonArray/set.cpp @@ -8,8 +8,7 @@ using namespace Catch::Matchers; TEST_CASE("JsonArray::set()") { - DynamicJsonBuffer _jsonBuffer; - JsonArray& _array = _jsonBuffer.createArray(); + DynamicJsonArray _array; _array.add(0); SECTION("int") { @@ -41,7 +40,7 @@ TEST_CASE("JsonArray::set()") { } SECTION("nested array") { - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; _array.set(0, arr); @@ -51,7 +50,7 @@ TEST_CASE("JsonArray::set()") { } SECTION("nested object") { - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; _array.set(0, obj); @@ -61,7 +60,7 @@ TEST_CASE("JsonArray::set()") { } SECTION("array subscript") { - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add("hello"); _array.set(0, arr[0]); @@ -70,7 +69,7 @@ TEST_CASE("JsonArray::set()") { } SECTION("object subscript") { - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; obj["x"] = "hello"; _array.set(0, obj["x"]); @@ -81,18 +80,18 @@ TEST_CASE("JsonArray::set()") { SECTION("should not duplicate const char*") { _array.set(0, "world"); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should duplicate char*") { _array.set(0, const_cast("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should duplicate std::string") { _array.set(0, std::string("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } } diff --git a/test/JsonArray/size.cpp b/test/JsonArray/size.cpp index c45fe30ea..de409a794 100644 --- a/test/JsonArray/size.cpp +++ b/test/JsonArray/size.cpp @@ -6,8 +6,7 @@ #include TEST_CASE("JsonArray::size()") { - DynamicJsonBuffer _jsonBuffer; - JsonArray& _array = _jsonBuffer.createArray(); + DynamicJsonArray _array; SECTION("increases after add()") { _array.add("hello"); diff --git a/test/JsonArray/subscript.cpp b/test/JsonArray/subscript.cpp index 69893c53c..17f3e7a4f 100644 --- a/test/JsonArray/subscript.cpp +++ b/test/JsonArray/subscript.cpp @@ -7,8 +7,7 @@ #include TEST_CASE("JsonArray::operator[]") { - DynamicJsonBuffer _jsonBuffer; - JsonArray& _array = _jsonBuffer.createArray(); + DynamicJsonArray _array; _array.add(0); SECTION("int") { @@ -52,7 +51,7 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested array") { - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; _array[0] = arr; @@ -65,7 +64,7 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested object") { - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; _array[0] = obj; @@ -78,7 +77,7 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("array subscript") { - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; const char* str = "hello"; arr.add(str); @@ -89,7 +88,7 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("object subscript") { - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; const char* str = "hello"; obj["x"] = str; @@ -102,18 +101,18 @@ TEST_CASE("JsonArray::operator[]") { SECTION("should not duplicate const char*") { _array[0] = "world"; const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should duplicate char*") { _array[0] = const_cast("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } SECTION("should duplicate std::string") { _array[0] = std::string("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _array.memoryUsage()); } } diff --git a/test/JsonBuffer/CMakeLists.txt b/test/JsonBuffer/CMakeLists.txt deleted file mode 100644 index 34b3e735a..000000000 --- a/test/JsonBuffer/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -# ArduinoJson - arduinojson.org -# Copyright Benoit Blanchon 2014-2018 -# MIT License - -add_executable(JsonBufferTests - nested.cpp - nestingLimit.cpp - parse.cpp - parseArray.cpp - parseObject.cpp -) - -target_link_libraries(JsonBufferTests catch) -add_test(JsonBuffer JsonBufferTests) diff --git a/test/JsonBuffer/nested.cpp b/test/JsonBuffer/nested.cpp deleted file mode 100644 index 263e40e64..000000000 --- a/test/JsonBuffer/nested.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("JsonBuffer nested objects") { - SECTION("ArrayNestedInObject") { - DynamicJsonBuffer jsonBuffer; - char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; - - JsonObject &object = jsonBuffer.parseObject(jsonString); - JsonArray &array1 = object["ab"]; - const JsonArray &array2 = object["cd"]; - JsonArray &array3 = object["ef"]; - - REQUIRE(true == object.success()); - - REQUIRE(true == array1.success()); - REQUIRE(true == array2.success()); - REQUIRE(false == array3.success()); - - REQUIRE(2 == array1.size()); - REQUIRE(2 == array2.size()); - REQUIRE(0 == array3.size()); - - REQUIRE(1 == array1[0].as()); - REQUIRE(2 == array1[1].as()); - - REQUIRE(3 == array2[0].as()); - REQUIRE(4 == array2[1].as()); - - REQUIRE(0 == array3[0].as()); - } - - SECTION("ObjectNestedInArray") { - DynamicJsonBuffer jsonBuffer; - char jsonString[] = - " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; - - JsonArray &array = jsonBuffer.parseArray(jsonString); - JsonObject &object1 = array[0]; - const JsonObject &object2 = array[1]; - JsonObject &object3 = array[2]; - - REQUIRE(true == array.success()); - - REQUIRE(true == object1.success()); - REQUIRE(true == object2.success()); - REQUIRE(false == object3.success()); - - REQUIRE(2 == object1.size()); - REQUIRE(2 == object2.size()); - REQUIRE(0 == object3.size()); - - REQUIRE(1 == object1["a"].as()); - REQUIRE(2 == object1["b"].as()); - REQUIRE(3 == object2["c"].as()); - REQUIRE(4 == object2["d"].as()); - REQUIRE(0 == object3["e"].as()); - } -} diff --git a/test/JsonBuffer/parseArray.cpp b/test/JsonBuffer/parseArray.cpp deleted file mode 100644 index 2e843f8cf..000000000 --- a/test/JsonBuffer/parseArray.cpp +++ /dev/null @@ -1,318 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("JsonBuffer::parseArray()") { - DynamicJsonBuffer jb; - - SECTION("EmptyArray") { - JsonArray& arr = jb.parseArray("[]"); - - REQUIRE(arr.success()); - REQUIRE(0 == arr.size()); - } - - SECTION("MissingOpeningBracket") { - JsonArray& arr = jb.parseArray("]"); - REQUIRE_FALSE(arr.success()); - } - - SECTION("ArrayWithNoEnd") { - JsonArray& arr = jb.parseArray("["); - REQUIRE_FALSE(arr.success()); - } - - SECTION("EmptyArrayWithLeadingSpaces") { - JsonArray& arr = jb.parseArray(" []"); - - REQUIRE(arr.success()); - REQUIRE(0 == arr.size()); - } - - SECTION("Garbage") { - JsonArray& arr = jb.parseArray("%*$£¤"); - - REQUIRE_FALSE(arr.success()); - } - - SECTION("OneInteger") { - JsonArray& arr = jb.parseArray("[42]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } - - SECTION("OneIntegerWithSpacesBefore") { - JsonArray& arr = jb.parseArray("[ \t\r\n42]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } - - SECTION("OneIntegerWithSpaceAfter") { - JsonArray& arr = jb.parseArray("[42 \t\r\n]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } - - SECTION("TwoIntegers") { - JsonArray& arr = jb.parseArray("[42,84]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == 42); - REQUIRE(arr[1] == 84); - } - - SECTION("TwoDoubles") { - JsonArray& arr = jb.parseArray("[4.2,1e2]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == 4.2); - REQUIRE(arr[1] == 1e2); - } - - SECTION("UnsignedLong") { - JsonArray& arr = jb.parseArray("[4294967295]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 4294967295UL); - } - - SECTION("TwoBooleans") { - JsonArray& arr = jb.parseArray("[true,false]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == true); - REQUIRE(arr[1] == false); - } - - SECTION("TwoNulls") { - JsonArray& arr = jb.parseArray("[null,null]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0].as() == 0); - REQUIRE(arr[1].as() == 0); - } - - SECTION("TwoStringsDoubleQuotes") { - JsonArray& arr = jb.parseArray("[ \"hello\" , \"world\" ]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("TwoStringsSingleQuotes") { - JsonArray& arr = jb.parseArray("[ 'hello' , 'world' ]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("TwoStringsNoQuotes") { - JsonArray& arr = jb.parseArray("[ hello , world ]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("EmptyStringsDoubleQuotes") { - JsonArray& arr = jb.parseArray("[\"\",\"\"]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } - - SECTION("EmptyStringSingleQuotes") { - JsonArray& arr = jb.parseArray("[\'\',\'\']"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } - - SECTION("EmptyStringNoQuotes") { - JsonArray& arr = jb.parseArray("[,]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } - - SECTION("ClosingDoubleQuoteMissing") { - JsonArray& arr = jb.parseArray("[\"]"); - - REQUIRE_FALSE(arr.success()); - } - - SECTION("ClosingSignleQuoteMissing") { - JsonArray& arr = jb.parseArray("[\']"); - - REQUIRE_FALSE(arr.success()); - } - - SECTION("StringWithEscapedChars") { - JsonArray& arr = jb.parseArray("[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); - } - - SECTION("StringWithUnterminatedEscapeSequence") { - JsonArray& arr = jb.parseArray("\"\\\0\"", 4); - REQUIRE_FALSE(arr.success()); - } - - SECTION("CCommentBeforeOpeningBracket") { - JsonArray& arr = jb.parseArray("/*COMMENT*/ [\"hello\"]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentAfterOpeningBracket") { - JsonArray& arr = jb.parseArray("[/*COMMENT*/ \"hello\"]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentBeforeClosingBracket") { - JsonArray& arr = jb.parseArray("[\"hello\"/*COMMENT*/]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentAfterClosingBracket") { - JsonArray& arr = jb.parseArray("[\"hello\"]/*COMMENT*/"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentBeforeComma") { - JsonArray& arr = jb.parseArray("[\"hello\"/*COMMENT*/,\"world\"]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CCommentAfterComma") { - JsonArray& arr = jb.parseArray("[\"hello\",/*COMMENT*/ \"world\"]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CppCommentBeforeOpeningBracket") { - JsonArray& arr = jb.parseArray("//COMMENT\n\t[\"hello\"]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentAfterOpeningBracket") { - JsonArray& arr = jb.parseArray("[//COMMENT\n\"hello\"]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentBeforeClosingBracket") { - JsonArray& arr = jb.parseArray("[\"hello\"//COMMENT\r\n]"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentAfterClosingBracket") { - JsonArray& arr = jb.parseArray("[\"hello\"]//COMMENT\n"); - - REQUIRE(arr.success()); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentBeforeComma") { - JsonArray& arr = jb.parseArray("[\"hello\"//COMMENT\n,\"world\"]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CppCommentAfterComma") { - JsonArray& arr = jb.parseArray("[\"hello\",//COMMENT\n\"world\"]"); - - REQUIRE(arr.success()); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("InvalidCppComment") { - JsonArray& arr = jb.parseArray("[/COMMENT\n]"); - REQUIRE_FALSE(arr.success()); - } - - SECTION("InvalidComment") { - JsonArray& arr = jb.parseArray("[/*/\n]"); - REQUIRE_FALSE(arr.success()); - } - - SECTION("UnfinishedCComment") { - JsonArray& arr = jb.parseArray("[/*COMMENT]"); - REQUIRE_FALSE(arr.success()); - } - - SECTION("EndsInCppComment") { - JsonArray& arr = jb.parseArray("[//COMMENT"); - REQUIRE_FALSE(arr.success()); - } - - SECTION("AfterClosingStar") { - JsonArray& arr = jb.parseArray("[/*COMMENT*"); - REQUIRE_FALSE(arr.success()); - } - - SECTION("DeeplyNested") { - JsonArray& arr = - jb.parseArray("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"); - REQUIRE(arr.success()); - } -} diff --git a/test/JsonBuffer/parseObject.cpp b/test/JsonBuffer/parseObject.cpp deleted file mode 100644 index 3a4067c56..000000000 --- a/test/JsonBuffer/parseObject.cpp +++ /dev/null @@ -1,170 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("JsonBuffer::parseObject()") { - DynamicJsonBuffer jb; - - SECTION("An empty object") { - JsonObject& obj = jb.parseObject("{}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 0); - } - - SECTION("Quotes") { - SECTION("Double quotes") { - JsonObject& obj = jb.parseObject("{\"key\":\"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("Single quotes") { - JsonObject& obj = jb.parseObject("{'key':'value'}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("No quotes") { - JsonObject& obj = jb.parseObject("{key:value}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("No quotes, allow underscore in key") { - JsonObject& obj = jb.parseObject("{_k_e_y_:42}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["_k_e_y_"] == 42); - } - } - - SECTION("Spaces") { - SECTION("Before the key") { - JsonObject& obj = jb.parseObject("{ \"key\":\"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("After the key") { - JsonObject& obj = jb.parseObject("{\"key\" :\"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("Before the value") { - JsonObject& obj = jb.parseObject("{\"key\": \"value\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("After the value") { - JsonObject& obj = jb.parseObject("{\"key\":\"value\" }"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 1); - REQUIRE(obj["key"] == "value"); - } - - SECTION("Before the colon") { - JsonObject& obj = - jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == "value1"); - REQUIRE(obj["key2"] == "value2"); - } - - SECTION("After the colon") { - JsonObject& obj = - jb.parseObject("{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == "value1"); - REQUIRE(obj["key2"] == "value2"); - } - } - - SECTION("Values types") { - SECTION("String") { - JsonObject& obj = - jb.parseObject("{\"key1\":\"value1\",\"key2\":\"value2\"}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == "value1"); - REQUIRE(obj["key2"] == "value2"); - } - - SECTION("Integer") { - JsonObject& obj = jb.parseObject("{\"key1\":42,\"key2\":-42}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == 42); - REQUIRE(obj["key2"] == -42); - } - - SECTION("Double") { - JsonObject& obj = jb.parseObject("{\"key1\":12.345,\"key2\":-7E89}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == 12.345); - REQUIRE(obj["key2"] == -7E89); - } - - SECTION("Booleans") { - JsonObject& obj = jb.parseObject("{\"key1\":true,\"key2\":false}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"] == true); - REQUIRE(obj["key2"] == false); - } - - SECTION("Null") { - JsonObject& obj = jb.parseObject("{\"key1\":null,\"key2\":null}"); - REQUIRE(obj.success()); - REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"].as() == 0); - REQUIRE(obj["key2"].as() == 0); - } - } - - SECTION("Misc") { - SECTION("The opening brace is missing") { - JsonObject& obj = jb.parseObject("}"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("The closing brace is missing") { - JsonObject& obj = jb.parseObject("{"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("A quoted key without value") { - JsonObject& obj = jb.parseObject("{\"key\"}"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("A non-quoted key without value") { - JsonObject& obj = jb.parseObject("{key}"); - REQUIRE_FALSE(obj.success()); - } - - SECTION("A dangling comma") { - JsonObject& obj = jb.parseObject("{\"key1\":\"value1\",}"); - REQUIRE_FALSE(obj.success()); - REQUIRE(obj.size() == 0); - } - - SECTION("null as a key") { - JsonObject& obj = jb.parseObject("null:\"value\"}"); - REQUIRE_FALSE(obj.success()); - } - } -} diff --git a/test/JsonObject/basics.cpp b/test/JsonObject/basics.cpp index dd9817029..a5e584580 100644 --- a/test/JsonObject/basics.cpp +++ b/test/JsonObject/basics.cpp @@ -6,8 +6,7 @@ #include TEST_CASE("JsonObject basics") { - DynamicJsonBuffer _jsonBuffer; - JsonObject& _object = _jsonBuffer.createObject(); + DynamicJsonObject _object; SECTION("InitialSizeIsZero") { REQUIRE(0 == _object.size()); diff --git a/test/JsonObject/containsKey.cpp b/test/JsonObject/containsKey.cpp index f8d0a1520..c28d11e03 100644 --- a/test/JsonObject/containsKey.cpp +++ b/test/JsonObject/containsKey.cpp @@ -6,8 +6,7 @@ #include TEST_CASE("JsonObject::containsKey()") { - DynamicJsonBuffer _jsonBuffer; - JsonObject& _object = _jsonBuffer.createObject(); + DynamicJsonObject _object; SECTION("ContainsKeyReturnsFalseForNonExistingKey") { _object.set("hello", 42); diff --git a/test/JsonObject/get.cpp b/test/JsonObject/get.cpp index b3635956a..d1fb8317b 100644 --- a/test/JsonObject/get.cpp +++ b/test/JsonObject/get.cpp @@ -8,8 +8,7 @@ using namespace Catch::Matchers; TEST_CASE("JsonObject::get()") { - DynamicJsonBuffer jb; - JsonObject& obj = jb.createObject(); + DynamicJsonObject obj; SECTION("GetConstCharPointer_GivenStringLiteral") { obj.set("hello", "world"); diff --git a/test/JsonObject/iterator.cpp b/test/JsonObject/iterator.cpp index e765d5c71..661f27d8c 100644 --- a/test/JsonObject/iterator.cpp +++ b/test/JsonObject/iterator.cpp @@ -8,8 +8,7 @@ using namespace Catch::Matchers; TEST_CASE("JsonObject::begin()/end()") { - StaticJsonBuffer jb; - JsonObject& obj = jb.createObject(); + StaticJsonObject obj; obj["ab"] = 12; obj["cd"] = 34; diff --git a/test/JsonObject/prettyPrintTo.cpp b/test/JsonObject/prettyPrintTo.cpp index 304592469..885a68952 100644 --- a/test/JsonObject/prettyPrintTo.cpp +++ b/test/JsonObject/prettyPrintTo.cpp @@ -18,8 +18,7 @@ void check(const JsonObject &obj, const std::string expected) { } TEST_CASE("JsonObject::prettyPrintTo()") { - DynamicJsonBuffer jb; - JsonObject &obj = jb.createObject(); + DynamicJsonObject obj; SECTION("EmptyObject") { check(obj, "{}"); diff --git a/test/JsonObject/printTo.cpp b/test/JsonObject/printTo.cpp index 6d0bcc9ad..f72bb2e1b 100644 --- a/test/JsonObject/printTo.cpp +++ b/test/JsonObject/printTo.cpp @@ -16,8 +16,7 @@ void check(const JsonObject &obj, const std::string &expected) { REQUIRE(expected.size() == measuredLen); } TEST_CASE("JsonObject::printTo()") { - DynamicJsonBuffer _jsonBuffer; - JsonObject &obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; SECTION("EmptyObject") { check(obj, "{}"); @@ -92,17 +91,22 @@ TEST_CASE("JsonObject::printTo()") { } SECTION("ThreeNestedArrays") { + DynamicJsonArray b, c; + obj.createNestedArray("a"); - obj["b"] = _jsonBuffer.createArray(); - obj.set("c", _jsonBuffer.createArray()); + obj["b"] = b; + obj.set("c", c); check(obj, "{\"a\":[],\"b\":[],\"c\":[]}"); } SECTION("ThreeNestedObjects") { + DynamicJsonObject b; + DynamicJsonObject c; + obj.createNestedObject("a"); - obj["b"] = _jsonBuffer.createObject(); - obj.set("c", _jsonBuffer.createObject()); + obj["b"] = b; + obj.set("c", c); check(obj, "{\"a\":{},\"b\":{},\"c\":{}}"); } diff --git a/test/JsonObject/remove.cpp b/test/JsonObject/remove.cpp index 0e68eec05..28bf539ba 100644 --- a/test/JsonObject/remove.cpp +++ b/test/JsonObject/remove.cpp @@ -7,10 +7,9 @@ #include TEST_CASE("JsonObject::remove()") { - DynamicJsonBuffer jb; + DynamicJsonObject obj; SECTION("SizeDecreased_WhenValuesAreRemoved") { - JsonObject& obj = jb.createObject(); obj["hello"] = 1; obj.remove("hello"); @@ -19,7 +18,6 @@ TEST_CASE("JsonObject::remove()") { } SECTION("SizeUntouched_WhenRemoveIsCalledWithAWrongKey") { - JsonObject& obj = jb.createObject(); obj["hello"] = 1; obj.remove("world"); @@ -28,7 +26,7 @@ TEST_CASE("JsonObject::remove()") { } SECTION("RemoveByIterator") { - JsonObject& obj = jb.parseObject("{\"a\":0,\"b\":1,\"c\":2}"); + deserializeJson(obj, "{\"a\":0,\"b\":1,\"c\":2}"); for (JsonObject::iterator it = obj.begin(); it != obj.end(); ++it) { if (it->value == 1) obj.remove(it); diff --git a/test/JsonObject/set.cpp b/test/JsonObject/set.cpp index d5ae48b21..fbc32ee6f 100644 --- a/test/JsonObject/set.cpp +++ b/test/JsonObject/set.cpp @@ -7,8 +7,7 @@ #include TEST_CASE("JsonObject::set()") { - DynamicJsonBuffer jb; - JsonObject& _object = jb.createObject(); + DynamicJsonObject _object; SECTION("int") { _object.set("hello", 123); @@ -43,7 +42,7 @@ TEST_CASE("JsonObject::set()") { } SECTION("nested array") { - JsonArray& arr = jb.createArray(); + DynamicJsonArray arr; _object.set("hello", arr); @@ -53,7 +52,7 @@ TEST_CASE("JsonObject::set()") { } SECTION("nested object") { - JsonObject& obj = jb.createObject(); + DynamicJsonObject obj; _object.set("hello", obj); @@ -63,7 +62,7 @@ TEST_CASE("JsonObject::set()") { } SECTION("array subscript") { - JsonArray& arr = jb.createArray(); + DynamicJsonArray arr; arr.add(42); _object.set("a", arr[0]); @@ -72,7 +71,7 @@ TEST_CASE("JsonObject::set()") { } SECTION("object subscript") { - JsonObject& obj = jb.createObject(); + DynamicJsonObject obj; obj.set("x", 42); _object.set("a", obj["x"]); @@ -81,15 +80,13 @@ TEST_CASE("JsonObject::set()") { } SECTION("returns true when allocation succeeds") { - StaticJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + StaticJsonObject obj; REQUIRE(true == obj.set(std::string("hello"), std::string("world"))); } SECTION("returns false when allocation fails") { - StaticJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + StaticJsonObject obj; REQUIRE(false == obj.set(std::string("hello"), std::string("world"))); } @@ -97,42 +94,42 @@ TEST_CASE("JsonObject::set()") { SECTION("should not duplicate const char*") { _object.set("hello", "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == jb.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate char* value") { _object.set("hello", const_cast("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == jb.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate char* key") { _object.set(const_cast("hello"), "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == jb.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate char* key&value") { _object.set(const_cast("hello"), const_cast("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= jb.size()); + REQUIRE(expectedSize <= _object.memoryUsage()); } SECTION("should duplicate std::string value") { _object.set("hello", std::string("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == jb.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate std::string key") { _object.set(std::string("hello"), "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == jb.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate std::string key&value") { _object.set(std::string("hello"), std::string("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= jb.size()); + REQUIRE(expectedSize <= _object.memoryUsage()); } } diff --git a/test/JsonObject/size.cpp b/test/JsonObject/size.cpp index eae888342..ee3b413f8 100644 --- a/test/JsonObject/size.cpp +++ b/test/JsonObject/size.cpp @@ -7,8 +7,7 @@ #include TEST_CASE("JsonObject::size()") { - DynamicJsonBuffer jb; - JsonObject& _object = jb.createObject(); + DynamicJsonObject _object; SECTION("increases when values are added") { _object.set("hello", 42); diff --git a/test/JsonObject/subscript.cpp b/test/JsonObject/subscript.cpp index d08e8c77d..aecfb0ce7 100644 --- a/test/JsonObject/subscript.cpp +++ b/test/JsonObject/subscript.cpp @@ -6,8 +6,7 @@ #include TEST_CASE("JsonObject::operator[]") { - DynamicJsonBuffer _jsonBuffer; - JsonObject& _object = _jsonBuffer.createObject(); + DynamicJsonObject _object; SECTION("int") { _object["hello"] = 123; @@ -53,7 +52,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("array") { - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; _object["hello"] = arr; @@ -69,7 +68,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("object") { - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; _object["hello"] = obj; @@ -85,7 +84,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("array subscript") { - JsonArray& arr = _jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add(42); _object["a"] = arr[0]; @@ -94,7 +93,7 @@ TEST_CASE("JsonObject::operator[]") { } SECTION("object subscript") { - JsonObject& obj = _jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set("x", 42); _object["a"] = obj["x"]; @@ -111,42 +110,42 @@ TEST_CASE("JsonObject::operator[]") { SECTION("should not duplicate const char*") { _object["hello"] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate char* value") { _object["hello"] = const_cast("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate char* key") { _object[const_cast("hello")] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate char* key&value") { _object[const_cast("hello")] = const_cast("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _jsonBuffer.size()); + REQUIRE(expectedSize <= _object.memoryUsage()); } SECTION("should duplicate std::string value") { _object["hello"] = std::string("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate std::string key") { _object[std::string("hello")] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _jsonBuffer.size()); + REQUIRE(expectedSize == _object.memoryUsage()); } SECTION("should duplicate std::string key&value") { _object[std::string("hello")] = std::string("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _jsonBuffer.size()); + REQUIRE(expectedSize <= _object.memoryUsage()); } } diff --git a/test/JsonParser/CMakeLists.txt b/test/JsonParser/CMakeLists.txt new file mode 100644 index 000000000..fa5ec203e --- /dev/null +++ b/test/JsonParser/CMakeLists.txt @@ -0,0 +1,15 @@ +# ArduinoJson - arduinojson.org +# Copyright Benoit Blanchon 2014-2018 +# MIT License + +add_executable(JsonParserTests + JsonArray.cpp + JsonObject.cpp + JsonVariant.cpp + nestingLimit.cpp + StaticJsonArray.cpp + StaticJsonObject.cpp +) + +target_link_libraries(JsonParserTests catch) +add_test(JsonParser JsonParserTests) diff --git a/test/JsonParser/JsonArray.cpp b/test/JsonParser/JsonArray.cpp new file mode 100644 index 000000000..af12c5482 --- /dev/null +++ b/test/JsonParser/JsonArray.cpp @@ -0,0 +1,346 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeJson(JsonArray&)") { + DynamicJsonArray arr; + + SECTION("EmptyArray") { + bool success = deserializeJson(arr, "[]"); + + REQUIRE(success == true); + REQUIRE(0 == arr.size()); + } + + SECTION("MissingOpeningBracket") { + bool success = deserializeJson(arr, "]"); + REQUIRE_FALSE(success == true); + } + + SECTION("ArrayWithNoEnd") { + bool success = deserializeJson(arr, "["); + REQUIRE_FALSE(success == true); + } + + SECTION("EmptyArrayWithLeadingSpaces") { + bool success = deserializeJson(arr, " []"); + + REQUIRE(success == true); + REQUIRE(0 == arr.size()); + } + + SECTION("Garbage") { + bool success = deserializeJson(arr, "%*$£¤"); + + REQUIRE_FALSE(success == true); + } + + SECTION("OneInteger") { + bool success = deserializeJson(arr, "[42]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } + + SECTION("OneIntegerWithSpacesBefore") { + bool success = deserializeJson(arr, "[ \t\r\n42]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } + + SECTION("OneIntegerWithSpaceAfter") { + bool success = deserializeJson(arr, "[42 \t\r\n]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } + + SECTION("TwoIntegers") { + bool success = deserializeJson(arr, "[42,84]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == 42); + REQUIRE(arr[1] == 84); + } + + SECTION("TwoDoubles") { + bool success = deserializeJson(arr, "[4.2,1e2]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == 4.2); + REQUIRE(arr[1] == 1e2); + } + + SECTION("UnsignedLong") { + bool success = deserializeJson(arr, "[4294967295]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 4294967295UL); + } + + SECTION("TwoBooleans") { + bool success = deserializeJson(arr, "[true,false]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == true); + REQUIRE(arr[1] == false); + } + + SECTION("TwoNulls") { + bool success = deserializeJson(arr, "[null,null]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0].as() == 0); + REQUIRE(arr[1].as() == 0); + } + + SECTION("TwoStringsDoubleQuotes") { + bool success = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("TwoStringsSingleQuotes") { + bool success = deserializeJson(arr, "[ 'hello' , 'world' ]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("TwoStringsNoQuotes") { + bool success = deserializeJson(arr, "[ hello , world ]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("EmptyStringsDoubleQuotes") { + bool success = deserializeJson(arr, "[\"\",\"\"]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } + + SECTION("EmptyStringSingleQuotes") { + bool success = deserializeJson(arr, "[\'\',\'\']"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } + + SECTION("EmptyStringNoQuotes") { + bool success = deserializeJson(arr, "[,]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } + + SECTION("ClosingDoubleQuoteMissing") { + bool success = deserializeJson(arr, "[\"]"); + + REQUIRE_FALSE(success == true); + } + + SECTION("ClosingSignleQuoteMissing") { + bool success = deserializeJson(arr, "[\']"); + + REQUIRE_FALSE(success == true); + } + + SECTION("StringWithEscapedChars") { + bool success = + deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); + } + + SECTION("StringWithUnterminatedEscapeSequence") { + bool success = deserializeJson(arr, "\"\\\0\"", 4); + REQUIRE_FALSE(success == true); + } + + SECTION("CCommentBeforeOpeningBracket") { + bool success = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CCommentAfterOpeningBracket") { + bool success = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CCommentBeforeClosingBracket") { + bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CCommentAfterClosingBracket") { + bool success = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CCommentBeforeComma") { + bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("CCommentAfterComma") { + bool success = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("CppCommentBeforeOpeningBracket") { + bool success = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CppCommentAfterOpeningBracket") { + bool success = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CppCommentBeforeClosingBracket") { + bool success = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CppCommentAfterClosingBracket") { + bool success = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); + + REQUIRE(success == true); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("CppCommentBeforeComma") { + bool success = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("CppCommentAfterComma") { + bool success = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); + + REQUIRE(success == true); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("InvalidCppComment") { + bool success = deserializeJson(arr, "[/COMMENT\n]"); + REQUIRE_FALSE(success == true); + } + + SECTION("InvalidComment") { + bool success = deserializeJson(arr, "[/*/\n]"); + REQUIRE_FALSE(success == true); + } + + SECTION("UnfinishedCComment") { + bool success = deserializeJson(arr, "[/*COMMENT]"); + REQUIRE_FALSE(success == true); + } + + SECTION("EndsInCppComment") { + bool success = deserializeJson(arr, "[//COMMENT"); + REQUIRE_FALSE(success == true); + } + + SECTION("AfterClosingStar") { + bool success = deserializeJson(arr, "[/*COMMENT*"); + REQUIRE_FALSE(success == true); + } + + SECTION("DeeplyNested") { + bool success = deserializeJson( + arr, "[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"); + REQUIRE(success == true); + } + + SECTION("ObjectNestedInArray") { + char jsonString[] = + " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; + + bool success = deserializeJson(arr, jsonString); + + JsonObject &object1 = arr[0]; + const JsonObject &object2 = arr[1]; + JsonObject &object3 = arr[2]; + + REQUIRE(true == success); + + REQUIRE(true == object1.success()); + REQUIRE(true == object2.success()); + REQUIRE(false == object3.success()); + + REQUIRE(2 == object1.size()); + REQUIRE(2 == object2.size()); + REQUIRE(0 == object3.size()); + + REQUIRE(1 == object1["a"].as()); + REQUIRE(2 == object1["b"].as()); + REQUIRE(3 == object2["c"].as()); + REQUIRE(4 == object2["d"].as()); + REQUIRE(0 == object3["e"].as()); + } +} diff --git a/test/JsonParser/JsonObject.cpp b/test/JsonParser/JsonObject.cpp new file mode 100644 index 000000000..41bc3e5f0 --- /dev/null +++ b/test/JsonParser/JsonObject.cpp @@ -0,0 +1,197 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeJson(JsonObject&)") { + DynamicJsonObject obj; + + SECTION("An empty object") { + bool success = deserializeJson(obj, "{}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 0); + } + + SECTION("Quotes") { + SECTION("Double quotes") { + bool success = deserializeJson(obj, "{\"key\":\"value\"}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("Single quotes") { + bool success = deserializeJson(obj, "{'key':'value'}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("No quotes") { + bool success = deserializeJson(obj, "{key:value}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("No quotes, allow underscore in key") { + bool success = deserializeJson(obj, "{_k_e_y_:42}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["_k_e_y_"] == 42); + } + } + + SECTION("Spaces") { + SECTION("Before the key") { + bool success = deserializeJson(obj, "{ \"key\":\"value\"}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("After the key") { + bool success = deserializeJson(obj, "{\"key\" :\"value\"}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("Before the value") { + bool success = deserializeJson(obj, "{\"key\": \"value\"}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("After the value") { + bool success = deserializeJson(obj, "{\"key\":\"value\" }"); + REQUIRE(success == true); + REQUIRE(obj.size() == 1); + REQUIRE(obj["key"] == "value"); + } + + SECTION("Before the colon") { + bool success = + deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == "value1"); + REQUIRE(obj["key2"] == "value2"); + } + + SECTION("After the colon") { + bool success = + deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == "value1"); + REQUIRE(obj["key2"] == "value2"); + } + } + + SECTION("Values types") { + SECTION("String") { + bool success = + deserializeJson(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == "value1"); + REQUIRE(obj["key2"] == "value2"); + } + + SECTION("Integer") { + bool success = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == 42); + REQUIRE(obj["key2"] == -42); + } + + SECTION("Double") { + bool success = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == 12.345); + REQUIRE(obj["key2"] == -7E89); + } + + SECTION("Booleans") { + bool success = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"] == true); + REQUIRE(obj["key2"] == false); + } + + SECTION("Null") { + bool success = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); + REQUIRE(success == true); + REQUIRE(obj.size() == 2); + REQUIRE(obj["key1"].as() == 0); + REQUIRE(obj["key2"].as() == 0); + } + + SECTION("Array") { + char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; + + bool success = deserializeJson(obj, jsonString); + + JsonArray &array1 = obj["ab"]; + const JsonArray &array2 = obj["cd"]; + JsonArray &array3 = obj["ef"]; + + REQUIRE(true == success); + + REQUIRE(true == array1.success()); + REQUIRE(true == array2.success()); + REQUIRE(false == array3.success()); + + REQUIRE(2 == array1.size()); + REQUIRE(2 == array2.size()); + REQUIRE(0 == array3.size()); + + REQUIRE(1 == array1[0].as()); + REQUIRE(2 == array1[1].as()); + + REQUIRE(3 == array2[0].as()); + REQUIRE(4 == array2[1].as()); + + REQUIRE(0 == array3[0].as()); + } + } + + SECTION("Misc") { + SECTION("The opening brace is missing") { + bool success = deserializeJson(obj, "}"); + REQUIRE(success == false); + } + + SECTION("The closing brace is missing") { + bool success = deserializeJson(obj, "{"); + REQUIRE(success == false); + } + + SECTION("A quoted key without value") { + bool success = deserializeJson(obj, "{\"key\"}"); + REQUIRE(success == false); + } + + SECTION("A non-quoted key without value") { + bool success = deserializeJson(obj, "{key}"); + REQUIRE(success == false); + } + + SECTION("A dangling comma") { + bool success = deserializeJson(obj, "{\"key1\":\"value1\",}"); + REQUIRE(success == false); + } + + SECTION("null as a key") { + bool success = deserializeJson(obj, "null:\"value\"}"); + REQUIRE(success == false); + } + } +} diff --git a/test/JsonBuffer/parse.cpp b/test/JsonParser/JsonVariant.cpp similarity index 56% rename from test/JsonBuffer/parse.cpp rename to test/JsonParser/JsonVariant.cpp index 70e57918c..9141c2d48 100644 --- a/test/JsonBuffer/parse.cpp +++ b/test/JsonParser/JsonVariant.cpp @@ -7,73 +7,83 @@ using namespace Catch::Matchers; -TEST_CASE("JsonBuffer::parse()") { - DynamicJsonBuffer jb; +TEST_CASE("deserializeJson(JsonVariant&)") { + DynamicJsonVariant variant; SECTION("EmptyObject") { - JsonVariant variant = jb.parse("{}"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "{}"); + + REQUIRE(success == true); REQUIRE(variant.is()); } SECTION("EmptyArray") { - JsonVariant variant = jb.parse("[]"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "[]"); + + REQUIRE(success == true); REQUIRE(variant.is()); } SECTION("Integer") { - JsonVariant variant = jb.parse("-42"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "-42"); + + REQUIRE(success == true); REQUIRE(variant.is()); REQUIRE_FALSE(variant.is()); REQUIRE(variant == -42); } SECTION("Double") { - JsonVariant variant = jb.parse("-1.23e+4"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "-1.23e+4"); + + REQUIRE(success == true); REQUIRE_FALSE(variant.is()); REQUIRE(variant.is()); REQUIRE(variant.as() == Approx(-1.23e+4)); } SECTION("Double quoted string") { - JsonVariant variant = jb.parse("\"hello world\""); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "\"hello world\""); + + REQUIRE(success == true); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello world")); } SECTION("Single quoted string") { - JsonVariant variant = jb.parse("\'hello world\'"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "\'hello world\'"); + + REQUIRE(success == true); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello world")); } SECTION("True") { - JsonVariant variant = jb.parse("true"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "true"); + + REQUIRE(success == true); REQUIRE(variant.is()); REQUIRE(variant == true); } SECTION("False") { - JsonVariant variant = jb.parse("false"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "false"); + + REQUIRE(success == true); REQUIRE(variant.is()); REQUIRE(variant == false); } SECTION("OpenBrace") { - JsonVariant variant = jb.parse("{"); - REQUIRE_FALSE(variant.success()); + bool success = deserializeJson(variant, "{"); + + REQUIRE(success == false); } SECTION("Incomplete string") { - JsonVariant variant = jb.parse("\"hello"); - REQUIRE(variant.success()); + bool success = deserializeJson(variant, "\"hello"); + + REQUIRE(success == true); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello")); } diff --git a/test/JsonParser/StaticJsonArray.cpp b/test/JsonParser/StaticJsonArray.cpp new file mode 100644 index 000000000..0775fc029 --- /dev/null +++ b/test/JsonParser/StaticJsonArray.cpp @@ -0,0 +1,79 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeJson(StaticJsonArray&)") { + SECTION("BufferOfTheRightSizeForEmptyArray") { + StaticJsonArray arr; + char input[] = "[]"; + + bool success = deserializeJson(arr, input); + + REQUIRE(success == true); + } + + SECTION("TooSmallBufferForArrayWithOneValue") { + StaticJsonArray arr; + char input[] = "[1]"; + + bool success = deserializeJson(arr, input); + + REQUIRE(success == false); + } + + SECTION("BufferOfTheRightSizeForArrayWithOneValue") { + StaticJsonArray arr; + char input[] = "[1]"; + + bool success = deserializeJson(arr, input); + + REQUIRE(success == true); + } + + SECTION("TooSmallBufferForArrayWithNestedObject") { + StaticJsonArray arr; + char input[] = "[{}]"; + + bool success = deserializeJson(arr, input); + + REQUIRE(success == false); + } + + SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { + StaticJsonArray arr; + char input[] = "[{}]"; + + bool success = deserializeJson(arr, input); + + REQUIRE(success == true); + } + + SECTION("CharPtrNull") { + StaticJsonArray<100> arr; + + bool success = deserializeJson(arr, static_cast(0)); + + REQUIRE(success == false); + } + + SECTION("ConstCharPtrNull") { + StaticJsonArray<100> arr; + + bool success = deserializeJson(arr, static_cast(0)); + + REQUIRE(success == false); + } + + 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 + } +} diff --git a/test/JsonParser/StaticJsonObject.cpp b/test/JsonParser/StaticJsonObject.cpp new file mode 100644 index 000000000..a738e49e6 --- /dev/null +++ b/test/JsonParser/StaticJsonObject.cpp @@ -0,0 +1,69 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeJson(StaticJsonObject&)") { + SECTION("BufferOfTheRightSizeForEmptyObject") { + StaticJsonObject obj; + char input[] = "{}"; + + bool success = deserializeJson(obj, input); + + REQUIRE(success == true); + } + + SECTION("TooSmallBufferForObjectWithOneValue") { + StaticJsonObject obj; + char input[] = "{\"a\":1}"; + + bool success = deserializeJson(obj, input); + + REQUIRE(success == false); + } + + SECTION("BufferOfTheRightSizeForObjectWithOneValue") { + StaticJsonObject obj; + char input[] = "{\"a\":1}"; + + bool success = deserializeJson(obj, input); + + REQUIRE(success == true); + } + + SECTION("TooSmallBufferForObjectWithNestedObject") { + StaticJsonObject obj; + char input[] = "{\"a\":[]}"; + + bool success = deserializeJson(obj, input); + + REQUIRE(success == false); + } + + SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { + StaticJsonObject obj; + char input[] = "{\"a\":[]}"; + + bool success = deserializeJson(obj, input); + + REQUIRE(success == true); + } + + SECTION("CharPtrNull") { + StaticJsonObject<100> obj; + + bool success = deserializeJson(obj, static_cast(0)); + + REQUIRE(success == false); + } + + SECTION("ConstCharPtrNull") { + StaticJsonObject<100> obj; + + bool success = deserializeJson(obj, static_cast(0)); + + REQUIRE(success == false); + } +} diff --git a/test/JsonBuffer/nestingLimit.cpp b/test/JsonParser/nestingLimit.cpp similarity index 87% rename from test/JsonBuffer/nestingLimit.cpp rename to test/JsonParser/nestingLimit.cpp index 0d7be1151..290dae67f 100644 --- a/test/JsonBuffer/nestingLimit.cpp +++ b/test/JsonParser/nestingLimit.cpp @@ -6,13 +6,13 @@ #include bool tryParseArray(const char *json, uint8_t nestingLimit) { - DynamicJsonBuffer buffer; - return buffer.parseArray(json, nestingLimit).success(); + DynamicJsonArray array; + return deserializeJson(array, json, nestingLimit); } bool tryParseObject(const char *json, uint8_t nestingLimit) { - DynamicJsonBuffer buffer; - return buffer.parseObject(json, nestingLimit).success(); + DynamicJsonObject obj; + return deserializeJson(obj, json, nestingLimit); } TEST_CASE("JsonParser nestingLimit") { diff --git a/test/JsonVariant/as.cpp b/test/JsonVariant/as.cpp index 6d3b11cc2..bf03b1b65 100644 --- a/test/JsonVariant/as.cpp +++ b/test/JsonVariant/as.cpp @@ -192,9 +192,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ObjectAsString") { - DynamicJsonBuffer buffer; + DynamicJsonObject obj; - JsonObject& obj = buffer.createObject(); obj["key"] = "value"; JsonVariant variant = obj; @@ -202,9 +201,7 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ArrayAsString") { - DynamicJsonBuffer buffer; - - JsonArray& arr = buffer.createArray(); + DynamicJsonArray arr; arr.add(4); arr.add(2); @@ -213,8 +210,7 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ArrayAsJsonArray") { - DynamicJsonBuffer buffer; - JsonArray& arr = buffer.createArray(); + DynamicJsonArray arr; JsonVariant variant = arr; REQUIRE(&arr == &variant.as()); @@ -222,11 +218,10 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ObjectAsJsonObject") { - DynamicJsonBuffer buffer; - JsonObject& arr = buffer.createObject(); + DynamicJsonObject obj; - JsonVariant variant = arr; - REQUIRE(&arr == &variant.as()); - REQUIRE(&arr == &variant.as()); // <- shorthand + JsonVariant variant = obj; + REQUIRE(&obj == &variant.as()); + REQUIRE(&obj == &variant.as()); // <- shorthand } } diff --git a/test/JsonVariant/compare.cpp b/test/JsonVariant/compare.cpp index 965ec8efc..0364ec443 100644 --- a/test/JsonVariant/compare.cpp +++ b/test/JsonVariant/compare.cpp @@ -97,8 +97,8 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("StringLiteral") { - DynamicJsonBuffer jsonBuffer; - JsonVariant variant = jsonBuffer.parse("\"hello\""); + DynamicJsonVariant variant; + deserializeJson(variant, "\"hello\""); REQUIRE(variant == "hello"); REQUIRE_FALSE(variant != "hello"); @@ -114,8 +114,8 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("String") { - DynamicJsonBuffer jsonBuffer; - JsonVariant variant = jsonBuffer.parse("\"hello\""); + DynamicJsonVariant variant; + deserializeJson(variant, "\"hello\""); REQUIRE(variant == std::string("hello")); REQUIRE_FALSE(variant != std::string("hello")); @@ -179,9 +179,7 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("ArrayInVariant") { - DynamicJsonBuffer jsonBuffer; - JsonArray& array1 = jsonBuffer.createArray(); - JsonArray& array2 = jsonBuffer.createArray(); + DynamicJsonArray array1, array2; JsonVariant variant1 = array1; JsonVariant variant2 = array1; @@ -195,9 +193,8 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("ObjectInVariant") { - DynamicJsonBuffer jsonBuffer; - JsonObject& obj1 = jsonBuffer.createObject(); - JsonObject& obj2 = jsonBuffer.createObject(); + DynamicJsonObject obj1; + DynamicJsonObject obj2; JsonVariant variant1 = obj1; JsonVariant variant2 = obj1; @@ -211,14 +208,10 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("VariantsOfDifferentTypes") { - DynamicJsonBuffer jsonBuffer; + DynamicJsonObject obj; + DynamicJsonArray arr; JsonVariant variants[] = { - true, - 42, - 666.667, - "hello", - jsonBuffer.createArray(), - jsonBuffer.createObject(), + true, 42, 666.667, "hello", arr, obj, }; size_t n = sizeof(variants) / sizeof(variants[0]); diff --git a/test/JsonVariant/copy.cpp b/test/JsonVariant/copy.cpp index 50e0a3bf1..ebd8b90b1 100644 --- a/test/JsonVariant/copy.cpp +++ b/test/JsonVariant/copy.cpp @@ -6,7 +6,6 @@ #include TEST_CASE("JsonVariant copy") { - DynamicJsonBuffer _jsonBuffer; JsonVariant _variant1; JsonVariant _variant2; @@ -43,7 +42,7 @@ TEST_CASE("JsonVariant copy") { } SECTION("ObjectsAreCopiedByReference") { - JsonObject &object = _jsonBuffer.createObject(); + DynamicJsonObject object; _variant1 = object; @@ -53,7 +52,7 @@ TEST_CASE("JsonVariant copy") { } SECTION("ArraysAreCopiedByReference") { - JsonArray &array = _jsonBuffer.createArray(); + DynamicJsonArray array; _variant1 = array; diff --git a/test/JsonVariant/is.cpp b/test/JsonVariant/is.cpp index 1bb03cbbc..7ecfdcdf9 100644 --- a/test/JsonVariant/is.cpp +++ b/test/JsonVariant/is.cpp @@ -72,7 +72,8 @@ TEST_CASE("JsonVariant::is()") { DynamicJsonBuffer jsonBuffer; SECTION("JsonArray") { - checkIsArray(jsonBuffer.createArray()); + DynamicJsonArray array; + checkIsArray(array); } SECTION("bool") { diff --git a/test/JsonVariant/set_get.cpp b/test/JsonVariant/set_get.cpp index af68c8b05..ef6a09a97 100644 --- a/test/JsonVariant/set_get.cpp +++ b/test/JsonVariant/set_get.cpp @@ -122,9 +122,8 @@ TEST_CASE("JsonVariant set()/get()") { #endif SECTION("CanStoreObject") { - DynamicJsonBuffer jsonBuffer; - JsonObject &object = jsonBuffer.createObject(); + DynamicJsonObject object; - checkReference(object); + checkReference(object); } } diff --git a/test/JsonVariant/subscript.cpp b/test/JsonVariant/subscript.cpp index 5ce13e6f6..122ba47c8 100644 --- a/test/JsonVariant/subscript.cpp +++ b/test/JsonVariant/subscript.cpp @@ -6,10 +6,8 @@ #include TEST_CASE("JsonVariant::operator[]") { - DynamicJsonBuffer _jsonBuffer; - SECTION("Array") { - JsonArray &array = _jsonBuffer.createArray(); + DynamicJsonArray array; array.add("element at index 0"); array.add("element at index 1"); @@ -26,7 +24,7 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("Object") { - JsonObject &object = _jsonBuffer.createObject(); + DynamicJsonObject object; object["a"] = "element at key \"a\""; object["b"] = "element at key \"b\""; @@ -54,21 +52,24 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("ObjectSetValue") { - JsonVariant var = _jsonBuffer.createObject(); + DynamicJsonObject obj; + JsonVariant var = obj; var["hello"] = "world"; REQUIRE(1 == var.size()); REQUIRE(std::string("world") == var["hello"]); } SECTION("ArraySetValue") { - JsonVariant var = _jsonBuffer.parseArray("[\"hello\"]"); + DynamicJsonVariant var; + deserializeJson(var, "[\"hello\"]"); var[0] = "world"; REQUIRE(1 == var.size()); REQUIRE(std::string("world") == var[0]); } SECTION("NestedObjectSetValue") { - JsonVariant var = _jsonBuffer.parseArray("[{}]"); + DynamicJsonVariant var; + deserializeJson(var, "[{}]"); var[0]["hello"] = "world"; REQUIRE(1 == var.size()); REQUIRE(1 == var[0].size()); diff --git a/test/JsonVariant/success.cpp b/test/JsonVariant/success.cpp index af8aad940..a06fbf236 100644 --- a/test/JsonVariant/success.cpp +++ b/test/JsonVariant/success.cpp @@ -17,16 +17,16 @@ TEST_CASE("JsonVariant::success()") { } SECTION("ReturnsTrue_WhenEmptyArray") { - DynamicJsonBuffer jsonBuffer; + DynamicJsonArray array; - JsonVariant variant = jsonBuffer.createArray(); + JsonVariant variant = array; REQUIRE(true == variant.success()); } SECTION("ReturnsTrue_WhenEmptyObject") { - DynamicJsonBuffer jsonBuffer; + DynamicJsonObject obj; - JsonVariant variant = jsonBuffer.createObject(); + JsonVariant variant = obj; REQUIRE(true == variant.success()); } diff --git a/test/Misc/deprecated.cpp b/test/Misc/deprecated.cpp index 8fa4fe28d..b84ad65cd 100644 --- a/test/Misc/deprecated.cpp +++ b/test/Misc/deprecated.cpp @@ -16,15 +16,15 @@ #endif TEST_CASE("Deprecated functions") { - DynamicJsonBuffer jsonBuffer; - SECTION("JsonVariant::asArray()") { - JsonVariant variant = jsonBuffer.createArray(); + DynamicJsonArray array; + JsonVariant variant = array; REQUIRE(variant.asArray().success()); } SECTION("JsonVariant::asObject()") { - JsonVariant variant = jsonBuffer.createObject(); + DynamicJsonObject obj; + JsonVariant variant = obj; REQUIRE(variant.asObject().success()); } @@ -34,7 +34,7 @@ TEST_CASE("Deprecated functions") { } SECTION("JsonArray::removeAt()") { - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.removeAt(0); } @@ -59,7 +59,7 @@ TEST_CASE("Deprecated functions") { } SECTION("JsonArraySubscript::set(double, uint8_t)") { - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add(666); arr[0].set(123.45, 2); REQUIRE(123.45 == arr[0].as()); @@ -68,26 +68,26 @@ TEST_CASE("Deprecated functions") { } SECTION("JsonArray::add(double, uint8_t)") { - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add(3.14159265358979323846, 4); } SECTION("JsonArray::add(float, uint8_t)") { - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add(3.14159265358979323846f, 4); } SECTION("JsonObject::set(unsigned char[], double, uint8_t)") { unsigned char key[] = "hello"; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set(key, 3.14, 2); REQUIRE(3.14 == obj["hello"]); } SECTION("JsonObject::set(const char*, double, uint8_t)") { - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set("hello", 123.45, 2); REQUIRE(123.45 == obj["hello"].as()); @@ -96,7 +96,7 @@ TEST_CASE("Deprecated functions") { } SECTION("JsonObjectSubscript::set(double, uint8_t)") { - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj["hello"].set(123.45, 2); REQUIRE(true == obj["hello"].is()); diff --git a/test/Misc/std_stream.cpp b/test/Misc/std_stream.cpp index 170c9418a..9af55894e 100644 --- a/test/Misc/std_stream.cpp +++ b/test/Misc/std_stream.cpp @@ -23,8 +23,7 @@ TEST_CASE("std::stream") { SECTION("JsonObject") { std::ostringstream os; - DynamicJsonBuffer jsonBuffer; - JsonObject& object = jsonBuffer.createObject(); + DynamicJsonObject object; object["key"] = "value"; os << object; REQUIRE("{\"key\":\"value\"}" == os.str()); @@ -32,8 +31,7 @@ TEST_CASE("std::stream") { SECTION("JsonObjectSubscript") { std::ostringstream os; - DynamicJsonBuffer jsonBuffer; - JsonObject& object = jsonBuffer.createObject(); + DynamicJsonObject object; object["key"] = "value"; os << object["key"]; REQUIRE("\"value\"" == os.str()); @@ -41,8 +39,7 @@ TEST_CASE("std::stream") { SECTION("JsonArray") { std::ostringstream os; - DynamicJsonBuffer jsonBuffer; - JsonArray& array = jsonBuffer.createArray(); + DynamicJsonArray array; array.add("value"); os << array; REQUIRE("[\"value\"]" == os.str()); @@ -50,8 +47,7 @@ TEST_CASE("std::stream") { SECTION("JsonArraySubscript") { std::ostringstream os; - DynamicJsonBuffer jsonBuffer; - JsonArray& array = jsonBuffer.createArray(); + DynamicJsonArray array; array.add("value"); os << array[0]; REQUIRE("\"value\"" == os.str()); @@ -59,26 +55,28 @@ TEST_CASE("std::stream") { SECTION("ParseArray") { std::istringstream json(" [ 42 /* comment */ ] "); - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.parseArray(json); - REQUIRE(true == arr.success()); + DynamicJsonArray arr; + bool success = deserializeJson(arr, json); + + REQUIRE(true == success); REQUIRE(1 == arr.size()); REQUIRE(42 == arr[0]); } SECTION("ParseObject") { std::istringstream json(" { hello : world // comment\n }"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject(json); - REQUIRE(true == obj.success()); + DynamicJsonObject obj; + bool success = deserializeJson(obj, json); + + REQUIRE(true == success); REQUIRE(1 == obj.size()); REQUIRE(std::string("world") == obj["hello"]); } SECTION("ShouldNotReadPastTheEnd") { std::istringstream json("{}123"); - DynamicJsonBuffer jsonBuffer; - jsonBuffer.parseObject(json); + DynamicJsonObject obj; + deserializeJson(obj, json); REQUIRE('1' == json.get()); } } diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index aeb188ddf..e164f8bd2 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -13,231 +13,224 @@ static void eraseString(std::string &str) { TEST_CASE("std::string") { DynamicJsonBuffer jb; - SECTION("JsonBuffer_ParseArray") { - std::string json("[\"hello\"]"); - JsonArray &array = jb.parseArray(json); - eraseString(json); - REQUIRE(true == array.success()); - REQUIRE(std::string("hello") == array[0]); - } - - SECTION("JsonBuffer_ParseObject") { - std::string json("{\"hello\":\"world\"}"); - JsonObject &object = jb.parseObject(json); - eraseString(json); - REQUIRE(true == object.success()); - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonObject_Subscript") { - char json[] = "{\"key\":\"value\"}"; - JsonObject &object = jb.parseObject(json); - REQUIRE(std::string("value") == object[std::string("key")]); - } - - SECTION("JsonObject_ConstSubscript") { - char json[] = "{\"key\":\"value\"}"; - const JsonObject &object = jb.parseObject(json); - REQUIRE(std::string("value") == object[std::string("key")]); - } - - SECTION("JsonObject_SetKey") { - JsonObject &object = jb.createObject(); - std::string key("hello"); - object.set(key, "world"); - eraseString(key); - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonObject_SetValue") { - JsonObject &object = jb.createObject(); - std::string value("world"); - object.set("hello", value); - eraseString(value); - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonObject_SetKeyValue") { - JsonObject &object = jb.createObject(); - std::string key("hello"); - std::string value("world"); - object.set(key, value); - eraseString(key); - eraseString(value); - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonObject_SetToArraySubscript") { - JsonArray &arr = jb.createArray(); - arr.add("world"); - - JsonObject &object = jb.createObject(); - object.set(std::string("hello"), arr[0]); - - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonObject_SetToObjectSubscript") { - JsonObject &arr = jb.createObject(); - arr.set("x", "world"); - - JsonObject &object = jb.createObject(); - object.set(std::string("hello"), arr["x"]); - - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonObject_Get") { - char json[] = "{\"key\":\"value\"}"; - const JsonObject &object = jb.parseObject(json); - REQUIRE(std::string("value") == - object.get(std::string("key"))); - } - - SECTION("JsonObject_GetT") { - char json[] = "{\"key\":\"value\"}"; - const JsonObject &object = jb.parseObject(json); - REQUIRE(std::string("value") == - object.get(std::string("key"))); - } - - SECTION("JsonObject_IsT") { - char json[] = "{\"key\":\"value\"}"; - const JsonObject &object = jb.parseObject(json); - REQUIRE(true == object.is(std::string("key"))); - } - - SECTION("JsonObject_CreateNestedObject") { - std::string key = "key"; - char json[64]; - JsonObject &object = jb.createObject(); - object.createNestedObject(key); - eraseString(key); - object.printTo(json, sizeof(json)); - REQUIRE(std::string("{\"key\":{}}") == json); - } - - SECTION("JsonObject_CreateNestedArray") { - std::string key = "key"; - char json[64]; - JsonObject &object = jb.createObject(); - object.createNestedArray(key); - eraseString(key); - object.printTo(json, sizeof(json)); - REQUIRE(std::string("{\"key\":[]}") == json); - } - - SECTION("JsonObject_ContainsKey") { - char json[] = "{\"key\":\"value\"}"; - const JsonObject &object = jb.parseObject(json); - REQUIRE(true == object.containsKey(std::string("key"))); - } - - SECTION("JsonObject_Remove") { - char json[] = "{\"key\":\"value\"}"; - JsonObject &object = jb.parseObject(json); - REQUIRE(1 == object.size()); - object.remove(std::string("key")); - REQUIRE(0 == object.size()); - } - - SECTION("JsonObjectSubscript_SetKey") { - JsonObject &object = jb.createObject(); - std::string key("hello"); - object[key] = "world"; - eraseString(key); - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonObjectSubscript_SetValue") { - JsonObject &object = jb.createObject(); - std::string value("world"); - object["hello"] = value; - eraseString(value); - REQUIRE(std::string("world") == object["hello"]); - } - - SECTION("JsonArray_Add") { - JsonArray &array = jb.createArray(); - std::string value("hello"); - array.add(value); - eraseString(value); - REQUIRE(std::string("hello") == array[0]); - } - - SECTION("JsonArray_Set") { - JsonArray &array = jb.createArray(); - std::string value("world"); - array.add("hello"); - array.set(0, value); - eraseString(value); - REQUIRE(std::string("world") == array[0]); - } - - SECTION("JsonArraySubscript") { - JsonArray &array = jb.createArray(); - std::string value("world"); - array.add("hello"); - array[0] = value; - eraseString(value); - REQUIRE(std::string("world") == array[0]); - } - - SECTION("JsonArray_PrintTo") { - JsonArray &array = jb.createArray(); - array.add(4); - array.add(2); - std::string json; - array.printTo(json); - REQUIRE(std::string("[4,2]") == json); - } - - SECTION("JsonArray_PrettyPrintTo") { - JsonArray &array = jb.createArray(); - array.add(4); - array.add(2); - std::string json; - array.prettyPrintTo(json); - REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json); - } - - SECTION("JsonObject_PrintTo") { - JsonObject &object = jb.createObject(); - object["key"] = "value"; - std::string json; - object.printTo(json); - REQUIRE(std::string("{\"key\":\"value\"}") == json); - } - - SECTION("JsonObject_PrettyPrintTo") { - JsonObject &object = jb.createObject(); - object["key"] = "value"; - std::string json; - object.prettyPrintTo(json); - REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); - } - - SECTION("JsonBuffer_GrowWhenAddingNewKey") { - JsonObject &object = jb.createObject(); - std::string key1("hello"), key2("world"); - - object[key1] = 1; - size_t sizeBefore = jb.size(); - object[key2] = 2; - size_t sizeAfter = jb.size(); - - REQUIRE(sizeAfter - sizeBefore >= key2.size()); - } - - SECTION("JsonBuffer_DontGrowWhenReusingKey") { - JsonObject &object = jb.createObject(); - std::string key("hello"); - - object[key] = 1; - size_t sizeBefore = jb.size(); - object[key] = 2; - size_t sizeAfter = jb.size(); - - REQUIRE(sizeBefore == sizeAfter); + SECTION("JsonArray") { + DynamicJsonArray array; + + SECTION("deserializeJson") { + std::string json("[\"hello\"]"); + + bool success = deserializeJson(array, json); + eraseString(json); + + REQUIRE(true == success); + REQUIRE(std::string("hello") == array[0]); + } + + SECTION("add()") { + std::string value("hello"); + array.add(value); + eraseString(value); + REQUIRE(std::string("hello") == array[0]); + } + + SECTION("set()") { + std::string value("world"); + array.add("hello"); + array.set(0, value); + eraseString(value); + REQUIRE(std::string("world") == array[0]); + } + + SECTION("operator[]") { + std::string value("world"); + array.add("hello"); + array[0] = value; + eraseString(value); + REQUIRE(std::string("world") == array[0]); + } + + SECTION("printTo()") { + array.add(4); + array.add(2); + std::string json; + array.printTo(json); + REQUIRE(std::string("[4,2]") == json); + } + + SECTION("prettyPrintTo") { + array.add(4); + array.add(2); + std::string json; + array.prettyPrintTo(json); + REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json); + } + } + + SECTION("JsonObject") { + DynamicJsonObject object; + + SECTION("deserializeJson") { + std::string json("{\"hello\":\"world\"}"); + + bool success = deserializeJson(object, json); + eraseString(json); + + REQUIRE(true == success); + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("operator[]") { + char json[] = "{\"key\":\"value\"}"; + + deserializeJson(object, json); + + REQUIRE(std::string("value") == object[std::string("key")]); + } + + SECTION("operator[] const") { + char json[] = "{\"key\":\"value\"}"; + + deserializeJson(object, json); + const JsonObject &obj = object; + + REQUIRE(std::string("value") == obj[std::string("key")]); + } + + SECTION("set(key)") { + std::string key("hello"); + object.set(key, "world"); + eraseString(key); + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("set(value)") { + std::string value("world"); + object.set("hello", value); + eraseString(value); + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("set(key,value)") { + std::string key("hello"); + std::string value("world"); + object.set(key, value); + eraseString(key); + eraseString(value); + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("set(JsonArraySubscript)") { + DynamicJsonArray arr; + arr.add("world"); + + object.set(std::string("hello"), arr[0]); + + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("set(JsonObjectSubscript)") { + DynamicJsonObject obj; + obj.set("x", "world"); + + object.set(std::string("hello"), obj["x"]); + + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("get()") { + char json[] = "{\"key\":\"value\"}"; + deserializeJson(object, json); + + REQUIRE(std::string("value") == + object.get(std::string("key"))); + } + + SECTION("is()") { + char json[] = "{\"key\":\"value\"}"; + deserializeJson(object, json); + REQUIRE(true == object.is(std::string("key"))); + } + + SECTION("createNestedObject()") { + std::string key = "key"; + char json[64]; + object.createNestedObject(key); + eraseString(key); + object.printTo(json, sizeof(json)); + REQUIRE(std::string("{\"key\":{}}") == json); + } + + SECTION("createNestedArray()") { + std::string key = "key"; + char json[64]; + object.createNestedArray(key); + eraseString(key); + object.printTo(json, sizeof(json)); + REQUIRE(std::string("{\"key\":[]}") == json); + } + + SECTION("containsKey()") { + char json[] = "{\"key\":\"value\"}"; + deserializeJson(object, json); + REQUIRE(true == object.containsKey(std::string("key"))); + } + + SECTION("remove()") { + char json[] = "{\"key\":\"value\"}"; + deserializeJson(object, json); + REQUIRE(1 == object.size()); + object.remove(std::string("key")); + REQUIRE(0 == object.size()); + } + + SECTION("operator[], set key") { + std::string key("hello"); + object[key] = "world"; + eraseString(key); + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("operator[], set value") { + std::string value("world"); + object["hello"] = value; + eraseString(value); + REQUIRE(std::string("world") == object["hello"]); + } + + SECTION("printTo") { + object["key"] = "value"; + std::string json; + object.printTo(json); + REQUIRE(std::string("{\"key\":\"value\"}") == json); + } + + SECTION("prettyPrintTo") { + object["key"] = "value"; + std::string json; + object.prettyPrintTo(json); + REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); + } + + SECTION("memoryUsage() increases when adding a new key") { + std::string key1("hello"), key2("world"); + + object[key1] = 1; + size_t sizeBefore = object.memoryUsage(); + object[key2] = 2; + size_t sizeAfter = object.memoryUsage(); + + REQUIRE(sizeAfter - sizeBefore >= key2.size()); + } + + SECTION("memoryUsage() remains when adding the same key") { + std::string key("hello"); + + object[key] = 1; + size_t sizeBefore = object.memoryUsage(); + object[key] = 2; + size_t sizeAfter = object.memoryUsage(); + + REQUIRE(sizeBefore == sizeAfter); + } } } diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index ce1c474af..146a936c3 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -13,19 +13,19 @@ TEST_CASE("unsigned char string") { SECTION("JsonBuffer::parseArray") { unsigned char json[] = "[42]"; - StaticJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.parseArray(json); + StaticJsonArray arr; + bool success = deserializeJson(arr, json); - REQUIRE(true == arr.success()); + REQUIRE(true == success); } SECTION("JsonBuffer::parseObject") { unsigned char json[] = "{\"a\":42}"; - StaticJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject(json); + StaticJsonObject obj; + bool success = deserializeJson(obj, json); - REQUIRE(true == obj.success()); + REQUIRE(true == success); } SECTION("JsonVariant constructor") { @@ -49,8 +49,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator[]") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonVariant variant; + deserializeJson(variant, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == variant[key]); } @@ -60,8 +60,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator[] const") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - const JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonVariant variant; + deserializeJson(variant, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == variant[key]); } @@ -70,8 +70,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator==") { unsigned char comparand[] = "hello"; - DynamicJsonBuffer jsonBuffer; - const JsonVariant variant = "hello"; + DynamicJsonVariant variant; + variant = "hello"; REQUIRE(comparand == variant); REQUIRE(variant == comparand); @@ -82,8 +82,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator!=") { unsigned char comparand[] = "hello"; - DynamicJsonBuffer jsonBuffer; - const JsonVariant variant = "world"; + DynamicJsonVariant variant; + variant = "world"; REQUIRE(comparand != variant); REQUIRE(variant != comparand); @@ -95,8 +95,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::operator[]") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj[key] = "world"; REQUIRE(std::string("world") == obj["hello"]); @@ -106,8 +105,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonObjectSubscript::operator=") { // issue #416 unsigned char value[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj["hello"] = value; REQUIRE(std::string("world") == obj["hello"]); @@ -116,8 +114,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonObjectSubscript::set()") { unsigned char value[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj["hello"].set(value); REQUIRE(std::string("world") == obj["hello"]); @@ -127,8 +124,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::operator[] const") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == obj[key]); } @@ -137,8 +134,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::get()") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == obj.get(key)); } @@ -146,8 +143,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::set() key") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set(key, "world"); REQUIRE(std::string("world") == obj["hello"]); @@ -156,8 +152,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::set() value") { unsigned char value[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set("hello", value); REQUIRE(std::string("world") == obj["hello"]); @@ -166,8 +161,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::set key&value") { unsigned char key[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set(key, key); REQUIRE(std::string("world") == obj["world"]); @@ -176,8 +170,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::containsKey()") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); REQUIRE(true == obj.containsKey(key)); } @@ -185,8 +179,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::remove()") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); obj.remove(key); REQUIRE(0 == obj.size()); @@ -195,8 +189,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::is()") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject("{\"hello\":42}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":42}"); REQUIRE(true == obj.is(key)); } @@ -204,24 +198,21 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::createNestedArray()") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.createNestedArray(key); } SECTION("JsonObject::createNestedObject()") { unsigned char key[] = "hello"; - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.createNestedObject(key); } SECTION("JsonArray::add()") { unsigned char value[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add(value); REQUIRE(std::string("world") == arr[0]); @@ -230,8 +221,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonArray::set()") { unsigned char value[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add("hello"); arr.set(0, value); @@ -241,8 +231,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonArraySubscript::set()") { unsigned char value[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add("hello"); arr[0].set(value); @@ -252,8 +241,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonArraySubscript::operator=") { unsigned char value[] = "world"; - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add("hello"); arr[0] = value; diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index e9d1cb676..9c16f5102 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -22,10 +22,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "[42]"); - StaticJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.parseArray(vla); + StaticJsonArray arr; + bool success = deserializeJson(arr, vla); - REQUIRE(true == arr.success()); + REQUIRE(true == success); } SECTION("ParseObject") { @@ -33,8 +33,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "{\"a\":42}"); - StaticJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject(vla); + StaticJsonObject obj; + deserializeJson(obj, vla); REQUIRE(true == obj.success()); } @@ -44,8 +44,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "42"); - StaticJsonBuffer<1> jsonBuffer; - JsonVariant variant = jsonBuffer.parse(vla); + StaticJsonVariant<> variant; + deserializeJson(variant, vla); REQUIRE(42 == variant.as()); } @@ -77,8 +77,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonVariant variant; + deserializeJson(variant, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == variant[vla]); } @@ -90,8 +90,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - const JsonVariant variant = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonVariant variant; + deserializeJson(variant, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == variant[vla]); } @@ -102,8 +102,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - const JsonVariant variant = "hello"; + DynamicJsonVariant variant; + variant = "hello"; REQUIRE((vla == variant)); REQUIRE((variant == vla)); @@ -116,8 +116,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - const JsonVariant variant = "world"; + DynamicJsonVariant variant; + variant = "world"; REQUIRE((vla != variant)); REQUIRE((variant != vla)); @@ -131,8 +131,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj[vla] = "world"; REQUIRE(std::string("world") == obj["hello"]); @@ -144,8 +143,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj["hello"] = vla; REQUIRE(std::string("world") == obj["hello"].as()); @@ -156,8 +154,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj["hello"].set(vla); REQUIRE(std::string("world") == obj["hello"].as()); @@ -169,8 +166,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == obj[vla]); } @@ -181,8 +178,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); REQUIRE(std::string("world") == obj.get(vla)); } @@ -192,8 +189,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set(vla, "world"); REQUIRE(std::string("world") == obj["hello"]); @@ -204,8 +200,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set("hello", vla); REQUIRE(std::string("world") == obj["hello"]); @@ -216,8 +211,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.set(vla, vla); REQUIRE(std::string("world") == obj["world"]); @@ -228,8 +222,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - const JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); REQUIRE(true == obj.containsKey(vla)); } @@ -239,8 +233,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject("{\"hello\":\"world\"}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":\"world\"}"); obj.remove(vla); REQUIRE(0 == obj.size()); @@ -251,8 +245,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.parseObject("{\"hello\":42}"); + DynamicJsonObject obj; + deserializeJson(obj, "{\"hello\":42}"); REQUIRE(true == obj.is(vla)); } @@ -262,8 +256,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.createNestedArray(vla); } @@ -272,8 +265,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonBuffer jsonBuffer; - JsonObject& obj = jsonBuffer.createObject(); + DynamicJsonObject obj; obj.createNestedObject(vla); } @@ -282,8 +274,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add(vla); REQUIRE(std::string("world") == arr[0]); @@ -294,8 +285,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add("hello"); arr.set(0, vla); @@ -307,8 +297,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add("hello"); arr[0].set(vla); @@ -320,8 +309,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonBuffer jsonBuffer; - JsonArray& arr = jsonBuffer.createArray(); + DynamicJsonArray arr; arr.add("hello"); arr[0] = vla; diff --git a/test/StaticJsonBuffer/CMakeLists.txt b/test/StaticJsonBuffer/CMakeLists.txt index 00c78dfa5..0be97fbee 100644 --- a/test/StaticJsonBuffer/CMakeLists.txt +++ b/test/StaticJsonBuffer/CMakeLists.txt @@ -4,10 +4,6 @@ add_executable(StaticJsonBufferTests alloc.cpp - createArray.cpp - createObject.cpp - parseArray.cpp - parseObject.cpp size.cpp startString.cpp ) diff --git a/test/StaticJsonBuffer/createArray.cpp b/test/StaticJsonBuffer/createArray.cpp deleted file mode 100644 index 9f0d3bd5f..000000000 --- a/test/StaticJsonBuffer/createArray.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("StaticJsonBuffer::createArray()") { - SECTION("GrowsWithArray") { - StaticJsonBuffer json; - - JsonArray &array = json.createArray(); - REQUIRE(JSON_ARRAY_SIZE(0) == json.size()); - - array.add("hello"); - REQUIRE(JSON_ARRAY_SIZE(1) == json.size()); - - array.add("world"); - REQUIRE(JSON_ARRAY_SIZE(2) == json.size()); - } - - SECTION("SucceedWhenBigEnough") { - StaticJsonBuffer json; - - JsonArray &array = json.createArray(); - REQUIRE(array.success()); - } - - SECTION("FailsWhenTooSmall") { - StaticJsonBuffer json; - - JsonArray &array = json.createArray(); - REQUIRE_FALSE(array.success()); - } - - SECTION("ArrayDoesntGrowWhenFull") { - StaticJsonBuffer json; - - JsonArray &array = json.createArray(); - array.add("hello"); - array.add("world"); - - REQUIRE(1 == array.size()); - } -} diff --git a/test/StaticJsonBuffer/createObject.cpp b/test/StaticJsonBuffer/createObject.cpp deleted file mode 100644 index c51e9bb95..000000000 --- a/test/StaticJsonBuffer/createObject.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("StaticJsonBuffer::createObject()") { - SECTION("GrowsWithObject") { - StaticJsonBuffer buffer; - - JsonObject &obj = buffer.createObject(); - REQUIRE(JSON_OBJECT_SIZE(0) == buffer.size()); - - obj["hello"]; - REQUIRE(JSON_OBJECT_SIZE(0) == buffer.size()); - - obj["hello"] = 1; - REQUIRE(JSON_OBJECT_SIZE(1) == buffer.size()); - - obj["world"] = 2; - REQUIRE(JSON_OBJECT_SIZE(2) == buffer.size()); - - obj["world"] = 3; // <- same key, should not grow - REQUIRE(JSON_OBJECT_SIZE(2) == buffer.size()); - } - - SECTION("SucceedWhenBigEnough") { - StaticJsonBuffer buffer; - - JsonObject &object = buffer.createObject(); - REQUIRE(object.success()); - } - - SECTION("FailsWhenTooSmall") { - StaticJsonBuffer buffer; - - JsonObject &object = buffer.createObject(); - REQUIRE_FALSE(object.success()); - } - - SECTION("ObjectDoesntGrowWhenFull") { - StaticJsonBuffer buffer; - - JsonObject &obj = buffer.createObject(); - obj["hello"] = 1; - obj["world"] = 2; - - REQUIRE(JSON_OBJECT_SIZE(1) == buffer.size()); - REQUIRE(1 == obj.size()); - - char json[64]; - obj.printTo(json, sizeof(json)); - REQUIRE(std::string("{\"hello\":1}") == json); - } -} diff --git a/test/StaticJsonBuffer/parseArray.cpp b/test/StaticJsonBuffer/parseArray.cpp deleted file mode 100644 index f2feda995..000000000 --- a/test/StaticJsonBuffer/parseArray.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("StaticJsonBuffer::parseArray()") { - SECTION("TooSmallBufferForEmptyArray") { - StaticJsonBuffer bufferTooSmall; - char input[] = "[]"; - JsonArray& arr = bufferTooSmall.parseArray(input); - REQUIRE_FALSE(arr.success()); - } - - SECTION("BufferOfTheRightSizeForEmptyArray") { - StaticJsonBuffer bufferOfRightSize; - char input[] = "[]"; - JsonArray& arr = bufferOfRightSize.parseArray(input); - REQUIRE(arr.success()); - } - - SECTION("TooSmallBufferForArrayWithOneValue") { - StaticJsonBuffer bufferTooSmall; - char input[] = "[1]"; - JsonArray& arr = bufferTooSmall.parseArray(input); - REQUIRE_FALSE(arr.success()); - } - - SECTION("BufferOfTheRightSizeForArrayWithOneValue") { - StaticJsonBuffer bufferOfRightSize; - char input[] = "[1]"; - JsonArray& arr = bufferOfRightSize.parseArray(input); - REQUIRE(arr.success()); - } - - SECTION("TooSmallBufferForArrayWithNestedObject") { - StaticJsonBuffer - bufferTooSmall; - char input[] = "[{}]"; - JsonArray& arr = bufferTooSmall.parseArray(input); - REQUIRE_FALSE(arr.success()); - } - - SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { - StaticJsonBuffer - bufferOfRightSize; - char input[] = "[{}]"; - JsonArray& arr = bufferOfRightSize.parseArray(input); - REQUIRE(arr.success()); - } - - SECTION("CharPtrNull") { - REQUIRE_FALSE( - StaticJsonBuffer<100>().parseArray(static_cast(0)).success()); - } - - SECTION("ConstCharPtrNull") { - REQUIRE_FALSE(StaticJsonBuffer<100>() - .parseArray(static_cast(0)) - .success()); - } - - SECTION("CopyStringNotSpaces") { - StaticJsonBuffer<100> jsonBuffer; - jsonBuffer.parseArray(" [ \"1234567\" ] "); - REQUIRE(JSON_ARRAY_SIZE(1) + sizeof("1234567") == jsonBuffer.size()); - // note we use a string of 8 bytes to be sure that the StaticJsonBuffer - // will not insert bytes to enforce alignement - } -} diff --git a/test/StaticJsonBuffer/parseObject.cpp b/test/StaticJsonBuffer/parseObject.cpp deleted file mode 100644 index 83601d672..000000000 --- a/test/StaticJsonBuffer/parseObject.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include -TEST_CASE("StaticJsonBuffer::parseObject()") { - SECTION("TooSmallBufferForEmptyObject") { - StaticJsonBuffer bufferTooSmall; - char input[] = "{}"; - JsonObject& obj = bufferTooSmall.parseObject(input); - REQUIRE_FALSE(obj.success()); - } - - SECTION("BufferOfTheRightSizeForEmptyObject") { - StaticJsonBuffer bufferOfRightSize; - char input[] = "{}"; - JsonObject& obj = bufferOfRightSize.parseObject(input); - REQUIRE(obj.success()); - } - - SECTION("TooSmallBufferForObjectWithOneValue") { - StaticJsonBuffer bufferTooSmall; - char input[] = "{\"a\":1}"; - JsonObject& obj = bufferTooSmall.parseObject(input); - REQUIRE_FALSE(obj.success()); - } - - SECTION("BufferOfTheRightSizeForObjectWithOneValue") { - StaticJsonBuffer bufferOfRightSize; - char input[] = "{\"a\":1}"; - JsonObject& obj = bufferOfRightSize.parseObject(input); - REQUIRE(obj.success()); - } - - SECTION("TooSmallBufferForObjectWithNestedObject") { - StaticJsonBuffer - bufferTooSmall; - char input[] = "{\"a\":[]}"; - JsonObject& obj = bufferTooSmall.parseObject(input); - REQUIRE_FALSE(obj.success()); - } - - SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { - StaticJsonBuffer - bufferOfRightSize; - char input[] = "{\"a\":[]}"; - JsonObject& obj = bufferOfRightSize.parseObject(input); - REQUIRE(obj.success()); - } - - SECTION("CharPtrNull") { - REQUIRE_FALSE( - StaticJsonBuffer<100>().parseObject(static_cast(0)).success()); - } - - SECTION("ConstCharPtrNull") { - REQUIRE_FALSE(StaticJsonBuffer<100>() - .parseObject(static_cast(0)) - .success()); - } -} From 83d73c93f7214a86dfd7a51cef4a6a6c1846001f Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 1 Mar 2018 09:24:58 +0100 Subject: [PATCH 0017/1079] Replaced `printTo()` with `serializeJson()` * Added `serializeJson()` and `serializeJsonPretty()` * Added `measureJson()` and `measureJsonPretty()` * Removed `printTo()` and `prettyPrintTo()` * Removed `measureLength()` and `measurePrettyLength()` --- CHANGELOG.md | 18 ++- README.md | 4 +- examples/JsonConfigFile/JsonConfigFile.ino | 2 +- .../JsonGeneratorExample.ino | 4 +- examples/JsonServer/JsonServer.ino | 4 +- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 4 +- examples/StringExample/StringExample.ino | 2 +- keywords.txt | 25 ++-- .../Deserialization/JsonParserImpl.hpp | 1 + src/ArduinoJson/JsonArray.hpp | 4 +- src/ArduinoJson/JsonArraySubscript.hpp | 11 +- src/ArduinoJson/JsonObject.hpp | 4 +- src/ArduinoJson/JsonObjectSubscript.hpp | 12 +- src/ArduinoJson/JsonVariant.hpp | 7 +- src/ArduinoJson/JsonVariantBase.hpp | 8 +- src/ArduinoJson/JsonVariantImpl.hpp | 6 - src/ArduinoJson/Serialization/DummyPrint.hpp | 6 +- .../Serialization/IndentedPrint.hpp | 6 +- .../Serialization/JsonPrintable.hpp | 117 ---------------- .../Serialization/JsonSerializer.hpp | 126 ++++++++++++++++++ src/ArduinoJson/Serialization/JsonWriter.hpp | 6 +- test/CMakeLists.txt | 1 + test/DynamicJsonBuffer/alloc.cpp | 3 +- test/IntegrationTests/round_trip.cpp | 4 +- test/JsonArray/CMakeLists.txt | 2 - test/JsonArray/copyFrom.cpp | 8 +- test/JsonArray/invalid.cpp | 2 +- test/JsonObject/CMakeLists.txt | 2 - test/JsonObject/invalid.cpp | 2 +- test/JsonObject/remove.cpp | 2 +- test/JsonSerializer/CMakeLists.txt | 14 ++ .../JsonArray.cpp} | 6 +- .../JsonArrayPretty.cpp} | 6 +- .../JsonObject.cpp} | 7 +- .../JsonObjectPretty.cpp} | 6 +- .../JsonVariant.cpp} | 4 +- test/JsonVariant/CMakeLists.txt | 3 +- test/Misc/std_string.cpp | 22 +-- 38 files changed, 238 insertions(+), 233 deletions(-) delete mode 100644 src/ArduinoJson/Serialization/JsonPrintable.hpp create mode 100644 test/JsonSerializer/CMakeLists.txt rename test/{JsonArray/printTo.cpp => JsonSerializer/JsonArray.cpp} (94%) rename test/{JsonArray/prettyPrintTo.cpp => JsonSerializer/JsonArrayPretty.cpp} (89%) rename test/{JsonObject/printTo.cpp => JsonSerializer/JsonObject.cpp} (94%) rename test/{JsonObject/prettyPrintTo.cpp => JsonSerializer/JsonObjectPretty.cpp} (90%) rename test/{JsonVariant/printTo.cpp => JsonSerializer/JsonVariant.cpp} (91%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84e7ddfba..20aaa183b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,16 @@ ArduinoJson: change log HEAD ---- -* Added DynamicJsonArray and StaticJsonArray -* Added DynamicJsonObject and StaticJsonObject -* Added DynamicJsonVariant and StaticJsonVariant -* Added deserializeJson() -* Removed JsonBuffer::parseArray(), parseObject() and parse() -* Removed JsonBuffer::createArray() and createObject() +* Added `DynamicJsonArray` and `StaticJsonArray` +* Added `DynamicJsonObject` and `StaticJsonObject` +* Added `DynamicJsonVariant` and `StaticJsonVariant` +* Added `deserializeJson()` +* Added `serializeJson()` and `serializeJsonPretty()` +* Added `measureJson()` and `measureJsonPretty()` +* Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` +* Removed `JsonBuffer::createArray()` and `createObject()` +* Removed `printTo()` and `prettyPrintTo()` +* Removed `measureLength()` and `measurePrettyLength()` > ### BREAKING CHANGES > @@ -51,7 +55,7 @@ HEAD > ```c++ > DynamicJsonObject obj; > obj["key"] = "value"; -> obj.printTo(Serial); +> serializeJson(obj, Serial); > ``` v5.13.1 diff --git a/README.md b/README.md index 7a398aca7..31fc6266e 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ Here is a program that parses a JSON document with ArduinoJson. char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; DynamicJsonObject root; -derserializeJson(root, json); +deserializeJson(root, json); const char* sensor = root["sensor"]; long time = root["time"]; @@ -83,7 +83,7 @@ JsonArray& data = root.createNestedArray("data"); data.add(48.756080); data.add(2.302038); -root.printTo(Serial); +serializeJson(root, Serial); // This prints: // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} ``` diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index 299447fc8..442a86511 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -72,7 +72,7 @@ void saveConfiguration(const char *filename, const Config &config) { root["port"] = config.port; // Serialize JSON to file - if (root.printTo(file) == 0) { + if (serializeJson(root, file) == 0) { Serial.println(F("Failed to write to file")); } diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index 4903b1144..ee22fe716 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -38,13 +38,13 @@ void setup() { data.add(48.756080); data.add(2.302038); - root.printTo(Serial); + serializeJson(root, Serial); // This prints: // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} Serial.println(); - root.prettyPrintTo(Serial); + serializeJsonPretty(root, Serial); // This prints: // { // "sensor": "gps", diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index ded6d5aba..677d5039a 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -76,7 +76,7 @@ void loop() { } Serial.print(F("Sending: ")); - root.printTo(Serial); + serializeJson(root, Serial); Serial.println(); // Write response headers @@ -86,7 +86,7 @@ void loop() { client.println(); // Write JSON document - root.prettyPrintTo(client); + serializeJsonPretty(root, client); // Disconnect client.stop(); diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index 3f912c68f..82c8b8ffe 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -72,11 +72,11 @@ void loop() { Serial.print(remoteIp); Serial.print(F(" on port ")); Serial.println(remotePort); - root.printTo(Serial); + serializeJson(root, Serial); // Send UDP packet udp.beginPacket(remoteIp, remotePort); - root.printTo(udp); + serializeJson(root, udp); udp.println(); udp.endPacket(); diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index 1ffed4581..a497651ae 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -54,7 +54,7 @@ void setup() { // Lastly, you can print the resulting JSON to a String String output; - root.printTo(output); + serializeJson(root, output); } void loop() { diff --git a/keywords.txt b/keywords.txt index 1bb6f1405..ae31a74c9 100644 --- a/keywords.txt +++ b/keywords.txt @@ -1,13 +1,18 @@ -JsonArray KEYWORD1 -JsonObject KEYWORD1 -JsonVariant KEYWORD1 -StaticJsonBuffer KEYWORD1 -DynamicJsonBuffer KEYWORD1 add KEYWORD2 +as KEYWORD2 createNestedArray KEYWORD2 createNestedObject KEYWORD2 -parseArray KEYWORD2 -parseObject KEYWORD2 -prettyPrintTo KEYWORD2 -printTo KEYWORD2 -success KEYWORD2 +deserializeJson KEYWORD2 +DynamicJsonArray KEYWORD1 +DynamicJsonObject KEYWORD1 +DynamicJsonVariant KEYWORD1 +get KEYWORD2 +JsonArray KEYWORD1 +JsonObject KEYWORD1 +JsonVariant KEYWORD1 +serializeJson KEYWORD2 +serializeJsonPretty KEYWORD2 +set KEYWORD2 +StaticJsonArray KEYWORD1 +StaticJsonObject KEYWORD1 +StaticJsonVariant KEYWORD1 diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 19ca8b7a2..3543d8703 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -4,6 +4,7 @@ #pragma once +#include "../Data/Encoding.hpp" #include "Comments.hpp" #include "JsonParser.hpp" diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 6ca712e2d..2a9dc26d9 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -9,7 +9,6 @@ #include "Data/ReferenceType.hpp" #include "Data/ValueSaver.hpp" #include "JsonVariant.hpp" -#include "Serialization/JsonPrintable.hpp" #include "StringTraits/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsArray.hpp" @@ -30,8 +29,7 @@ namespace Internals { class JsonArraySubscript; } -class JsonArray : public Internals::JsonPrintable, - public Internals::ReferenceType, +class JsonArray : public Internals::ReferenceType, public Internals::NonCopyable, public Internals::List, public Internals::JsonBufferAllocated { diff --git a/src/ArduinoJson/JsonArraySubscript.hpp b/src/ArduinoJson/JsonArraySubscript.hpp index afb4dc1ec..de40afc15 100644 --- a/src/ArduinoJson/JsonArraySubscript.hpp +++ b/src/ArduinoJson/JsonArraySubscript.hpp @@ -98,14 +98,7 @@ inline const JsonArraySubscript JsonVariantSubscripts::operator[]( size_t index) const { return impl()->template as()[index]; } - -#if ARDUINOJSON_ENABLE_STD_STREAM -inline std::ostream& operator<<(std::ostream& os, - const JsonArraySubscript& source) { - return source.printTo(os); -} -#endif -} +} // namespace Internals inline Internals::JsonArraySubscript JsonArray::operator[](size_t index) { return Internals::JsonArraySubscript(*this, index); @@ -115,7 +108,7 @@ inline const Internals::JsonArraySubscript JsonArray::operator[]( size_t index) const { return Internals::JsonArraySubscript(*const_cast(this), index); } -} +} // namespace ArduinoJson #ifdef _MSC_VER #pragma warning(pop) diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 1802e59f0..d182ae7a1 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -9,7 +9,6 @@ #include "Data/ReferenceType.hpp" #include "Data/ValueSaver.hpp" #include "JsonPair.hpp" -#include "Serialization/JsonPrintable.hpp" #include "StringTraits/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsArray.hpp" @@ -31,8 +30,7 @@ template class JsonObjectSubscript; } -class JsonObject : public Internals::JsonPrintable, - public Internals::ReferenceType, +class JsonObject : public Internals::ReferenceType, public Internals::NonCopyable, public Internals::List, public Internals::JsonBufferAllocated { diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index 6ac476370..e108f3f50 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -94,16 +94,8 @@ class JsonObjectSubscript JsonObject& _object; TStringRef _key; }; - -#if ARDUINOJSON_ENABLE_STD_STREAM -template -inline std::ostream& operator<<(std::ostream& os, - const JsonObjectSubscript& source) { - return source.printTo(os); -} -#endif -} -} +} // namespace Internals +} // namespace ArduinoJson #ifdef _MSC_VER #pragma warning(pop) diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index e5cb91486..9fffb4afd 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -12,7 +12,6 @@ #include "Data/JsonVariantType.hpp" #include "JsonVariantBase.hpp" #include "RawJson.hpp" -#include "Serialization/JsonPrintable.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsChar.hpp" #include "TypeTraits/IsFloatingPoint.hpp" @@ -28,6 +27,10 @@ namespace ArduinoJson { // Forward declarations. class JsonArray; class JsonObject; +namespace Internals { +template +class JsonSerializer; +} // A variant that can be a any value serializable to a JSON value. // @@ -194,7 +197,7 @@ class JsonVariant : public Internals::JsonVariantBase { const char *cstr = variantAsString(); if (cstr) return T(cstr); T s; - printTo(s); + serializeJson(*this, s); return s; } // diff --git a/src/ArduinoJson/JsonVariantBase.hpp b/src/ArduinoJson/JsonVariantBase.hpp index 44acf2e14..268326ca7 100644 --- a/src/ArduinoJson/JsonVariantBase.hpp +++ b/src/ArduinoJson/JsonVariantBase.hpp @@ -8,17 +8,15 @@ #include "JsonVariantComparisons.hpp" #include "JsonVariantOr.hpp" #include "JsonVariantSubscripts.hpp" -#include "Serialization/JsonPrintable.hpp" namespace ArduinoJson { namespace Internals { template -class JsonVariantBase : public JsonPrintable, - public JsonVariantCasts, +class JsonVariantBase : public JsonVariantCasts, public JsonVariantComparisons, public JsonVariantOr, public JsonVariantSubscripts, public JsonVariantTag {}; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonVariantImpl.hpp b/src/ArduinoJson/JsonVariantImpl.hpp index 31f96ce1a..93f70f096 100644 --- a/src/ArduinoJson/JsonVariantImpl.hpp +++ b/src/ArduinoJson/JsonVariantImpl.hpp @@ -117,10 +117,4 @@ inline bool JsonVariant::variantIsFloat() const { (_type == JSON_UNPARSED && isFloat(_content.asString)); } -#if ARDUINOJSON_ENABLE_STD_STREAM -inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) { - return source.printTo(os); -} -#endif - } // namespace ArduinoJson diff --git a/src/ArduinoJson/Serialization/DummyPrint.hpp b/src/ArduinoJson/Serialization/DummyPrint.hpp index 9fdf2d6a0..67ec33e13 100644 --- a/src/ArduinoJson/Serialization/DummyPrint.hpp +++ b/src/ArduinoJson/Serialization/DummyPrint.hpp @@ -7,7 +7,7 @@ namespace ArduinoJson { namespace Internals { -// A dummy Print implementation used in JsonPrintable::measureLength() +// A dummy Print implementation used in measureJson() class DummyPrint { public: size_t print(char) { @@ -18,5 +18,5 @@ class DummyPrint { return strlen(s); } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Serialization/IndentedPrint.hpp b/src/ArduinoJson/Serialization/IndentedPrint.hpp index 864f9aaa4..a71ceb66a 100644 --- a/src/ArduinoJson/Serialization/IndentedPrint.hpp +++ b/src/ArduinoJson/Serialization/IndentedPrint.hpp @@ -8,7 +8,7 @@ namespace ArduinoJson { namespace Internals { // Decorator on top of Print to allow indented output. -// This class is used by JsonPrintable::prettyPrintTo() but can also be used +// This class is used by serializeJsonPretty() but can also be used // for your own purpose, like logging. template class IndentedPrint { @@ -64,5 +64,5 @@ class IndentedPrint { static const int MAX_LEVEL = 15; // because it's only 4 bits static const int MAX_TAB_SIZE = 7; // because it's only 3 bits }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Serialization/JsonPrintable.hpp b/src/ArduinoJson/Serialization/JsonPrintable.hpp deleted file mode 100644 index 43d413a85..000000000 --- a/src/ArduinoJson/Serialization/JsonPrintable.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "../Configuration.hpp" -#include "../TypeTraits/EnableIf.hpp" -#include "DummyPrint.hpp" -#include "DynamicStringBuilder.hpp" -#include "IndentedPrint.hpp" -#include "JsonSerializer.hpp" -#include "JsonWriter.hpp" -#include "Prettyfier.hpp" -#include "StaticStringBuilder.hpp" - -#if ARDUINOJSON_ENABLE_STD_STREAM -#include "StreamPrintAdapter.hpp" -#endif - -namespace ArduinoJson { -namespace Internals { - -// Implements all the overloads of printTo() and prettyPrintTo() -// Caution: this class use a template parameter to avoid virtual methods. -// This is a bit curious but allows to reduce the size of JsonVariant, JsonArray -// and JsonObject. -template -class JsonPrintable { - public: - template - typename EnableIf::has_append, size_t>::type printTo( - Print &print) const { - JsonWriter writer(print); - JsonSerializer >::serialize(downcast(), writer); - return writer.bytesWritten(); - } - -#if ARDUINOJSON_ENABLE_STD_STREAM - std::ostream &printTo(std::ostream &os) const { - StreamPrintAdapter adapter(os); - printTo(adapter); - return os; - } -#endif - - size_t printTo(char *buffer, size_t bufferSize) const { - StaticStringBuilder sb(buffer, bufferSize); - return printTo(sb); - } - - template - size_t printTo(char (&buffer)[N]) const { - return printTo(buffer, N); - } - - template - typename EnableIf::has_append, size_t>::type printTo( - TString &str) const { - DynamicStringBuilder sb(str); - return printTo(sb); - } - - template - size_t prettyPrintTo(IndentedPrint &print) const { - Prettyfier p(print); - return printTo(p); - } - - size_t prettyPrintTo(char *buffer, size_t bufferSize) const { - StaticStringBuilder sb(buffer, bufferSize); - return prettyPrintTo(sb); - } - - template - size_t prettyPrintTo(char (&buffer)[N]) const { - return prettyPrintTo(buffer, N); - } - - template - typename EnableIf::has_append, size_t>::type - prettyPrintTo(Print &print) const { - IndentedPrint indentedPrint(print); - return prettyPrintTo(indentedPrint); - } - - template - typename EnableIf::has_append, size_t>::type - prettyPrintTo(TString &str) const { - DynamicStringBuilder sb(str); - return prettyPrintTo(sb); - } - - size_t measureLength() const { - DummyPrint dp; - return printTo(dp); - } - - size_t measurePrettyLength() const { - DummyPrint dp; - return prettyPrintTo(dp); - } - - private: - const T &downcast() const { - return *static_cast(this); - } -}; - -#if ARDUINOJSON_ENABLE_STD_STREAM -template -inline std::ostream &operator<<(std::ostream &os, const JsonPrintable &v) { - return v.printTo(os); -} -#endif -} -} diff --git a/src/ArduinoJson/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Serialization/JsonSerializer.hpp index 0cb537f7d..211e9fbfc 100644 --- a/src/ArduinoJson/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Serialization/JsonSerializer.hpp @@ -4,7 +4,16 @@ #pragma once +#include "DummyPrint.hpp" +#include "DynamicStringBuilder.hpp" +#include "IndentedPrint.hpp" #include "JsonWriter.hpp" +#include "Prettyfier.hpp" +#include "StaticStringBuilder.hpp" + +#if ARDUINOJSON_ENABLE_STD_STREAM +#include "StreamPrintAdapter.hpp" +#endif namespace ArduinoJson { @@ -28,5 +37,122 @@ class JsonSerializer { static void serialize(const JsonObjectSubscript &, Writer &); static void serialize(const JsonVariant &, Writer &); }; +} // namespace Internals + +template +typename Internals::EnableIf::has_append, + size_t>::type +serializeJson(const TSource &source, TDestination &destination) { + Internals::JsonWriter writer(destination); + Internals::JsonSerializer >::serialize( + source, writer); + return writer.bytesWritten(); +} + +#if ARDUINOJSON_ENABLE_STD_STREAM +template +std::ostream &serializeJson(const TSource &source, std::ostream &os) { + Internals::StreamPrintAdapter adapter(os); + serializeJson(source, adapter); + return os; +} +#endif + +template +size_t serializeJson(const TSource &source, char *buffer, size_t bufferSize) { + Internals::StaticStringBuilder sb(buffer, bufferSize); + return serializeJson(source, sb); +} + +template +size_t serializeJson(const TSource &source, char (&buffer)[N]) { + return serializeJson(source, buffer, N); +} + +template +typename Internals::EnableIf::has_append, + size_t>::type +serializeJson(const TSource &source, TDestination &str) { + Internals::DynamicStringBuilder sb(str); + return serializeJson(source, sb); } + +template +size_t serializeJsonPretty(const TSource &source, + Internals::IndentedPrint &print) { + Internals::Prettyfier p(print); + return serializeJson(source, p); } + +template +size_t serializeJsonPretty(const TSource &source, char *buffer, + size_t bufferSize) { + Internals::StaticStringBuilder sb(buffer, bufferSize); + return serializeJsonPretty(source, sb); +} + +template +size_t serializeJsonPretty(const TSource &source, char (&buffer)[N]) { + return serializeJsonPretty(source, buffer, N); +} + +template +typename Internals::EnableIf::has_append, + size_t>::type +serializeJsonPretty(const TSource &source, TDestination &print) { + Internals::IndentedPrint indentedPrint(print); + return serializeJsonPretty(source, indentedPrint); +} + +template +typename Internals::EnableIf::has_append, + size_t>::type +serializeJsonPretty(const TSource &source, TDestination &str) { + Internals::DynamicStringBuilder sb(str); + return serializeJsonPretty(source, sb); +} + +template +size_t measureJson(const TSource &source) { + Internals::DummyPrint dp; + return serializeJson(source, dp); +} + +template +size_t measureJsonPretty(const TSource &source) { + Internals::DummyPrint dp; + return serializeJsonPretty(source, dp); +} + +#if ARDUINOJSON_ENABLE_STD_STREAM +inline std::ostream &operator<<(std::ostream &os, const JsonArray &source) { + serializeJson(source, os); + return os; +} +inline std::ostream &operator<<(std::ostream &os, const JsonObject &source) { + serializeJson(source, os); + return os; +} +inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) { + serializeJson(source, os); + return os; +} + +namespace Internals { +inline std::ostream &operator<<(std::ostream &os, + const JsonArraySubscript &source) { + serializeJson(source, os); + return os; +} + +template +inline std::ostream &operator<<(std::ostream &os, + const JsonObjectSubscript &source) { + serializeJson(source, os); + return os; +} +} // namespace Internals + +#endif + +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Serialization/JsonWriter.hpp b/src/ArduinoJson/Serialization/JsonWriter.hpp index 146d51dcb..d56828636 100644 --- a/src/ArduinoJson/Serialization/JsonWriter.hpp +++ b/src/ArduinoJson/Serialization/JsonWriter.hpp @@ -26,8 +26,6 @@ class JsonWriter { explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {} // Returns the number of bytes sent to the Print implementation. - // This is very handy for implementations of printTo() that must return the - // number of bytes written. size_t bytesWritten() const { return _length; } @@ -151,5 +149,5 @@ class JsonWriter { private: JsonWriter &operator=(const JsonWriter &); // cannot be assigned }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 931a46128..578937a9d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -69,6 +69,7 @@ add_subdirectory(IntegrationTests) add_subdirectory(JsonArray) add_subdirectory(JsonObject) add_subdirectory(JsonParser) +add_subdirectory(JsonSerializer) add_subdirectory(JsonVariant) add_subdirectory(JsonWriter) add_subdirectory(Misc) diff --git a/test/DynamicJsonBuffer/alloc.cpp b/test/DynamicJsonBuffer/alloc.cpp index c45e6866a..0d1994f65 100644 --- a/test/DynamicJsonBuffer/alloc.cpp +++ b/test/DynamicJsonBuffer/alloc.cpp @@ -18,7 +18,8 @@ std::stringstream allocatorLog; struct SpyingAllocator : DefaultAllocator { void* allocate(size_t n) { - allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize); + allocatorLog << static_cast("A") + << (n - DynamicJsonBuffer::EmptyBlockSize); return DefaultAllocator::allocate(n); } void deallocate(void* p) { diff --git a/test/IntegrationTests/round_trip.cpp b/test/IntegrationTests/round_trip.cpp index 9dd49f938..487dbb740 100644 --- a/test/IntegrationTests/round_trip.cpp +++ b/test/IntegrationTests/round_trip.cpp @@ -10,11 +10,11 @@ void check(std::string originalJson) { std::string prettyJson; deserializeJson(obj, originalJson); - obj.prettyPrintTo(prettyJson); + serializeJsonPretty(obj, prettyJson); std::string finalJson; deserializeJson(obj, originalJson); - obj.printTo(finalJson); + serializeJson(obj, finalJson); REQUIRE(originalJson == finalJson); } diff --git a/test/JsonArray/CMakeLists.txt b/test/JsonArray/CMakeLists.txt index ec0e5206b..c0b13b60f 100644 --- a/test/JsonArray/CMakeLists.txt +++ b/test/JsonArray/CMakeLists.txt @@ -9,8 +9,6 @@ add_executable(JsonArrayTests copyTo.cpp invalid.cpp iterator.cpp - prettyPrintTo.cpp - printTo.cpp remove.cpp set.cpp size.cpp diff --git a/test/JsonArray/copyFrom.cpp b/test/JsonArray/copyFrom.cpp index a881e53d5..fa2045bce 100644 --- a/test/JsonArray/copyFrom.cpp +++ b/test/JsonArray/copyFrom.cpp @@ -14,7 +14,7 @@ TEST_CASE("JsonArray::copyFrom()") { bool ok = array.copyFrom(source); REQUIRE(ok); - array.printTo(json, sizeof(json)); + serializeJson(array, json, sizeof(json)); REQUIRE(std::string("[1,2,3]") == json); } @@ -27,7 +27,7 @@ TEST_CASE("JsonArray::copyFrom()") { bool ok = array.copyFrom(source); REQUIRE_FALSE(ok); - array.printTo(json, sizeof(json)); + serializeJson(array, json, sizeof(json)); REQUIRE(std::string("[1,2]") == json); } @@ -39,7 +39,7 @@ TEST_CASE("JsonArray::copyFrom()") { bool ok = array.copyFrom(source); REQUIRE(ok); - array.printTo(json, sizeof(json)); + serializeJson(array, json, sizeof(json)); REQUIRE(std::string("[[1,2,3],[4,5,6]]") == json); } @@ -53,7 +53,7 @@ TEST_CASE("JsonArray::copyFrom()") { bool ok = array.copyFrom(source); REQUIRE_FALSE(ok); - array.printTo(json, sizeof(json)); + serializeJson(array, json, sizeof(json)); REQUIRE(std::string("[[1,2,3],[4,5]]") == json); } } diff --git a/test/JsonArray/invalid.cpp b/test/JsonArray/invalid.cpp index 045517bab..f057c0a71 100644 --- a/test/JsonArray/invalid.cpp +++ b/test/JsonArray/invalid.cpp @@ -28,7 +28,7 @@ TEST_CASE("JsonArray::invalid()") { SECTION("PrintToWritesBrackets") { char buffer[32]; - JsonArray::invalid().printTo(buffer, sizeof(buffer)); + serializeJson(JsonArray::invalid(), buffer, sizeof(buffer)); REQUIRE_THAT(buffer, Equals("[]")); } } diff --git a/test/JsonObject/CMakeLists.txt b/test/JsonObject/CMakeLists.txt index 93e8f0ded..b6de6d30b 100644 --- a/test/JsonObject/CMakeLists.txt +++ b/test/JsonObject/CMakeLists.txt @@ -8,8 +8,6 @@ add_executable(JsonObjectTests get.cpp invalid.cpp iterator.cpp - prettyPrintTo.cpp - printTo.cpp remove.cpp set.cpp size.cpp diff --git a/test/JsonObject/invalid.cpp b/test/JsonObject/invalid.cpp index 019ced10c..7dbfd868a 100644 --- a/test/JsonObject/invalid.cpp +++ b/test/JsonObject/invalid.cpp @@ -29,7 +29,7 @@ TEST_CASE("JsonObject::invalid()") { SECTION("PrintToWritesBraces") { char buffer[32]; - obj.printTo(buffer, sizeof(buffer)); + serializeJson(obj, buffer, sizeof(buffer)); REQUIRE_THAT(buffer, Equals("{}")); } } diff --git a/test/JsonObject/remove.cpp b/test/JsonObject/remove.cpp index 28bf539ba..4048ebd53 100644 --- a/test/JsonObject/remove.cpp +++ b/test/JsonObject/remove.cpp @@ -33,7 +33,7 @@ TEST_CASE("JsonObject::remove()") { } std::string result; - obj.printTo(result); + serializeJson(obj, result); REQUIRE("{\"a\":0,\"c\":2}" == result); } } diff --git a/test/JsonSerializer/CMakeLists.txt b/test/JsonSerializer/CMakeLists.txt new file mode 100644 index 000000000..f513ca1d2 --- /dev/null +++ b/test/JsonSerializer/CMakeLists.txt @@ -0,0 +1,14 @@ +# ArduinoJson - arduinojson.org +# Copyright Benoit Blanchon 2014-2018 +# MIT License + +add_executable(JsonSerializerTests + JsonArray.cpp + JsonArrayPretty.cpp + JsonObject.cpp + JsonObjectPretty.cpp + JsonVariant.cpp +) + +target_link_libraries(JsonSerializerTests catch) +add_test(JsonSerializer JsonSerializerTests) diff --git a/test/JsonArray/printTo.cpp b/test/JsonSerializer/JsonArray.cpp similarity index 94% rename from test/JsonArray/printTo.cpp rename to test/JsonSerializer/JsonArray.cpp index 82ebad9ae..ced91238a 100644 --- a/test/JsonArray/printTo.cpp +++ b/test/JsonSerializer/JsonArray.cpp @@ -7,14 +7,14 @@ static void check(JsonArray &array, std::string expected) { std::string actual; - size_t actualLen = array.printTo(actual); + size_t actualLen = serializeJson(array, actual); REQUIRE(expected == actual); REQUIRE(actualLen == expected.size()); - size_t measuredLen = array.measureLength(); + size_t measuredLen = measureJson(array); REQUIRE(measuredLen == expected.size()); } -TEST_CASE("JsonArray::printTo()") { +TEST_CASE("serializeJson(JsonArray)") { StaticJsonArray array; SECTION("Empty") { diff --git a/test/JsonArray/prettyPrintTo.cpp b/test/JsonSerializer/JsonArrayPretty.cpp similarity index 89% rename from test/JsonArray/prettyPrintTo.cpp rename to test/JsonSerializer/JsonArrayPretty.cpp index af36a3207..4785d6433 100644 --- a/test/JsonArray/prettyPrintTo.cpp +++ b/test/JsonSerializer/JsonArrayPretty.cpp @@ -7,14 +7,14 @@ static void check(JsonArray& array, std::string expected) { std::string actual; - size_t actualLen = array.prettyPrintTo(actual); - size_t measuredLen = array.measurePrettyLength(); + size_t actualLen = serializeJsonPretty(array, actual); + size_t measuredLen = measureJsonPretty(array); CHECK(actualLen == expected.size()); CHECK(measuredLen == expected.size()); REQUIRE(expected == actual); } -TEST_CASE("JsonArray::prettyPrintTo()") { +TEST_CASE("serializeJsonPretty(JsonArray)") { DynamicJsonArray array; SECTION("Empty") { diff --git a/test/JsonObject/printTo.cpp b/test/JsonSerializer/JsonObject.cpp similarity index 94% rename from test/JsonObject/printTo.cpp rename to test/JsonSerializer/JsonObject.cpp index f72bb2e1b..25476928a 100644 --- a/test/JsonObject/printTo.cpp +++ b/test/JsonSerializer/JsonObject.cpp @@ -8,14 +8,15 @@ void check(const JsonObject &obj, const std::string &expected) { char actual[256]; - size_t actualLen = obj.printTo(actual); - size_t measuredLen = obj.measureLength(); + size_t actualLen = serializeJson(obj, actual); + size_t measuredLen = measureJson(obj); REQUIRE(expected == actual); REQUIRE(expected.size() == actualLen); REQUIRE(expected.size() == measuredLen); } -TEST_CASE("JsonObject::printTo()") { + +TEST_CASE("serializeJson(JsonObject)") { DynamicJsonObject obj; SECTION("EmptyObject") { diff --git a/test/JsonObject/prettyPrintTo.cpp b/test/JsonSerializer/JsonObjectPretty.cpp similarity index 90% rename from test/JsonObject/prettyPrintTo.cpp rename to test/JsonSerializer/JsonObjectPretty.cpp index 885a68952..efcc947e4 100644 --- a/test/JsonObject/prettyPrintTo.cpp +++ b/test/JsonSerializer/JsonObjectPretty.cpp @@ -9,15 +9,15 @@ void check(const JsonObject &obj, const std::string expected) { char json[256]; - size_t actualLen = obj.prettyPrintTo(json); - size_t measuredLen = obj.measurePrettyLength(); + size_t actualLen = serializeJsonPretty(obj, json); + size_t measuredLen = measureJsonPretty(obj); REQUIRE(json == expected); REQUIRE(expected.size() == actualLen); REQUIRE(expected.size() == measuredLen); } -TEST_CASE("JsonObject::prettyPrintTo()") { +TEST_CASE("serializeJsonPretty(JsonObject)") { DynamicJsonObject obj; SECTION("EmptyObject") { diff --git a/test/JsonVariant/printTo.cpp b/test/JsonSerializer/JsonVariant.cpp similarity index 91% rename from test/JsonVariant/printTo.cpp rename to test/JsonSerializer/JsonVariant.cpp index 3431eaeee..10c5ddf3e 100644 --- a/test/JsonVariant/printTo.cpp +++ b/test/JsonSerializer/JsonVariant.cpp @@ -8,12 +8,12 @@ void check(JsonVariant variant, const std::string &expected) { char buffer[256] = ""; - size_t returnValue = variant.printTo(buffer, sizeof(buffer)); + size_t returnValue = serializeJson(variant, buffer, sizeof(buffer)); REQUIRE(expected == buffer); REQUIRE(expected.size() == returnValue); } -TEST_CASE("JsonVariant::printTo()") { +TEST_CASE("serializeJson(JsonVariant)") { SECTION("Empty") { check(JsonVariant(), ""); } diff --git a/test/JsonVariant/CMakeLists.txt b/test/JsonVariant/CMakeLists.txt index 0a00a15a1..2ceb9277a 100644 --- a/test/JsonVariant/CMakeLists.txt +++ b/test/JsonVariant/CMakeLists.txt @@ -2,13 +2,12 @@ # Copyright Benoit Blanchon 2014-2018 # MIT License -add_executable(JsonVariantTests +add_executable(JsonVariantTests as.cpp compare.cpp copy.cpp is.cpp or.cpp - printTo.cpp set_get.cpp subscript.cpp success.cpp diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index e164f8bd2..ea11cb35a 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -49,19 +49,19 @@ TEST_CASE("std::string") { REQUIRE(std::string("world") == array[0]); } - SECTION("printTo()") { + SECTION("serializeJson()") { array.add(4); array.add(2); std::string json; - array.printTo(json); + serializeJson(array, json); REQUIRE(std::string("[4,2]") == json); } - SECTION("prettyPrintTo") { + SECTION("serializeJsonPretty()") { array.add(4); array.add(2); std::string json; - array.prettyPrintTo(json); + serializeJsonPretty(array, json); REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json); } } @@ -69,7 +69,7 @@ TEST_CASE("std::string") { SECTION("JsonObject") { DynamicJsonObject object; - SECTION("deserializeJson") { + SECTION("deserializeJson()") { std::string json("{\"hello\":\"world\"}"); bool success = deserializeJson(object, json); @@ -156,7 +156,7 @@ TEST_CASE("std::string") { char json[64]; object.createNestedObject(key); eraseString(key); - object.printTo(json, sizeof(json)); + serializeJson(object, json, sizeof(json)); REQUIRE(std::string("{\"key\":{}}") == json); } @@ -165,7 +165,7 @@ TEST_CASE("std::string") { char json[64]; object.createNestedArray(key); eraseString(key); - object.printTo(json, sizeof(json)); + serializeJson(object, json, sizeof(json)); REQUIRE(std::string("{\"key\":[]}") == json); } @@ -197,17 +197,17 @@ TEST_CASE("std::string") { REQUIRE(std::string("world") == object["hello"]); } - SECTION("printTo") { + SECTION("serializeJson()") { object["key"] = "value"; std::string json; - object.printTo(json); + serializeJson(object, json); REQUIRE(std::string("{\"key\":\"value\"}") == json); } - SECTION("prettyPrintTo") { + SECTION("serializeJsonPretty()") { object["key"] = "value"; std::string json; - object.prettyPrintTo(json); + serializeJsonPretty(object, json); REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); } From b2a8085651ed6c774967c9426957f4132c3f25f7 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 9 Mar 2018 16:58:01 +0100 Subject: [PATCH 0018/1079] Added JsonError --- CHANGELOG.md | 4 +- examples/JsonConfigFile/JsonConfigFile.ino | 4 +- examples/JsonHttpClient/JsonHttpClient.ino | 4 +- .../JsonParserExample/JsonParserExample.ino | 4 +- fuzzing/fuzzer.cpp | 5 +- .../Deserialization/JsonParser.hpp | 17 +- .../Deserialization/JsonParserImpl.hpp | 89 ++- src/ArduinoJson/JsonError.hpp | 83 +++ src/ArduinoJson/deserializeJson.hpp | 19 +- test/DynamicJsonBuffer/no_memory.cpp | 8 +- test/IntegrationTests/gbathree.cpp | 4 +- test/JsonArray/copyTo.cpp | 12 +- test/JsonParser/CMakeLists.txt | 1 + test/JsonParser/JsonArray.cpp | 553 +++++++++--------- test/JsonParser/JsonError.cpp | 44 ++ test/JsonParser/JsonObject.cpp | 92 +-- test/JsonParser/JsonVariant.cpp | 40 +- test/JsonParser/StaticJsonArray.cpp | 28 +- test/JsonParser/StaticJsonObject.cpp | 28 +- test/JsonParser/nestingLimit.cpp | 29 +- test/Misc/std_stream.cpp | 8 +- test/Misc/std_string.cpp | 8 +- test/Misc/unsigned_char.cpp | 8 +- test/Misc/vla.cpp | 4 +- 24 files changed, 611 insertions(+), 485 deletions(-) create mode 100644 src/ArduinoJson/JsonError.hpp create mode 100644 test/JsonParser/JsonError.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index 20aaa183b..9434822db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,8 +33,8 @@ HEAD > > ```c++ > DynamicJsonObject obj; -> bool success = deserializeJson(obj, json); -> if (success) { +> JsonError error = deserializeJson(obj, json); +> if (error) { > > } > ``` diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index 442a86511..ebf03738b 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -35,9 +35,9 @@ void loadConfiguration(const char *filename, Config &config) { StaticJsonObject<512> root; // Parse the root object - bool success = deserializeJson(root, file); + JsonError error = deserializeJson(root, file); - if (!success) + if (error) Serial.println(F("Failed to read file, using default configuration")); // Copy values from the JsonObject to the Config diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index 8ce57a7f7..aeae598a2 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -76,8 +76,8 @@ void setup() { DynamicJsonObject root(capacity); // Parse JSON object - bool success = deserializeJson(root, client); - if (!root.success()) { + JsonError error = deserializeJson(root, client); + if (error) { Serial.println(F("Parsing failed!")); return; } diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 6c8063a5f..1f9cb3068 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -36,10 +36,10 @@ void setup() { // 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. - bool success = deserializeJson(root, json); + JsonError error = deserializeJson(root, json); // Test if parsing succeeds. - if (!success) { + if (error) { Serial.println("parseObject() failed"); return; } diff --git a/fuzzing/fuzzer.cpp b/fuzzing/fuzzer.cpp index 24b2f1911..358273c38 100644 --- a/fuzzing/fuzzer.cpp +++ b/fuzzing/fuzzer.cpp @@ -16,10 +16,11 @@ class memstream : public std::istream { }; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - DynamicJsonBuffer jsonBuffer; + DynamicJsonVariant variant; memstream json(data, size); + JsonError error = deserializeJson(variant, json); JsonVariant variant = jsonBuffer.parse(json); - if (variant.success()) { + if (!error) { variant.as(); // <- serialize to JSON } return 0; diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index b30abddc0..3c132448b 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -5,6 +5,7 @@ #pragma once #include "../JsonBuffer.hpp" +#include "../JsonError.hpp" #include "../JsonVariant.hpp" #include "../TypeTraits/IsConst.hpp" #include "StringWriter.hpp" @@ -24,9 +25,9 @@ class JsonParser { _reader(reader), _writer(writer), _nestingLimit(nestingLimit) {} - bool parse(JsonArray &destination); - bool parse(JsonObject &destination); - bool parse(JsonVariant &destination); + JsonError parse(JsonArray &destination); + JsonError parse(JsonObject &destination); + JsonError parse(JsonVariant &destination); private: JsonParser &operator=(const JsonParser &); // non-copiable @@ -37,12 +38,12 @@ class JsonParser { } const char *parseString(); - bool parseAnythingTo(JsonVariant *destination); - FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination); + JsonError parseAnythingTo(JsonVariant *destination); + FORCE_INLINE JsonError parseAnythingToUnsafe(JsonVariant *destination); - inline bool parseArrayTo(JsonVariant *destination); - inline bool parseObjectTo(JsonVariant *destination); - inline bool parseStringTo(JsonVariant *destination); + inline JsonError parseArrayTo(JsonVariant *destination); + inline JsonError parseObjectTo(JsonVariant *destination); + inline JsonError parseStringTo(JsonVariant *destination); static inline bool isBetween(char c, char min, char max) { return min <= c && c <= max; diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 3543d8703..3e767a2a8 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -18,18 +18,18 @@ inline bool ArduinoJson::Internals::JsonParser::eat( } template -inline bool +inline ArduinoJson::JsonError ArduinoJson::Internals::JsonParser::parseAnythingTo( JsonVariant *destination) { - if (_nestingLimit == 0) return false; + if (_nestingLimit == 0) return JsonError::TooDeep; _nestingLimit--; - bool success = parseAnythingToUnsafe(destination); + JsonError error = parseAnythingToUnsafe(destination); _nestingLimit++; - return success; + return error; } template -inline bool +inline ArduinoJson::JsonError ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( JsonVariant *destination) { skipSpacesAndComments(_reader); @@ -47,92 +47,76 @@ ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( } template -inline bool ArduinoJson::Internals::JsonParser::parse( - JsonArray &array) { +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parse(JsonArray &array) { // Check opening braket - if (!eat('[')) goto ERROR_MISSING_BRACKET; - if (eat(']')) goto SUCCESS_EMPTY_ARRAY; + if (!eat('[')) return JsonError::OpeningBracketExpected; + if (eat(']')) return JsonError::Ok; // Read each value for (;;) { // 1 - Parse value JsonVariant value; - if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; - if (!array.add(value)) goto ERROR_NO_MEMORY; + JsonError error = parseAnythingTo(&value); + if (error != JsonError::Ok) return error; + if (!array.add(value)) return JsonError::NoMemory; // 2 - More values? - if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY; - if (!eat(',')) goto ERROR_MISSING_COMMA; + if (eat(']')) return JsonError::Ok; + if (!eat(',')) return JsonError::ClosingBracketExpected; } - -SUCCESS_EMPTY_ARRAY: -SUCCES_NON_EMPTY_ARRAY: - return true; - -ERROR_INVALID_VALUE: -ERROR_MISSING_BRACKET: -ERROR_MISSING_COMMA: -ERROR_NO_MEMORY: - return false; } template -inline bool ArduinoJson::Internals::JsonParser::parse( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parse( JsonObject &object) { // Check opening brace - if (!eat('{')) goto ERROR_MISSING_BRACE; - if (eat('}')) goto SUCCESS_EMPTY_OBJECT; + 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) goto ERROR_INVALID_KEY; - if (!eat(':')) goto ERROR_MISSING_COLON; + if (!key) return JsonError::NoMemory; + if (!eat(':')) return JsonError::ColonExpected; // 2 - Parse value JsonVariant value; - if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE; - if (!object.set(key, value)) goto ERROR_NO_MEMORY; + JsonError error = parseAnythingTo(&value); + if (error != JsonError::Ok) return error; + if (!object.set(key, value)) return JsonError::NoMemory; // 3 - More keys/values? - if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT; - if (!eat(',')) goto ERROR_MISSING_COMMA; + if (eat('}')) return JsonError::Ok; + if (!eat(',')) return JsonError::ClosingBraceExpected; } - -SUCCESS_EMPTY_OBJECT: -SUCCESS_NON_EMPTY_OBJECT: - return true; - -ERROR_INVALID_KEY: -ERROR_INVALID_VALUE: -ERROR_MISSING_BRACE: -ERROR_MISSING_COLON: -ERROR_MISSING_COMMA: -ERROR_NO_MEMORY: - return false; } template -inline bool ArduinoJson::Internals::JsonParser::parse( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parse( JsonVariant &variant) { return parseAnythingTo(&variant); } template -inline bool ArduinoJson::Internals::JsonParser::parseArrayTo( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parseArrayTo( JsonVariant *destination) { JsonArray *array = new (_buffer) JsonArray(_buffer); - if (!array) return false; + if (!array) return JsonError::NoMemory; *destination = array; return parse(*array); } template -inline bool ArduinoJson::Internals::JsonParser::parseObjectTo( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parseObjectTo( JsonVariant *destination) { JsonObject *object = new (_buffer) JsonObject(_buffer); - if (!object) return false; + if (!object) return JsonError::NoMemory; *destination = object; return parse(*object); } @@ -177,15 +161,16 @@ ArduinoJson::Internals::JsonParser::parseString() { } template -inline bool ArduinoJson::Internals::JsonParser::parseStringTo( +inline ArduinoJson::JsonError +ArduinoJson::Internals::JsonParser::parseStringTo( JsonVariant *destination) { bool hasQuotes = isQuote(_reader.current()); const char *value = parseString(); - if (value == NULL) return false; + if (value == NULL) return JsonError::NoMemory; if (hasQuotes) { *destination = value; } else { *destination = RawJson(value); } - return true; + return JsonError::Ok; } diff --git a/src/ArduinoJson/JsonError.hpp b/src/ArduinoJson/JsonError.hpp new file mode 100644 index 000000000..e62dae6fd --- /dev/null +++ b/src/ArduinoJson/JsonError.hpp @@ -0,0 +1,83 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { + +class JsonError { + public: + enum Code { + Ok, + OpeningBraceExpected, + ClosingBraceExpected, + OpeningBracketExpected, + ClosingBracketExpected, + ColonExpected, + TooDeep, + NoMemory + }; + + JsonError(Code code) : _code(code) {} + + bool operator==(Code code) const { + return _code == code; + } + + bool operator!=(Code code) const { + return _code != code; + } + + operator bool() const { + return _code != Ok; + } + + const char* c_str() const { + return to_string(_code); + } + + friend const char* to_string(const JsonError err) { + return to_string(err._code); + } + + friend const char* to_string(JsonError::Code code) { + switch (code) { + case Ok: + return "Ok"; + case OpeningBraceExpected: + return "OpeningBraceExpected"; + case ClosingBraceExpected: + return "ClosingBraceExpected"; + case OpeningBracketExpected: + return "OpeningBracketExpected"; + case ClosingBracketExpected: + return "ClosingBracketExpected"; + case ColonExpected: + return "ColonExpected"; + case TooDeep: + return "TooDeep"; + case NoMemory: + return "NoMemory"; + default: + return "???"; + } + } + + private: + Code _code; +}; + +#if ARDUINOJSON_ENABLE_STD_STREAM +inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { + s << to_string(e); + return s; +} + +inline std::ostream& operator<<(std::ostream& s, JsonError::Code e) { + s << to_string(e); + return s; +} +#endif + +} // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index c192c32bc..4593529f1 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -7,33 +7,36 @@ #include "Deserialization/JsonParser.hpp" namespace ArduinoJson { -// bool deserializeJson(TDestination& destination, TString json); +// JsonError deserializeJson(TDestination& destination, TString json); // TDestination = JsonArray, JsonObject, JsonVariant // TString = const std::string&, const String& template -typename Internals::EnableIf::value, bool>::type +typename Internals::EnableIf::value, + JsonError>::type deserializeJson(TDestination &destination, const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } // -// bool deserializeJson(TDestination& destination, TString json); +// JsonError deserializeJson(TDestination& destination, TString json); // TDestination = JsonArray, JsonObject, JsonVariant // TString = const char*, const char[N], const FlashStringHelper* template -bool deserializeJson(TDestination &destination, TString *json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { +JsonError deserializeJson( + TDestination &destination, TString *json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } // -// bool deserializeJson(TDestination& destination, TString json); +// JsonError deserializeJson(TDestination& destination, TString json); // TDestination = JsonArray, JsonObject, JsonVariant // TString = std::istream&, Stream& template -bool deserializeJson(TDestination &destination, TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { +JsonError deserializeJson( + TDestination &destination, TString &json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index be39c04d6..5587a1cea 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -27,9 +27,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { // char json[] = "[{}]"; // DynamicJsonArray arr; - // bool success = deserializeJson(arr, json); + // JsonError err = deserializeJson(arr, json); - // REQUIRE(success == false); + // REQUIRE(err != JsonError::Ok); // } // TODO: uncomment @@ -37,9 +37,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { // char json[] = "{[]}"; // DynamicJsonObject obj; - // bool success = deserializeJson(obj, json); + // JsonError err = deserializeJson(obj, json); - // REQUIRE(success == false); + // REQUIRE(err != JsonError::Ok); // } SECTION("startString()") { diff --git a/test/IntegrationTests/gbathree.cpp b/test/IntegrationTests/gbathree.cpp index 0f12dbf22..dd6b293f0 100644 --- a/test/IntegrationTests/gbathree.cpp +++ b/test/IntegrationTests/gbathree.cpp @@ -8,7 +8,7 @@ TEST_CASE("Gbathree") { DynamicJsonObject _object; - bool success = deserializeJson( + JsonError error = deserializeJson( _object, "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" @@ -22,7 +22,7 @@ TEST_CASE("Gbathree") { "[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); SECTION("Success") { - REQUIRE(success == true); + REQUIRE(error == JsonError::Ok); } SECTION("ProtocolName") { diff --git a/test/JsonArray/copyTo.cpp b/test/JsonArray/copyTo.cpp index 3a83a4616..9c31e880c 100644 --- a/test/JsonArray/copyTo.cpp +++ b/test/JsonArray/copyTo.cpp @@ -10,8 +10,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("BiggerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - bool success = deserializeJson(array, json); - REQUIRE(success == true); + JsonError err = deserializeJson(array, json); + REQUIRE(err == JsonError::Ok); int destination[4] = {0}; size_t result = array.copyTo(destination); @@ -25,8 +25,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("SmallerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - bool success = deserializeJson(array, json); - REQUIRE(success == true); + JsonError err = deserializeJson(array, json); + REQUIRE(err == JsonError::Ok); int destination[2] = {0}; size_t result = array.copyTo(destination); @@ -39,8 +39,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("TwoOneDimensionIntegerArray") { char json[] = "[[1,2],[3],[4]]"; - bool success = deserializeJson(array, json); - REQUIRE(success == true); + JsonError err = deserializeJson(array, json); + REQUIRE(err == JsonError::Ok); int destination[3][2] = {{0}}; array.copyTo(destination); diff --git a/test/JsonParser/CMakeLists.txt b/test/JsonParser/CMakeLists.txt index fa5ec203e..19381c404 100644 --- a/test/JsonParser/CMakeLists.txt +++ b/test/JsonParser/CMakeLists.txt @@ -4,6 +4,7 @@ add_executable(JsonParserTests JsonArray.cpp + JsonError.cpp JsonObject.cpp JsonVariant.cpp nestingLimit.cpp diff --git a/test/JsonParser/JsonArray.cpp b/test/JsonParser/JsonArray.cpp index af12c5482..5a9a6b14c 100644 --- a/test/JsonParser/JsonArray.cpp +++ b/test/JsonParser/JsonArray.cpp @@ -8,339 +8,346 @@ TEST_CASE("deserializeJson(JsonArray&)") { DynamicJsonArray arr; - SECTION("EmptyArray") { - bool success = deserializeJson(arr, "[]"); + SECTION("An empty array") { + JsonError err = deserializeJson(arr, "[]"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(0 == arr.size()); } - SECTION("MissingOpeningBracket") { - bool success = deserializeJson(arr, "]"); - REQUIRE_FALSE(success == true); - } + SECTION("Spaces") { + SECTION("Before the opening bracket") { + JsonError err = deserializeJson(arr, " []"); - SECTION("ArrayWithNoEnd") { - bool success = deserializeJson(arr, "["); - REQUIRE_FALSE(success == true); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(0 == arr.size()); + } - SECTION("EmptyArrayWithLeadingSpaces") { - bool success = deserializeJson(arr, " []"); + SECTION("Before first value") { + JsonError err = deserializeJson(arr, "[ \t\r\n42]"); - REQUIRE(success == true); - REQUIRE(0 == arr.size()); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } - SECTION("Garbage") { - bool success = deserializeJson(arr, "%*$£¤"); + SECTION("After first value") { + JsonError err = deserializeJson(arr, "[42 \t\r\n]"); - REQUIRE_FALSE(success == true); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } } - SECTION("OneInteger") { - bool success = deserializeJson(arr, "[42]"); + SECTION("Values types") { + SECTION("On integer") { + JsonError err = deserializeJson(arr, "[42]"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 42); + } - SECTION("OneIntegerWithSpacesBefore") { - bool success = deserializeJson(arr, "[ \t\r\n42]"); + SECTION("Two integers") { + JsonError err = deserializeJson(arr, "[42,84]"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == 42); + REQUIRE(arr[1] == 84); + } - SECTION("OneIntegerWithSpaceAfter") { - bool success = deserializeJson(arr, "[42 \t\r\n]"); + SECTION("Double") { + JsonError err = deserializeJson(arr, "[4.2,1e2]"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 42); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == 4.2); + REQUIRE(arr[1] == 1e2); + } - SECTION("TwoIntegers") { - bool success = deserializeJson(arr, "[42,84]"); + SECTION("Unsigned long") { + JsonError err = deserializeJson(arr, "[4294967295]"); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == 42); - REQUIRE(arr[1] == 84); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == 4294967295UL); + } - SECTION("TwoDoubles") { - bool success = deserializeJson(arr, "[4.2,1e2]"); + SECTION("Boolean") { + JsonError err = deserializeJson(arr, "[true,false]"); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == 4.2); - REQUIRE(arr[1] == 1e2); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == true); + REQUIRE(arr[1] == false); + } - SECTION("UnsignedLong") { - bool success = deserializeJson(arr, "[4294967295]"); + SECTION("Null") { + JsonError err = deserializeJson(arr, "[null,null]"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == 4294967295UL); + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0].as() == 0); + REQUIRE(arr[1].as() == 0); + } } - SECTION("TwoBooleans") { - bool success = deserializeJson(arr, "[true,false]"); + SECTION("Quotes") { + SECTION("Double quotes") { + JsonError err = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == true); - REQUIRE(arr[1] == false); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } - SECTION("TwoNulls") { - bool success = deserializeJson(arr, "[null,null]"); + SECTION("Single quotes") { + JsonError err = deserializeJson(arr, "[ 'hello' , 'world' ]"); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0].as() == 0); - REQUIRE(arr[1].as() == 0); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } - SECTION("TwoStringsDoubleQuotes") { - bool success = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); + SECTION("No quotes") { + JsonError err = deserializeJson(arr, "[ hello , world ]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("Double quotes (empty strings)") { + JsonError err = deserializeJson(arr, "[\"\",\"\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } + SECTION("Single quotes (empty strings)") { + JsonError err = deserializeJson(arr, "[\'\',\'\']"); - SECTION("TwoStringsSingleQuotes") { - bool success = deserializeJson(arr, "[ 'hello' , 'world' ]"); + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } + + SECTION("No quotes (empty strings)") { + JsonError err = deserializeJson(arr, "[,]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == ""); + REQUIRE(arr[1] == ""); + } - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } + SECTION("Closing single quotes missing") { + JsonError err = deserializeJson(arr, "[\"]"); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("Closing double quotes missing") { + JsonError err = deserializeJson(arr, "[\']"); - SECTION("TwoStringsNoQuotes") { - bool success = deserializeJson(arr, "[ hello , world ]"); + REQUIRE(err != JsonError::Ok); + } + } + + SECTION("Block comments") { + SECTION("Before opening bracket") { + JsonError err = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]"); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("After opening bracket") { + JsonError err = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); - SECTION("EmptyStringsDoubleQuotes") { - bool success = deserializeJson(arr, "[\"\",\"\"]"); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("Before closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("After closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("Before comma") { + JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } - SECTION("EmptyStringSingleQuotes") { - bool success = deserializeJson(arr, "[\'\',\'\']"); + SECTION("After comma") { + JsonError err = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } - SECTION("EmptyStringNoQuotes") { - bool success = deserializeJson(arr, "[,]"); + SECTION("/*/") { + JsonError err = deserializeJson(arr, "[/*/\n]"); + REQUIRE(err != JsonError::Ok); + } - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); - } - - SECTION("ClosingDoubleQuoteMissing") { - bool success = deserializeJson(arr, "[\"]"); + SECTION("Unfinished comment") { + JsonError err = deserializeJson(arr, "[/*COMMENT]"); + REQUIRE(err != JsonError::Ok); + } - REQUIRE_FALSE(success == true); + SECTION("Final slash missing") { + JsonError err = deserializeJson(arr, "[/*COMMENT*]"); + REQUIRE(err != JsonError::Ok); + } } - SECTION("ClosingSignleQuoteMissing") { - bool success = deserializeJson(arr, "[\']"); + SECTION("Line comments") { + SECTION("Before opening bracket") { + JsonError err = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); - REQUIRE_FALSE(success == true); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } - SECTION("StringWithEscapedChars") { - bool success = - deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); + SECTION("After opening bracket") { + JsonError err = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); - } + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } - SECTION("StringWithUnterminatedEscapeSequence") { - bool success = deserializeJson(arr, "\"\\\0\"", 4); - REQUIRE_FALSE(success == true); - } + SECTION("Before closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); - SECTION("CCommentBeforeOpeningBracket") { - bool success = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]"); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } + SECTION("After closing bracket") { + JsonError err = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); - SECTION("CCommentAfterOpeningBracket") { - bool success = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "hello"); + } + + SECTION("Before comma") { + JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } + SECTION("After comma") { + JsonError err = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(2 == arr.size()); + REQUIRE(arr[0] == "hello"); + REQUIRE(arr[1] == "world"); + } + + SECTION("Invalid comment") { + JsonError err = deserializeJson(arr, "[/COMMENT\n]"); + REQUIRE(err != JsonError::Ok); + } + + SECTION("End document with comment") { + JsonError err = deserializeJson(arr, "[//COMMENT"); + REQUIRE(err != JsonError::Ok); + } + } + + SECTION("Misc") { + SECTION("Garbage") { + JsonError err = deserializeJson(arr, "%*$£¤"); - SECTION("CCommentBeforeClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); + REQUIRE(err != JsonError::Ok); + } + + SECTION("The opening bracket is missing") { + JsonError err = deserializeJson(arr, "]"); + + REQUIRE(err != JsonError::Ok); // TODO + } - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } + SECTION("The closing bracket is missing") { + JsonError err = deserializeJson(arr, "["); + REQUIRE(err != JsonError::Ok); // TODO + } + + SECTION("Escape sequences") { + JsonError err = + deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); - SECTION("CCommentAfterClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); + } - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CCommentBeforeComma") { - bool success = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CCommentAfterComma") { - bool success = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CppCommentBeforeOpeningBracket") { - bool success = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentAfterOpeningBracket") { - bool success = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentBeforeClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentAfterClosingBracket") { - bool success = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); - - REQUIRE(success == true); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "hello"); - } - - SECTION("CppCommentBeforeComma") { - bool success = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("CppCommentAfterComma") { - bool success = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); - - REQUIRE(success == true); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == "hello"); - REQUIRE(arr[1] == "world"); - } - - SECTION("InvalidCppComment") { - bool success = deserializeJson(arr, "[/COMMENT\n]"); - REQUIRE_FALSE(success == true); - } - - SECTION("InvalidComment") { - bool success = deserializeJson(arr, "[/*/\n]"); - REQUIRE_FALSE(success == true); - } - - SECTION("UnfinishedCComment") { - bool success = deserializeJson(arr, "[/*COMMENT]"); - REQUIRE_FALSE(success == true); - } - - SECTION("EndsInCppComment") { - bool success = deserializeJson(arr, "[//COMMENT"); - REQUIRE_FALSE(success == true); - } - - SECTION("AfterClosingStar") { - bool success = deserializeJson(arr, "[/*COMMENT*"); - REQUIRE_FALSE(success == true); - } - - SECTION("DeeplyNested") { - bool success = deserializeJson( - arr, "[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"); - REQUIRE(success == true); - } + SECTION("Unterminated escape sequence") { + JsonError err = deserializeJson(arr, "\"\\\0\"", 4); + REQUIRE(err != JsonError::Ok); + } - SECTION("ObjectNestedInArray") { - char jsonString[] = - " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; + SECTION("Nested objects") { + char jsonString[] = + " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; - bool success = deserializeJson(arr, jsonString); + JsonError err = deserializeJson(arr, jsonString); - JsonObject &object1 = arr[0]; - const JsonObject &object2 = arr[1]; - JsonObject &object3 = arr[2]; + JsonObject &object1 = arr[0]; + const JsonObject &object2 = arr[1]; + JsonObject &object3 = arr[2]; - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); - REQUIRE(true == object1.success()); - REQUIRE(true == object2.success()); - REQUIRE(false == object3.success()); + REQUIRE(true == object1.success()); + REQUIRE(true == object2.success()); + REQUIRE(false == object3.success()); - REQUIRE(2 == object1.size()); - REQUIRE(2 == object2.size()); - REQUIRE(0 == object3.size()); + REQUIRE(2 == object1.size()); + REQUIRE(2 == object2.size()); + REQUIRE(0 == object3.size()); - REQUIRE(1 == object1["a"].as()); - REQUIRE(2 == object1["b"].as()); - REQUIRE(3 == object2["c"].as()); - REQUIRE(4 == object2["d"].as()); - REQUIRE(0 == object3["e"].as()); + REQUIRE(1 == object1["a"].as()); + REQUIRE(2 == object1["b"].as()); + REQUIRE(3 == object2["c"].as()); + REQUIRE(4 == object2["d"].as()); + REQUIRE(0 == object3["e"].as()); + } } } diff --git a/test/JsonParser/JsonError.cpp b/test/JsonParser/JsonError.cpp new file mode 100644 index 000000000..21714ba00 --- /dev/null +++ b/test/JsonParser/JsonError.cpp @@ -0,0 +1,44 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +void testStringification(JsonError error, std::string expected) { + REQUIRE(error.c_str() == expected); +} + +void testBoolification(JsonError error, bool expected) { + CHECK(error == expected); +} + +#define TEST_STRINGIFICATION(symbol) \ + testStringification(JsonError::symbol, #symbol) + +#define TEST_BOOLIFICATION(symbol, expected) \ + testBoolification(JsonError::symbol, expected) + +TEST_CASE("JsonError") { + SECTION("c_str()") { + TEST_STRINGIFICATION(Ok); + TEST_STRINGIFICATION(OpeningBraceExpected); + TEST_STRINGIFICATION(ClosingBraceExpected); + TEST_STRINGIFICATION(OpeningBracketExpected); + TEST_STRINGIFICATION(ClosingBracketExpected); + TEST_STRINGIFICATION(ColonExpected); + TEST_STRINGIFICATION(TooDeep); + TEST_STRINGIFICATION(NoMemory); + } + + SECTION("as boolean") { + TEST_BOOLIFICATION(Ok, false); + TEST_BOOLIFICATION(OpeningBraceExpected, true); + TEST_BOOLIFICATION(ClosingBraceExpected, true); + TEST_BOOLIFICATION(OpeningBracketExpected, true); + TEST_BOOLIFICATION(ClosingBracketExpected, true); + TEST_BOOLIFICATION(ColonExpected, true); + TEST_BOOLIFICATION(TooDeep, true); + TEST_BOOLIFICATION(NoMemory, true); + } +} diff --git a/test/JsonParser/JsonObject.cpp b/test/JsonParser/JsonObject.cpp index 41bc3e5f0..87200bf7b 100644 --- a/test/JsonParser/JsonObject.cpp +++ b/test/JsonParser/JsonObject.cpp @@ -9,36 +9,36 @@ TEST_CASE("deserializeJson(JsonObject&)") { DynamicJsonObject obj; SECTION("An empty object") { - bool success = deserializeJson(obj, "{}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 0); } SECTION("Quotes") { SECTION("Double quotes") { - bool success = deserializeJson(obj, "{\"key\":\"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\":\"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Single quotes") { - bool success = deserializeJson(obj, "{'key':'value'}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{'key':'value'}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes") { - bool success = deserializeJson(obj, "{key:value}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{key:value}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes, allow underscore in key") { - bool success = deserializeJson(obj, "{_k_e_y_:42}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{_k_e_y_:42}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["_k_e_y_"] == 42); } @@ -46,46 +46,46 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Spaces") { SECTION("Before the key") { - bool success = deserializeJson(obj, "{ \"key\":\"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{ \"key\":\"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the key") { - bool success = deserializeJson(obj, "{\"key\" :\"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\" :\"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the value") { - bool success = deserializeJson(obj, "{\"key\": \"value\"}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\": \"value\"}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the value") { - bool success = deserializeJson(obj, "{\"key\":\"value\" }"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key\":\"value\" }"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the colon") { - bool success = + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); } SECTION("After the colon") { - bool success = + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); @@ -94,41 +94,41 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Values types") { SECTION("String") { - bool success = + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); } SECTION("Integer") { - bool success = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 42); REQUIRE(obj["key2"] == -42); } SECTION("Double") { - bool success = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 12.345); REQUIRE(obj["key2"] == -7E89); } SECTION("Booleans") { - bool success = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == true); REQUIRE(obj["key2"] == false); } SECTION("Null") { - bool success = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); - REQUIRE(success == true); + JsonError err = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); + REQUIRE(err == JsonError::Ok); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"].as() == 0); REQUIRE(obj["key2"].as() == 0); @@ -137,13 +137,13 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Array") { char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; - bool success = deserializeJson(obj, jsonString); + JsonError err = deserializeJson(obj, jsonString); JsonArray &array1 = obj["ab"]; const JsonArray &array2 = obj["cd"]; JsonArray &array3 = obj["ef"]; - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(true == array1.success()); REQUIRE(true == array2.success()); @@ -165,33 +165,33 @@ TEST_CASE("deserializeJson(JsonObject&)") { SECTION("Misc") { SECTION("The opening brace is missing") { - bool success = deserializeJson(obj, "}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "}"); + REQUIRE(err == JsonError::OpeningBraceExpected); } SECTION("The closing brace is missing") { - bool success = deserializeJson(obj, "{"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{\"hello\":\"world\""); + REQUIRE(err == JsonError::ClosingBraceExpected); } SECTION("A quoted key without value") { - bool success = deserializeJson(obj, "{\"key\"}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{\"key\"}"); + REQUIRE(err == JsonError::ColonExpected); } SECTION("A non-quoted key without value") { - bool success = deserializeJson(obj, "{key}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{key}"); + REQUIRE(err == JsonError::ColonExpected); } SECTION("A dangling comma") { - bool success = deserializeJson(obj, "{\"key1\":\"value1\",}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{\"key1\":\"value1\",}"); + REQUIRE(err == JsonError::ColonExpected); } SECTION("null as a key") { - bool success = deserializeJson(obj, "null:\"value\"}"); - REQUIRE(success == false); + JsonError err = deserializeJson(obj, "{null:\"value\"}"); + REQUIRE(err == JsonError::Ok); } } } diff --git a/test/JsonParser/JsonVariant.cpp b/test/JsonParser/JsonVariant.cpp index 9141c2d48..f1b5c38ad 100644 --- a/test/JsonParser/JsonVariant.cpp +++ b/test/JsonParser/JsonVariant.cpp @@ -11,79 +11,79 @@ TEST_CASE("deserializeJson(JsonVariant&)") { DynamicJsonVariant variant; SECTION("EmptyObject") { - bool success = deserializeJson(variant, "{}"); + JsonError err = deserializeJson(variant, "{}"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); } SECTION("EmptyArray") { - bool success = deserializeJson(variant, "[]"); + JsonError err = deserializeJson(variant, "[]"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); } SECTION("Integer") { - bool success = deserializeJson(variant, "-42"); + JsonError err = deserializeJson(variant, "-42"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_FALSE(variant.is()); REQUIRE(variant == -42); } SECTION("Double") { - bool success = deserializeJson(variant, "-1.23e+4"); + JsonError err = deserializeJson(variant, "-1.23e+4"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE_FALSE(variant.is()); REQUIRE(variant.is()); REQUIRE(variant.as() == Approx(-1.23e+4)); } SECTION("Double quoted string") { - bool success = deserializeJson(variant, "\"hello world\""); + JsonError err = deserializeJson(variant, "\"hello world\""); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello world")); } SECTION("Single quoted string") { - bool success = deserializeJson(variant, "\'hello world\'"); + JsonError err = deserializeJson(variant, "\'hello world\'"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello world")); } SECTION("True") { - bool success = deserializeJson(variant, "true"); + JsonError err = deserializeJson(variant, "true"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE(variant == true); } SECTION("False") { - bool success = deserializeJson(variant, "false"); + JsonError err = deserializeJson(variant, "false"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE(variant == false); } SECTION("OpenBrace") { - bool success = deserializeJson(variant, "{"); + JsonError err = deserializeJson(variant, "{"); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("Incomplete string") { - bool success = deserializeJson(variant, "\"hello"); + JsonError err = deserializeJson(variant, "\"hello"); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello")); } diff --git a/test/JsonParser/StaticJsonArray.cpp b/test/JsonParser/StaticJsonArray.cpp index 0775fc029..6cc5208db 100644 --- a/test/JsonParser/StaticJsonArray.cpp +++ b/test/JsonParser/StaticJsonArray.cpp @@ -10,61 +10,61 @@ TEST_CASE("deserializeJson(StaticJsonArray&)") { StaticJsonArray arr; char input[] = "[]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForArrayWithOneValue") { StaticJsonArray arr; char input[] = "[1]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForArrayWithOneValue") { StaticJsonArray arr; char input[] = "[1]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForArrayWithNestedObject") { StaticJsonArray arr; char input[] = "[{}]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { StaticJsonArray arr; char input[] = "[{}]"; - bool success = deserializeJson(arr, input); + JsonError err = deserializeJson(arr, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("CharPtrNull") { StaticJsonArray<100> arr; - bool success = deserializeJson(arr, static_cast(0)); + JsonError err = deserializeJson(arr, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("ConstCharPtrNull") { StaticJsonArray<100> arr; - bool success = deserializeJson(arr, static_cast(0)); + JsonError err = deserializeJson(arr, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("CopyStringNotSpaces") { diff --git a/test/JsonParser/StaticJsonObject.cpp b/test/JsonParser/StaticJsonObject.cpp index a738e49e6..ffed607f3 100644 --- a/test/JsonParser/StaticJsonObject.cpp +++ b/test/JsonParser/StaticJsonObject.cpp @@ -10,60 +10,60 @@ TEST_CASE("deserializeJson(StaticJsonObject&)") { StaticJsonObject obj; char input[] = "{}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithOneValue") { StaticJsonObject obj; char input[] = "{\"a\":1}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithOneValue") { StaticJsonObject obj; char input[] = "{\"a\":1}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithNestedObject") { StaticJsonObject obj; char input[] = "{\"a\":[]}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { StaticJsonObject obj; char input[] = "{\"a\":[]}"; - bool success = deserializeJson(obj, input); + JsonError err = deserializeJson(obj, input); - REQUIRE(success == true); + REQUIRE(err == JsonError::Ok); } SECTION("CharPtrNull") { StaticJsonObject<100> obj; - bool success = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(obj, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } SECTION("ConstCharPtrNull") { StaticJsonObject<100> obj; - bool success = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(obj, static_cast(0)); - REQUIRE(success == false); + REQUIRE(err != JsonError::Ok); } } diff --git a/test/JsonParser/nestingLimit.cpp b/test/JsonParser/nestingLimit.cpp index 290dae67f..710a9fb56 100644 --- a/test/JsonParser/nestingLimit.cpp +++ b/test/JsonParser/nestingLimit.cpp @@ -5,44 +5,45 @@ #include #include -bool tryParseArray(const char *json, uint8_t nestingLimit) { +JsonError tryParseArray(const char *json, uint8_t nestingLimit) { DynamicJsonArray array; return deserializeJson(array, json, nestingLimit); } -bool tryParseObject(const char *json, uint8_t nestingLimit) { +JsonError tryParseObject(const char *json, uint8_t nestingLimit) { DynamicJsonObject obj; return deserializeJson(obj, json, nestingLimit); } TEST_CASE("JsonParser nestingLimit") { SECTION("ParseArrayWithNestingLimit0") { - REQUIRE(true == tryParseArray("[]", 0)); - REQUIRE(false == tryParseArray("[[]]", 0)); + REQUIRE(tryParseArray("[]", 0) == JsonError::Ok); + REQUIRE(tryParseArray("[[]]", 0) == JsonError::TooDeep); } SECTION("ParseArrayWithNestingLimit1") { - REQUIRE(true == tryParseArray("[[]]", 1)); - REQUIRE(false == tryParseArray("[[[]]]", 1)); + REQUIRE(tryParseArray("[[]]", 1) == JsonError::Ok); + REQUIRE(tryParseArray("[[[]]]", 1) == JsonError::TooDeep); } SECTION("ParseArrayWithNestingLimit2") { - REQUIRE(true == tryParseArray("[[[]]]", 2)); - REQUIRE(false == tryParseArray("[[[[]]]]", 2)); + REQUIRE(tryParseArray("[[[]]]", 2) == JsonError::Ok); + REQUIRE(tryParseArray("[[[[]]]]", 2) == JsonError::TooDeep); } SECTION("ParseObjectWithNestingLimit0") { - REQUIRE(true == tryParseObject("{}", 0)); - REQUIRE(false == tryParseObject("{\"key\":{}}", 0)); + REQUIRE(tryParseObject("{}", 0) == JsonError::Ok); + REQUIRE(tryParseObject("{\"key\":{}}", 0) == JsonError::TooDeep); } SECTION("ParseObjectWithNestingLimit1") { - REQUIRE(true == tryParseObject("{\"key\":{}}", 1)); - REQUIRE(false == tryParseObject("{\"key\":{\"key\":{}}}", 1)); + REQUIRE(tryParseObject("{\"key\":{}}", 1) == JsonError::Ok); + REQUIRE(tryParseObject("{\"key\":{\"key\":{}}}", 1) == JsonError::TooDeep); } SECTION("ParseObjectWithNestingLimit2") { - REQUIRE(true == tryParseObject("{\"key\":{\"key\":{}}}", 2)); - REQUIRE(false == tryParseObject("{\"key\":{\"key\":{\"key\":{}}}}", 2)); + REQUIRE(tryParseObject("{\"key\":{\"key\":{}}}", 2) == JsonError::Ok); + REQUIRE(tryParseObject("{\"key\":{\"key\":{\"key\":{}}}}", 2) == + JsonError::TooDeep); } } diff --git a/test/Misc/std_stream.cpp b/test/Misc/std_stream.cpp index 9af55894e..b2b171a38 100644 --- a/test/Misc/std_stream.cpp +++ b/test/Misc/std_stream.cpp @@ -56,9 +56,9 @@ TEST_CASE("std::stream") { SECTION("ParseArray") { std::istringstream json(" [ 42 /* comment */ ] "); DynamicJsonArray arr; - bool success = deserializeJson(arr, json); + JsonError err = deserializeJson(arr, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); REQUIRE(42 == arr[0]); } @@ -66,9 +66,9 @@ TEST_CASE("std::stream") { SECTION("ParseObject") { std::istringstream json(" { hello : world // comment\n }"); DynamicJsonObject obj; - bool success = deserializeJson(obj, json); + JsonError err = deserializeJson(obj, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(1 == obj.size()); REQUIRE(std::string("world") == obj["hello"]); } diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index ea11cb35a..9e58e0f1a 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -19,10 +19,10 @@ TEST_CASE("std::string") { SECTION("deserializeJson") { std::string json("[\"hello\"]"); - bool success = deserializeJson(array, json); + JsonError err = deserializeJson(array, json); eraseString(json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(std::string("hello") == array[0]); } @@ -72,10 +72,10 @@ TEST_CASE("std::string") { SECTION("deserializeJson()") { std::string json("{\"hello\":\"world\"}"); - bool success = deserializeJson(object, json); + JsonError err = deserializeJson(object, json); eraseString(json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); REQUIRE(std::string("world") == object["hello"]); } diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 146a936c3..23752b9e4 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -14,18 +14,18 @@ TEST_CASE("unsigned char string") { unsigned char json[] = "[42]"; StaticJsonArray arr; - bool success = deserializeJson(arr, json); + JsonError err = deserializeJson(arr, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); } SECTION("JsonBuffer::parseObject") { unsigned char json[] = "{\"a\":42}"; StaticJsonObject obj; - bool success = deserializeJson(obj, json); + JsonError err = deserializeJson(obj, json); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); } SECTION("JsonVariant constructor") { diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 9c16f5102..98a110d3e 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -23,9 +23,9 @@ TEST_CASE("Variable Length Array") { strcpy(vla, "[42]"); StaticJsonArray arr; - bool success = deserializeJson(arr, vla); + JsonError err = deserializeJson(arr, vla); - REQUIRE(true == success); + REQUIRE(err == JsonError::Ok); } SECTION("ParseObject") { From 3523296e3dfefa62c9c88dd37b06589e244a33f8 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 12 Mar 2018 18:28:37 +0100 Subject: [PATCH 0019/1079] Fixed `JsonBuffer::parse()` nesting limit (fixes #693) --- CHANGELOG.md | 6 ++ .../Deserialization/JsonParser.hpp | 1 - .../Deserialization/JsonParserImpl.hpp | 19 ++--- test/JsonBuffer/nestingLimit.cpp | 78 ++++++++++++------- 4 files changed, 62 insertions(+), 42 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fb7ecf94..9b25720f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ ArduinoJson: change log ======================= +HEAD +---- + +* Fixed `JsonBuffer::parse()` not respecting nesting limit correctly (issue #693) +* Fixed inconsistencies in nesting level counting (PR #695 from Zhenyu Wu) + v5.13.1 ------- diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index c348e759a..4cbaf454c 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -44,7 +44,6 @@ class JsonParser { const char *parseString(); bool parseAnythingTo(JsonVariant *destination); - FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination); inline bool parseArrayTo(JsonVariant *destination); inline bool parseObjectTo(JsonVariant *destination); diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp index 33ad42e9e..504267355 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Deserialization/JsonParserImpl.hpp @@ -20,17 +20,6 @@ template inline bool ArduinoJson::Internals::JsonParser::parseAnythingTo( JsonVariant *destination) { - if (_nestingLimit == 0) return false; - _nestingLimit--; - bool success = parseAnythingToUnsafe(destination); - _nestingLimit++; - return success; -} - -template -inline bool -ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( - JsonVariant *destination) { skipSpacesAndComments(_reader); switch (_reader.current()) { @@ -48,6 +37,9 @@ ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe( template inline ArduinoJson::JsonArray & ArduinoJson::Internals::JsonParser::parseArray() { + if (_nestingLimit == 0) return JsonArray::invalid(); + _nestingLimit--; + // Create an empty array JsonArray &array = _buffer->createArray(); @@ -69,6 +61,7 @@ ArduinoJson::Internals::JsonParser::parseArray() { SUCCESS_EMPTY_ARRAY: SUCCES_NON_EMPTY_ARRAY: + _nestingLimit++; return array; ERROR_INVALID_VALUE: @@ -91,6 +84,9 @@ inline bool ArduinoJson::Internals::JsonParser::parseArrayTo( template inline ArduinoJson::JsonObject & ArduinoJson::Internals::JsonParser::parseObject() { + if (_nestingLimit == 0) return JsonObject::invalid(); + _nestingLimit--; + // Create an empty object JsonObject &object = _buffer->createObject(); @@ -117,6 +113,7 @@ ArduinoJson::Internals::JsonParser::parseObject() { SUCCESS_EMPTY_OBJECT: SUCCESS_NON_EMPTY_OBJECT: + _nestingLimit++; return object; ERROR_INVALID_KEY: diff --git a/test/JsonBuffer/nestingLimit.cpp b/test/JsonBuffer/nestingLimit.cpp index 0d7be1151..30faca909 100644 --- a/test/JsonBuffer/nestingLimit.cpp +++ b/test/JsonBuffer/nestingLimit.cpp @@ -5,44 +5,62 @@ #include #include -bool tryParseArray(const char *json, uint8_t nestingLimit) { - DynamicJsonBuffer buffer; - return buffer.parseArray(json, nestingLimit).success(); -} - -bool tryParseObject(const char *json, uint8_t nestingLimit) { - DynamicJsonBuffer buffer; - return buffer.parseObject(json, nestingLimit).success(); -} +#define SHOULD_WORK(expression) REQUIRE(true == expression.success()); +#define SHOULD_FAIL(expression) REQUIRE(false == expression.success()); TEST_CASE("JsonParser nestingLimit") { - SECTION("ParseArrayWithNestingLimit0") { - REQUIRE(true == tryParseArray("[]", 0)); - REQUIRE(false == tryParseArray("[[]]", 0)); - } + DynamicJsonBuffer jb; - SECTION("ParseArrayWithNestingLimit1") { - REQUIRE(true == tryParseArray("[[]]", 1)); - REQUIRE(false == tryParseArray("[[[]]]", 1)); - } + SECTION("parseArray()") { + SECTION("limit = 0") { + SHOULD_FAIL(jb.parseArray("[]", 0)); + } - SECTION("ParseArrayWithNestingLimit2") { - REQUIRE(true == tryParseArray("[[[]]]", 2)); - REQUIRE(false == tryParseArray("[[[[]]]]", 2)); - } + SECTION("limit = 1") { + SHOULD_WORK(jb.parseArray("[]", 1)); + SHOULD_FAIL(jb.parseArray("[[]]", 1)); + } - SECTION("ParseObjectWithNestingLimit0") { - REQUIRE(true == tryParseObject("{}", 0)); - REQUIRE(false == tryParseObject("{\"key\":{}}", 0)); + SECTION("limit = 2") { + SHOULD_WORK(jb.parseArray("[[]]", 2)); + SHOULD_FAIL(jb.parseArray("[[[]]]", 2)); + } } - SECTION("ParseObjectWithNestingLimit1") { - REQUIRE(true == tryParseObject("{\"key\":{}}", 1)); - REQUIRE(false == tryParseObject("{\"key\":{\"key\":{}}}", 1)); + SECTION("parseObject()") { + SECTION("limit = 0") { + SHOULD_FAIL(jb.parseObject("{}", 0)); + } + + SECTION("limit = 1") { + SHOULD_WORK(jb.parseObject("{\"key\":42}", 1)); + SHOULD_FAIL(jb.parseObject("{\"key\":{\"key\":42}}", 1)); + } + + SECTION("limit = 2") { + SHOULD_WORK(jb.parseObject("{\"key\":{\"key\":42}}", 2)); + SHOULD_FAIL(jb.parseObject("{\"key\":{\"key\":{\"key\":42}}}", 2)); + } } - SECTION("ParseObjectWithNestingLimit2") { - REQUIRE(true == tryParseObject("{\"key\":{\"key\":{}}}", 2)); - REQUIRE(false == tryParseObject("{\"key\":{\"key\":{\"key\":{}}}}", 2)); + SECTION("parse()") { + SECTION("limit = 0") { + SHOULD_WORK(jb.parse("\"toto\"", 0)); + SHOULD_WORK(jb.parse("123", 0)); + SHOULD_WORK(jb.parse("true", 0)); + SHOULD_FAIL(jb.parse("[]", 0)); + SHOULD_FAIL(jb.parse("{}", 0)); + SHOULD_FAIL(jb.parse("[\"toto\"]", 0)); + SHOULD_FAIL(jb.parse("{\"toto\":1}", 0)); + } + + SECTION("limit = 1") { + SHOULD_WORK(jb.parse("[\"toto\"]", 1)); + SHOULD_WORK(jb.parse("{\"toto\":1}", 1)); + SHOULD_FAIL(jb.parse("{\"toto\":{}}", 1)); + SHOULD_FAIL(jb.parse("{\"toto\":[]}", 1)); + SHOULD_FAIL(jb.parse("[[\"toto\"]]", 1)); + SHOULD_FAIL(jb.parse("[{\"toto\":1}]", 1)); + } } } From ef55a6ba7cb9f433214e39f63e343a4b7e8f72f8 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 15 Mar 2018 09:43:10 +0100 Subject: [PATCH 0020/1079] Removed all deprecated features --- CHANGELOG.md | 1 + src/ArduinoJson/Configuration.hpp | 5 - src/ArduinoJson/JsonArray.hpp | 7 -- src/ArduinoJson/JsonArraySubscript.hpp | 8 -- src/ArduinoJson/JsonBuffer.hpp | 19 ---- src/ArduinoJson/JsonObject.hpp | 23 ---- src/ArduinoJson/JsonObjectSubscript.hpp | 8 -- src/ArduinoJson/JsonVariant.hpp | 19 ---- src/ArduinoJson/JsonVariantCasts.hpp | 21 +--- test/Misc/CMakeLists.txt | 1 - test/Misc/deprecated.cpp | 140 ------------------------ 11 files changed, 3 insertions(+), 249 deletions(-) delete mode 100644 test/Misc/deprecated.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index f316b7fa0..cf06e9422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ HEAD * Removed `JsonBuffer::createArray()` and `createObject()` * Removed `printTo()` and `prettyPrintTo()` * Removed `measureLength()` and `measurePrettyLength()` +* Removed all deprecated features > ### BREAKING CHANGES > diff --git a/src/ArduinoJson/Configuration.hpp b/src/ArduinoJson/Configuration.hpp index 82483adfa..2d0d14761 100644 --- a/src/ArduinoJson/Configuration.hpp +++ b/src/ArduinoJson/Configuration.hpp @@ -130,11 +130,6 @@ #endif #endif -// Enable deprecated functions by default -#ifndef ARDUINOJSON_ENABLE_DEPRECATED -#define ARDUINOJSON_ENABLE_DEPRECATED 1 -#endif - // Control the exponentiation threshold for big numbers // CAUTION: cannot be more that 1e9 !!!! #ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 2a9dc26d9..c050cf7e0 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -180,13 +180,6 @@ class JsonArray : public Internals::ReferenceType, } } -#if ARDUINOJSON_ENABLE_DEPRECATED - DEPRECATED("use remove() instead") - FORCE_INLINE void removeAt(size_t index) { - return remove(index); - } -#endif - private: template bool set_impl(size_t index, TValueRef value) { diff --git a/src/ArduinoJson/JsonArraySubscript.hpp b/src/ArduinoJson/JsonArraySubscript.hpp index de40afc15..a96339914 100644 --- a/src/ArduinoJson/JsonArraySubscript.hpp +++ b/src/ArduinoJson/JsonArraySubscript.hpp @@ -73,14 +73,6 @@ class JsonArraySubscript : public JsonVariantBase { FORCE_INLINE bool set(TValue* value) { return _array.set(_index, value); } - // - // bool set(TValue, uint8_t decimals); - // TValue = float, double - template - DEPRECATED("Second argument is not supported anymore") - FORCE_INLINE bool set(const TValue& value, uint8_t) { - return _array.set(_index, value); - } private: JsonArray& _array; diff --git a/src/ArduinoJson/JsonBuffer.hpp b/src/ArduinoJson/JsonBuffer.hpp index f49f423ce..1bd434ce1 100644 --- a/src/ArduinoJson/JsonBuffer.hpp +++ b/src/ArduinoJson/JsonBuffer.hpp @@ -24,25 +24,6 @@ class JsonObject; // fixed memory allocation. class JsonBuffer : Internals::NonCopyable { public: - // Duplicates a string - // - // const char* strdup(TValue); - // TValue = const std::string&, const String&, - template - DEPRECATED("char* are duplicated, you don't need strdup() anymore") - typename Internals::EnableIf::value, - const char *>::type strdup(const TString &src) { - return Internals::StringTraits::duplicate(src, this); - } - // - // const char* strdup(TValue); - // TValue = char*, const char*, const FlashStringHelper* - template - DEPRECATED("char* are duplicated, you don't need strdup() anymore") - const char *strdup(TString *src) { - return Internals::StringTraits::duplicate(src, this); - } - // Allocates n bytes in the JsonBuffer. // Return a pointer to the allocated memory or NULL if allocation fails. virtual void *alloc(size_t size) = 0; diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index d182ae7a1..502cc038b 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -112,29 +112,6 @@ class JsonObject : public Internals::ReferenceType, bool set(TString* key, TValue* value) { return set_impl(key, value); } - // - // bool set(TKey, TValue, uint8_t decimals); - // TKey = const std::string&, const String& - // TValue = float, double - template - DEPRECATED("Second argument is not supported anymore") - typename Internals::EnableIf::value, - bool>::type - set(const TString& key, TValue value, uint8_t) { - return set_impl(key, - JsonVariant(value)); - } - // - // bool set(TKey, TValue, uint8_t decimals); - // TKey = char*, const char*, const FlashStringHelper* - // TValue = float, double - template - DEPRECATED("Second argument is not supported anymore") - typename Internals::EnableIf::value, - bool>::type - set(TString* key, TValue value, uint8_t) { - return set_impl(key, JsonVariant(value)); - } // Gets the value associated with the specified key. // diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index e108f3f50..832d0ca91 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -81,14 +81,6 @@ class JsonObjectSubscript FORCE_INLINE bool set(const TValue* value) { return _object.set(_key, value); } - // - // bool set(TValue, uint8_t decimals); - // TValue = float, double - template - DEPRECATED("Second argument is not supported anymore") - FORCE_INLINE bool set(const TValue& value, uint8_t) { - return _object.set(_key, value); - } private: JsonObject& _object; diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index 9fffb4afd..598df822f 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -65,15 +65,6 @@ class JsonVariant : public Internals::JsonVariantBase { _type = JSON_FLOAT; _content.asFloat = static_cast(value); } - template - DEPRECATED("Second argument is not supported anymore") - JsonVariant(T value, uint8_t, - typename Internals::EnableIf< - Internals::IsFloatingPoint::value>::type * = 0) { - using namespace Internals; - _type = JSON_FLOAT; - _content.asFloat = static_cast(value); - } // Create a JsonVariant containing an integer value. // JsonVariant(char) @@ -355,14 +346,4 @@ class JsonVariant : public Internals::JsonVariantBase { // The various alternatives for the value of the variant. Internals::JsonVariantContent _content; }; - -DEPRECATED("Decimal places are ignored, use the float value instead") -inline JsonVariant float_with_n_digits(float value, uint8_t) { - return JsonVariant(value); -} - -DEPRECATED("Decimal places are ignored, use the double value instead") -inline JsonVariant double_with_n_digits(double value, uint8_t) { - return JsonVariant(value); -} } // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonVariantCasts.hpp b/src/ArduinoJson/JsonVariantCasts.hpp index 68f5bd7dd..3f4ee0186 100644 --- a/src/ArduinoJson/JsonVariantCasts.hpp +++ b/src/ArduinoJson/JsonVariantCasts.hpp @@ -13,23 +13,6 @@ namespace Internals { template class JsonVariantCasts { public: -#if ARDUINOJSON_ENABLE_DEPRECATED - DEPRECATED("use as() instead") - FORCE_INLINE JsonArray &asArray() const { - return impl()->template as(); - } - - DEPRECATED("use as() instead") - FORCE_INLINE JsonObject &asObject() const { - return impl()->template as(); - } - - DEPRECATED("use as() instead") - FORCE_INLINE const char *asString() const { - return impl()->template as(); - } -#endif - // Gets the variant as an array. // Returns a reference to the JsonArray or JsonArray::invalid() if the // variant @@ -55,5 +38,5 @@ class JsonVariantCasts { return static_cast(this); } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/test/Misc/CMakeLists.txt b/test/Misc/CMakeLists.txt index 0b54bd7bd..28e273d02 100644 --- a/test/Misc/CMakeLists.txt +++ b/test/Misc/CMakeLists.txt @@ -3,7 +3,6 @@ # MIT License add_executable(MiscTests - deprecated.cpp FloatParts.cpp std_stream.cpp std_string.cpp diff --git a/test/Misc/deprecated.cpp b/test/Misc/deprecated.cpp deleted file mode 100644 index b84ad65cd..000000000 --- a/test/Misc/deprecated.cpp +++ /dev/null @@ -1,140 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#define ARDUINOJSON_ENABLE_DEPRECATED 1 - -#include -#include - -#if defined(__clang__) -#pragma clang diagnostic ignored "-Wdeprecated-declarations" -#elif defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#elif defined(_MSC_VER) -#pragma warning(disable : 4996) -#endif - -TEST_CASE("Deprecated functions") { - SECTION("JsonVariant::asArray()") { - DynamicJsonArray array; - JsonVariant variant = array; - REQUIRE(variant.asArray().success()); - } - - SECTION("JsonVariant::asObject()") { - DynamicJsonObject obj; - JsonVariant variant = obj; - REQUIRE(variant.asObject().success()); - } - - SECTION("JsonVariant::asString()") { - JsonVariant variant = "hello"; - REQUIRE(std::string("hello") == variant.asString()); - } - - SECTION("JsonArray::removeAt()") { - DynamicJsonArray arr; - arr.removeAt(0); - } - - SECTION("JsonVariant::JsonVariant(float, uint8_t)") { - JsonVariant variant(3.14f, 2); - REQUIRE(variant == 3.14f); - } - - SECTION("JsonVariant::JsonVariant(double, uint8_t)") { - JsonVariant variant(3.14, 2); - REQUIRE(variant == 3.14); - } - - SECTION("float_with_n_digits()") { - JsonVariant variant = float_with_n_digits(3.14f, 4); - REQUIRE(variant == 3.14f); - } - - SECTION("double_with_n_digits()") { - JsonVariant variant = double_with_n_digits(3.14f, 4); - REQUIRE(variant == 3.14f); - } - - SECTION("JsonArraySubscript::set(double, uint8_t)") { - DynamicJsonArray arr; - arr.add(666); - arr[0].set(123.45, 2); - REQUIRE(123.45 == arr[0].as()); - REQUIRE(true == arr[0].is()); - REQUIRE(false == arr[0].is()); - } - - SECTION("JsonArray::add(double, uint8_t)") { - DynamicJsonArray arr; - arr.add(3.14159265358979323846, 4); - } - - SECTION("JsonArray::add(float, uint8_t)") { - DynamicJsonArray arr; - arr.add(3.14159265358979323846f, 4); - } - - SECTION("JsonObject::set(unsigned char[], double, uint8_t)") { - unsigned char key[] = "hello"; - - DynamicJsonObject obj; - obj.set(key, 3.14, 2); - - REQUIRE(3.14 == obj["hello"]); - } - - SECTION("JsonObject::set(const char*, double, uint8_t)") { - DynamicJsonObject obj; - obj.set("hello", 123.45, 2); - - REQUIRE(123.45 == obj["hello"].as()); - REQUIRE(obj["hello"].is()); - REQUIRE_FALSE(obj["hello"].is()); - } - - SECTION("JsonObjectSubscript::set(double, uint8_t)") { - DynamicJsonObject obj; - obj["hello"].set(123.45, 2); - - REQUIRE(true == obj["hello"].is()); - REQUIRE(false == obj["hello"].is()); - REQUIRE(123.45 == obj["hello"].as()); - } -} - -TEST_CASE("DynamicJsonBuffer::strdup()") { - DynamicJsonBuffer buffer; - - SECTION("char*") { - char original[] = "hello"; - const char* copy = buffer.strdup(original); - strcpy(original, "world"); - REQUIRE(std::string("hello") == copy); - } - - SECTION("unsigned char*") { - unsigned char value[] = "world"; - - DynamicJsonBuffer jsonBuffer; - const char* dup = jsonBuffer.strdup(value); - - REQUIRE(static_cast(value) != static_cast(dup)); - REQUIRE(std::string("world") == dup); - } - - SECTION("std::string") { - std::string original("hello"); - const char* copy = buffer.strdup(original); - original[0] = 'w'; - REQUIRE(std::string("hello") == copy); - } - - SECTION("NULL") { - const char* original = NULL; - const char* copy = buffer.strdup(original); - REQUIRE(0 == copy); - } -} From cf149940ed37b7454bec0fa492d26a19e1a82d17 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 15 Mar 2018 09:56:00 +0100 Subject: [PATCH 0021/1079] Moved JsonBuffer to Memory/ --- src/ArduinoJson.hpp | 2 -- src/ArduinoJson/Data/List.hpp | 2 +- src/ArduinoJson/Data/ListNode.hpp | 6 +++--- src/ArduinoJson/Data/ValueSaver.hpp | 6 +++--- src/ArduinoJson/Deserialization/JsonParser.hpp | 2 +- src/ArduinoJson/DynamicJsonArray.hpp | 2 +- src/ArduinoJson/DynamicJsonObject.hpp | 2 +- src/ArduinoJson/DynamicJsonVariant.hpp | 2 +- src/ArduinoJson/JsonArray.hpp | 4 ++-- src/ArduinoJson/JsonObject.hpp | 4 ++-- .../{ => Memory}/DynamicJsonBuffer.hpp | 0 src/ArduinoJson/{ => Memory}/JsonBuffer.hpp | 16 ++++++---------- .../{Data => Memory}/JsonBufferAllocated.hpp | 6 +++--- .../{ => Memory}/StaticJsonBuffer.hpp | 2 +- .../{Data => Polyfills}/NonCopyable.hpp | 0 src/ArduinoJson/StaticJsonArray.hpp | 2 +- src/ArduinoJson/StaticJsonObject.hpp | 2 +- src/ArduinoJson/StaticJsonVariant.hpp | 2 +- 18 files changed, 28 insertions(+), 34 deletions(-) rename src/ArduinoJson/{ => Memory}/DynamicJsonBuffer.hpp (100%) rename src/ArduinoJson/{ => Memory}/JsonBuffer.hpp (80%) rename src/ArduinoJson/{Data => Memory}/JsonBufferAllocated.hpp (82%) rename src/ArduinoJson/{ => Memory}/StaticJsonBuffer.hpp (98%) rename src/ArduinoJson/{Data => Polyfills}/NonCopyable.hpp (100%) diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 83830e2d9..c06d01163 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -5,11 +5,9 @@ #pragma once #include "ArduinoJson/DynamicJsonArray.hpp" -#include "ArduinoJson/DynamicJsonBuffer.hpp" #include "ArduinoJson/DynamicJsonObject.hpp" #include "ArduinoJson/DynamicJsonVariant.hpp" #include "ArduinoJson/StaticJsonArray.hpp" -#include "ArduinoJson/StaticJsonBuffer.hpp" #include "ArduinoJson/StaticJsonObject.hpp" #include "ArduinoJson/StaticJsonVariant.hpp" #include "ArduinoJson/deserializeJson.hpp" diff --git a/src/ArduinoJson/Data/List.hpp b/src/ArduinoJson/Data/List.hpp index f1e9b07b4..14215966e 100644 --- a/src/ArduinoJson/Data/List.hpp +++ b/src/ArduinoJson/Data/List.hpp @@ -4,7 +4,7 @@ #pragma once -#include "../JsonBuffer.hpp" +#include "../Memory/JsonBuffer.hpp" #include "ListConstIterator.hpp" #include "ListIterator.hpp" diff --git a/src/ArduinoJson/Data/ListNode.hpp b/src/ArduinoJson/Data/ListNode.hpp index c0907120e..f6e2a5e29 100644 --- a/src/ArduinoJson/Data/ListNode.hpp +++ b/src/ArduinoJson/Data/ListNode.hpp @@ -6,7 +6,7 @@ #include // for NULL -#include "JsonBufferAllocated.hpp" +#include "../Memory/JsonBufferAllocated.hpp" namespace ArduinoJson { namespace Internals { @@ -20,5 +20,5 @@ struct ListNode : public Internals::JsonBufferAllocated { ListNode *next; T content; }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Data/ValueSaver.hpp b/src/ArduinoJson/Data/ValueSaver.hpp index 9750f1ac5..4e1904d6b 100644 --- a/src/ArduinoJson/Data/ValueSaver.hpp +++ b/src/ArduinoJson/Data/ValueSaver.hpp @@ -4,8 +4,8 @@ #pragma once -#include "../JsonBuffer.hpp" #include "../JsonVariant.hpp" +#include "../Memory/JsonBuffer.hpp" #include "../StringTraits/StringTraits.hpp" #include "../TypeTraits/EnableIf.hpp" @@ -48,5 +48,5 @@ struct ValueSaver< return true; } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Deserialization/JsonParser.hpp index cbc7df6ff..d4a9c8f41 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Deserialization/JsonParser.hpp @@ -4,9 +4,9 @@ #pragma once -#include "../JsonBuffer.hpp" #include "../JsonError.hpp" #include "../JsonVariant.hpp" +#include "../Memory/JsonBuffer.hpp" #include "../TypeTraits/IsConst.hpp" #include "StringWriter.hpp" diff --git a/src/ArduinoJson/DynamicJsonArray.hpp b/src/ArduinoJson/DynamicJsonArray.hpp index 216402f10..0ec0d80ee 100644 --- a/src/ArduinoJson/DynamicJsonArray.hpp +++ b/src/ArduinoJson/DynamicJsonArray.hpp @@ -4,8 +4,8 @@ #pragma once -#include "DynamicJsonBuffer.hpp" #include "JsonArray.hpp" +#include "Memory/DynamicJsonBuffer.hpp" namespace ArduinoJson { class DynamicJsonArray : public JsonArray { diff --git a/src/ArduinoJson/DynamicJsonObject.hpp b/src/ArduinoJson/DynamicJsonObject.hpp index c602e7915..5e40ba40b 100644 --- a/src/ArduinoJson/DynamicJsonObject.hpp +++ b/src/ArduinoJson/DynamicJsonObject.hpp @@ -4,8 +4,8 @@ #pragma once -#include "DynamicJsonBuffer.hpp" #include "JsonObject.hpp" +#include "Memory/DynamicJsonBuffer.hpp" namespace ArduinoJson { class DynamicJsonObject : public JsonObject { diff --git a/src/ArduinoJson/DynamicJsonVariant.hpp b/src/ArduinoJson/DynamicJsonVariant.hpp index 32e228896..ccc110420 100644 --- a/src/ArduinoJson/DynamicJsonVariant.hpp +++ b/src/ArduinoJson/DynamicJsonVariant.hpp @@ -4,8 +4,8 @@ #pragma once -#include "DynamicJsonBuffer.hpp" #include "JsonVariant.hpp" +#include "Memory/DynamicJsonBuffer.hpp" namespace ArduinoJson { diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index c050cf7e0..2a77cf819 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -4,11 +4,11 @@ #pragma once -#include "Data/JsonBufferAllocated.hpp" #include "Data/List.hpp" #include "Data/ReferenceType.hpp" #include "Data/ValueSaver.hpp" #include "JsonVariant.hpp" +#include "Memory/JsonBufferAllocated.hpp" #include "StringTraits/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsArray.hpp" @@ -34,7 +34,7 @@ class JsonArray : public Internals::ReferenceType, public Internals::List, public Internals::JsonBufferAllocated { public: - explicit JsonArray(JsonBuffer *buf) throw() + explicit JsonArray(Internals::JsonBuffer *buf) throw() : Internals::List(buf) {} // Gets the value at the specified index diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 502cc038b..8c432c44d 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -4,11 +4,11 @@ #pragma once -#include "Data/JsonBufferAllocated.hpp" #include "Data/List.hpp" #include "Data/ReferenceType.hpp" #include "Data/ValueSaver.hpp" #include "JsonPair.hpp" +#include "Memory/JsonBufferAllocated.hpp" #include "StringTraits/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsArray.hpp" @@ -37,7 +37,7 @@ class JsonObject : public Internals::ReferenceType, public: // Create an empty JsonArray attached to the specified JsonBuffer. // You should not use this constructor directly. - explicit JsonObject(JsonBuffer* buf) throw() + explicit JsonObject(Internals::JsonBuffer* buf) throw() : Internals::List(buf) {} // Gets or sets the value associated with the specified key. diff --git a/src/ArduinoJson/DynamicJsonBuffer.hpp b/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp similarity index 100% rename from src/ArduinoJson/DynamicJsonBuffer.hpp rename to src/ArduinoJson/Memory/DynamicJsonBuffer.hpp diff --git a/src/ArduinoJson/JsonBuffer.hpp b/src/ArduinoJson/Memory/JsonBuffer.hpp similarity index 80% rename from src/ArduinoJson/JsonBuffer.hpp rename to src/ArduinoJson/Memory/JsonBuffer.hpp index 1bd434ce1..dedf2e381 100644 --- a/src/ArduinoJson/JsonBuffer.hpp +++ b/src/ArduinoJson/Memory/JsonBuffer.hpp @@ -8,21 +8,16 @@ #include // for uint8_t #include -#include "Data/NonCopyable.hpp" -#include "JsonVariant.hpp" -#include "TypeTraits/EnableIf.hpp" -#include "TypeTraits/IsArray.hpp" +#include "../Configuration.hpp" +#include "../Polyfills/NonCopyable.hpp" +#include "../Polyfills/attributes.hpp" namespace ArduinoJson { -class JsonArray; -class JsonObject; - -// Entry point for using the library. -// +namespace Internals { // Handle the memory management (done in derived classes) and calls the parser. // This abstract class is implemented by StaticJsonBuffer which implements a // fixed memory allocation. -class JsonBuffer : Internals::NonCopyable { +class JsonBuffer : NonCopyable { public: // Allocates n bytes in the JsonBuffer. // Return a pointer to the allocated memory or NULL if allocation fails. @@ -44,4 +39,5 @@ class JsonBuffer : Internals::NonCopyable { #endif } }; +} // namespace Internals } // namespace ArduinoJson diff --git a/src/ArduinoJson/Data/JsonBufferAllocated.hpp b/src/ArduinoJson/Memory/JsonBufferAllocated.hpp similarity index 82% rename from src/ArduinoJson/Data/JsonBufferAllocated.hpp rename to src/ArduinoJson/Memory/JsonBufferAllocated.hpp index 443aae4df..4712ccb12 100644 --- a/src/ArduinoJson/Data/JsonBufferAllocated.hpp +++ b/src/ArduinoJson/Memory/JsonBufferAllocated.hpp @@ -4,7 +4,7 @@ #pragma once -#include "../JsonBuffer.hpp" +#include "JsonBuffer.hpp" namespace ArduinoJson { namespace Internals { @@ -18,5 +18,5 @@ class JsonBufferAllocated { void operator delete(void *, JsonBuffer *)throw(); }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonBuffer.hpp b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp similarity index 98% rename from src/ArduinoJson/StaticJsonBuffer.hpp rename to src/ArduinoJson/Memory/StaticJsonBuffer.hpp index dd13dfa9d..237221d48 100644 --- a/src/ArduinoJson/StaticJsonBuffer.hpp +++ b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp @@ -4,8 +4,8 @@ #pragma once +#include "../TypeTraits/Max.hpp" #include "JsonBuffer.hpp" -#include "TypeTraits/Max.hpp" namespace ArduinoJson { namespace Internals { diff --git a/src/ArduinoJson/Data/NonCopyable.hpp b/src/ArduinoJson/Polyfills/NonCopyable.hpp similarity index 100% rename from src/ArduinoJson/Data/NonCopyable.hpp rename to src/ArduinoJson/Polyfills/NonCopyable.hpp diff --git a/src/ArduinoJson/StaticJsonArray.hpp b/src/ArduinoJson/StaticJsonArray.hpp index 6ace2d694..25bd8b60f 100644 --- a/src/ArduinoJson/StaticJsonArray.hpp +++ b/src/ArduinoJson/StaticJsonArray.hpp @@ -5,7 +5,7 @@ #pragma once #include "JsonArray.hpp" -#include "StaticJsonBuffer.hpp" +#include "Memory/StaticJsonBuffer.hpp" namespace ArduinoJson { diff --git a/src/ArduinoJson/StaticJsonObject.hpp b/src/ArduinoJson/StaticJsonObject.hpp index c46a97a38..ae5538f32 100644 --- a/src/ArduinoJson/StaticJsonObject.hpp +++ b/src/ArduinoJson/StaticJsonObject.hpp @@ -5,7 +5,7 @@ #pragma once #include "JsonObject.hpp" -#include "StaticJsonBuffer.hpp" +#include "Memory/StaticJsonBuffer.hpp" namespace ArduinoJson { diff --git a/src/ArduinoJson/StaticJsonVariant.hpp b/src/ArduinoJson/StaticJsonVariant.hpp index e565b1850..4d9a74868 100644 --- a/src/ArduinoJson/StaticJsonVariant.hpp +++ b/src/ArduinoJson/StaticJsonVariant.hpp @@ -5,7 +5,7 @@ #pragma once #include "JsonVariant.hpp" -#include "StaticJsonBuffer.hpp" +#include "Memory/StaticJsonBuffer.hpp" namespace ArduinoJson { From 0d1623edef2298ab0843cd8606ea08782bbc6d8f Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Sun, 18 Mar 2018 14:50:52 +0100 Subject: [PATCH 0022/1079] Clear the JsonObject or JsonArray in deserializeJson() --- src/ArduinoJson/Data/List.hpp | 4 +++ src/ArduinoJson/DynamicJsonArray.hpp | 5 +++ src/ArduinoJson/DynamicJsonObject.hpp | 5 +++ src/ArduinoJson/DynamicJsonVariant.hpp | 7 +++- src/ArduinoJson/StaticJsonArray.hpp | 5 +++ src/ArduinoJson/StaticJsonObject.hpp | 5 +++ src/ArduinoJson/StaticJsonVariant.hpp | 8 +++-- src/ArduinoJson/deserializeJson.hpp | 3 ++ test/JsonParser/CMakeLists.txt | 7 ++-- .../{JsonArray.cpp => DynamicJsonArray.cpp} | 10 +++++- .../{JsonObject.cpp => DynamicJsonObject.cpp} | 9 ++++- ...JsonVariant.cpp => DynamicJsonVariant.cpp} | 10 +++++- test/JsonParser/StaticJsonArray.cpp | 11 ++++++ test/JsonParser/StaticJsonObject.cpp | 11 ++++++ test/JsonParser/StaticJsonVariant.cpp | 35 +++++++++++++++++++ 15 files changed, 126 insertions(+), 9 deletions(-) rename test/JsonParser/{JsonArray.cpp => DynamicJsonArray.cpp} (97%) rename test/JsonParser/{JsonObject.cpp => DynamicJsonObject.cpp} (95%) rename test/JsonParser/{JsonVariant.cpp => DynamicJsonVariant.cpp} (88%) create mode 100644 test/JsonParser/StaticJsonVariant.cpp diff --git a/src/ArduinoJson/Data/List.hpp b/src/ArduinoJson/Data/List.hpp index 14215966e..185a62234 100644 --- a/src/ArduinoJson/Data/List.hpp +++ b/src/ArduinoJson/Data/List.hpp @@ -89,6 +89,10 @@ class List { } protected: + void clear() { + _firstNode = 0; + } + JsonBuffer *_buffer; private: diff --git a/src/ArduinoJson/DynamicJsonArray.hpp b/src/ArduinoJson/DynamicJsonArray.hpp index 0ec0d80ee..6b82c6e24 100644 --- a/src/ArduinoJson/DynamicJsonArray.hpp +++ b/src/ArduinoJson/DynamicJsonArray.hpp @@ -16,6 +16,11 @@ class DynamicJsonArray : public JsonArray { DynamicJsonArray(size_t capacity) : JsonArray(&_buffer), _buffer(capacity - sizeof(JsonArray)) {} + void clear() { + Internals::List::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonArray); } diff --git a/src/ArduinoJson/DynamicJsonObject.hpp b/src/ArduinoJson/DynamicJsonObject.hpp index 5e40ba40b..c442377cc 100644 --- a/src/ArduinoJson/DynamicJsonObject.hpp +++ b/src/ArduinoJson/DynamicJsonObject.hpp @@ -20,6 +20,11 @@ class DynamicJsonObject : public JsonObject { return _buffer; } + void clear() { + Internals::List::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonObject); } diff --git a/src/ArduinoJson/DynamicJsonVariant.hpp b/src/ArduinoJson/DynamicJsonVariant.hpp index ccc110420..3f67ec42f 100644 --- a/src/ArduinoJson/DynamicJsonVariant.hpp +++ b/src/ArduinoJson/DynamicJsonVariant.hpp @@ -14,6 +14,7 @@ class DynamicJsonVariant : public JsonVariant { public: DynamicJsonVariant() : JsonVariant() {} + DynamicJsonVariant(size_t capacity) : JsonVariant(), _buffer(capacity) {} template DynamicJsonVariant& operator=(const T& value) { @@ -33,8 +34,12 @@ class DynamicJsonVariant : public JsonVariant { return _buffer; } + void clear() { + _buffer.clear(); + } + size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonVariant); + return _buffer.size(); } }; } // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonArray.hpp b/src/ArduinoJson/StaticJsonArray.hpp index 25bd8b60f..21b3a2207 100644 --- a/src/ArduinoJson/StaticJsonArray.hpp +++ b/src/ArduinoJson/StaticJsonArray.hpp @@ -16,6 +16,11 @@ class StaticJsonArray : public JsonArray { public: StaticJsonArray() : JsonArray(&_buffer) {} + void clear() { + Internals::List::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonArray); } diff --git a/src/ArduinoJson/StaticJsonObject.hpp b/src/ArduinoJson/StaticJsonObject.hpp index ae5538f32..0b5912a84 100644 --- a/src/ArduinoJson/StaticJsonObject.hpp +++ b/src/ArduinoJson/StaticJsonObject.hpp @@ -16,6 +16,11 @@ class StaticJsonObject : public JsonObject { public: StaticJsonObject() : JsonObject(&_buffer) {} + void clear() { + Internals::List::clear(); + _buffer.clear(); + } + size_t memoryUsage() const { return _buffer.size() + sizeof(JsonObject); } diff --git a/src/ArduinoJson/StaticJsonVariant.hpp b/src/ArduinoJson/StaticJsonVariant.hpp index 4d9a74868..250e17549 100644 --- a/src/ArduinoJson/StaticJsonVariant.hpp +++ b/src/ArduinoJson/StaticJsonVariant.hpp @@ -11,7 +11,7 @@ namespace ArduinoJson { template class StaticJsonVariant : public JsonVariant { - StaticJsonBuffer _buffer; + StaticJsonBuffer _buffer; public: template @@ -32,8 +32,12 @@ class StaticJsonVariant : public JsonVariant { return _buffer; } + void clear() { + _buffer.clear(); + } + size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonVariant); + return _buffer.size(); } }; } // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index 4593529f1..b6e4659f7 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -15,6 +15,7 @@ typename Internals::EnableIf::value, JsonError>::type deserializeJson(TDestination &destination, const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + destination.clear(); return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } @@ -26,6 +27,7 @@ template JsonError deserializeJson( TDestination &destination, TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + destination.clear(); return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } @@ -37,6 +39,7 @@ template JsonError deserializeJson( TDestination &destination, TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + destination.clear(); return Internals::makeParser(&destination.buffer(), json, nestingLimit) .parse(destination); } diff --git a/test/JsonParser/CMakeLists.txt b/test/JsonParser/CMakeLists.txt index 19381c404..35f8e57c2 100644 --- a/test/JsonParser/CMakeLists.txt +++ b/test/JsonParser/CMakeLists.txt @@ -3,13 +3,14 @@ # MIT License add_executable(JsonParserTests - JsonArray.cpp + DynamicJsonArray.cpp + DynamicJsonObject.cpp + DynamicJsonVariant.cpp JsonError.cpp - JsonObject.cpp - JsonVariant.cpp nestingLimit.cpp StaticJsonArray.cpp StaticJsonObject.cpp + StaticJsonVariant.cpp ) target_link_libraries(JsonParserTests catch) diff --git a/test/JsonParser/JsonArray.cpp b/test/JsonParser/DynamicJsonArray.cpp similarity index 97% rename from test/JsonParser/JsonArray.cpp rename to test/JsonParser/DynamicJsonArray.cpp index 5a9a6b14c..cfb498f75 100644 --- a/test/JsonParser/JsonArray.cpp +++ b/test/JsonParser/DynamicJsonArray.cpp @@ -5,7 +5,7 @@ #include #include -TEST_CASE("deserializeJson(JsonArray&)") { +TEST_CASE("deserializeJson(DynamicJsonArray&)") { DynamicJsonArray arr; SECTION("An empty array") { @@ -350,4 +350,12 @@ TEST_CASE("deserializeJson(JsonArray&)") { REQUIRE(0 == object3["e"].as()); } } + + SECTION("Should clear the JsonArray") { + deserializeJson(arr, "[1,2,3,4]"); + deserializeJson(arr, "[]"); + + REQUIRE(arr.size() == 0); + REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); + } } diff --git a/test/JsonParser/JsonObject.cpp b/test/JsonParser/DynamicJsonObject.cpp similarity index 95% rename from test/JsonParser/JsonObject.cpp rename to test/JsonParser/DynamicJsonObject.cpp index 87200bf7b..72e6d2c50 100644 --- a/test/JsonParser/JsonObject.cpp +++ b/test/JsonParser/DynamicJsonObject.cpp @@ -5,7 +5,7 @@ #include #include -TEST_CASE("deserializeJson(JsonObject&)") { +TEST_CASE("deserializeJson(DynamicJsonObject&)") { DynamicJsonObject obj; SECTION("An empty object") { @@ -194,4 +194,11 @@ TEST_CASE("deserializeJson(JsonObject&)") { REQUIRE(err == JsonError::Ok); } } + + SECTION("Should clear the JsonObject") { + deserializeJson(obj, "{\"hello\":\"world\"}"); + deserializeJson(obj, "{}"); + REQUIRE(obj.size() == 0); + REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); + } } diff --git a/test/JsonParser/JsonVariant.cpp b/test/JsonParser/DynamicJsonVariant.cpp similarity index 88% rename from test/JsonParser/JsonVariant.cpp rename to test/JsonParser/DynamicJsonVariant.cpp index f1b5c38ad..50449d9a5 100644 --- a/test/JsonParser/JsonVariant.cpp +++ b/test/JsonParser/DynamicJsonVariant.cpp @@ -7,7 +7,7 @@ using namespace Catch::Matchers; -TEST_CASE("deserializeJson(JsonVariant&)") { +TEST_CASE("deserializeJson(DynamicJsonVariant&)") { DynamicJsonVariant variant; SECTION("EmptyObject") { @@ -87,4 +87,12 @@ TEST_CASE("deserializeJson(JsonVariant&)") { REQUIRE(variant.is()); REQUIRE_THAT(variant.as(), Equals("hello")); } + + SECTION("Should clear the JsonVariant") { + deserializeJson(variant, "[1,2,3]"); + deserializeJson(variant, "{}"); + + REQUIRE(variant.is()); + REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); + } } diff --git a/test/JsonParser/StaticJsonArray.cpp b/test/JsonParser/StaticJsonArray.cpp index 6cc5208db..3a79749b3 100644 --- a/test/JsonParser/StaticJsonArray.cpp +++ b/test/JsonParser/StaticJsonArray.cpp @@ -76,4 +76,15 @@ TEST_CASE("deserializeJson(StaticJsonArray&)") { // 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 arr; + char input[] = "[1,2,3,4]"; + + deserializeJson(arr, input); + deserializeJson(arr, "[]"); + + REQUIRE(arr.size() == 0); + REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); + } } diff --git a/test/JsonParser/StaticJsonObject.cpp b/test/JsonParser/StaticJsonObject.cpp index ffed607f3..525f5184f 100644 --- a/test/JsonParser/StaticJsonObject.cpp +++ b/test/JsonParser/StaticJsonObject.cpp @@ -66,4 +66,15 @@ TEST_CASE("deserializeJson(StaticJsonObject&)") { REQUIRE(err != JsonError::Ok); } + + SECTION("Should clear the JsonObject") { + StaticJsonObject obj; + char input[] = "{\"hello\":\"world\"}"; + + deserializeJson(obj, input); + deserializeJson(obj, "{}"); + + REQUIRE(obj.size() == 0); + REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); + } } diff --git a/test/JsonParser/StaticJsonVariant.cpp b/test/JsonParser/StaticJsonVariant.cpp new file mode 100644 index 000000000..a3fba6e10 --- /dev/null +++ b/test/JsonParser/StaticJsonVariant.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +using namespace Catch::Matchers; + +TEST_CASE("deserializeJson(StaticJsonVariant&)") { + SECTION("Array") { + StaticJsonVariant variant; + + char input[] = "[1,2]"; + JsonError err = deserializeJson(variant, input); + + REQUIRE(err == JsonError::Ok); + REQUIRE(variant.is()); + REQUIRE(variant[0] == 1); + REQUIRE(variant[1] == 2); + REQUIRE(variant.memoryUsage() == JSON_ARRAY_SIZE(2)); + } + + SECTION("Should clear the JsonVariant") { + StaticJsonVariant variant; + char input[] = "[1,2]"; + deserializeJson(variant, input); + + JsonError err = deserializeJson(variant, "{}"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(variant.is()); + REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); + } +} From 923d3e8a8431ec1d11fc81f1944d1207dc3f6668 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Fri, 23 Mar 2018 09:20:50 +0100 Subject: [PATCH 0023/1079] Removed friend relationship between JsonVariant and JsonSerializer --- src/ArduinoJson/JsonVariant.hpp | 40 ++++++++++++++---- .../Serialization/JsonSerializer.hpp | 41 +++++++++++++++++++ .../Serialization/JsonSerializerImpl.hpp | 36 +--------------- 3 files changed, 75 insertions(+), 42 deletions(-) diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index 598df822f..1a79af063 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -27,10 +27,6 @@ namespace ArduinoJson { // Forward declarations. class JsonArray; class JsonObject; -namespace Internals { -template -class JsonSerializer; -} // A variant that can be a any value serializable to a JSON value. // @@ -40,9 +36,6 @@ class JsonSerializer; // - a string (const char*) // - a reference to a JsonArray or JsonObject class JsonVariant : public Internals::JsonVariantBase { - template - friend class Internals::JsonSerializer; - public: // Creates an uninitialized JsonVariant JsonVariant() : _type(Internals::JSON_UNDEFINED) {} @@ -317,6 +310,39 @@ class JsonVariant : public Internals::JsonVariantBase { return _type != Internals::JSON_UNDEFINED; } + template + void visit(Visitor visitor) const { + using namespace Internals; + switch (_type) { + case JSON_FLOAT: + return visitor.acceptFloat(_content.asFloat); + + case JSON_ARRAY: + return visitor.acceptArray(*_content.asArray); + + case JSON_OBJECT: + return visitor.acceptObject(*_content.asObject); + + case JSON_STRING: + return visitor.acceptString(_content.asString); + + case JSON_UNPARSED: + return visitor.acceptRawJson(_content.asString); + + case JSON_NEGATIVE_INTEGER: + return visitor.acceptNegativeInteger(_content.asInteger); + + case JSON_POSITIVE_INTEGER: + return visitor.acceptPositiveInteger(_content.asInteger); + + case JSON_BOOLEAN: + return visitor.acceptBoolean(_content.asInteger != 0); + + default: // JSON_UNDEFINED + return visitor.acceptUndefined(); + } + } + private: JsonArray &variantAsArray() const; JsonObject &variantAsObject() const; diff --git a/src/ArduinoJson/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Serialization/JsonSerializer.hpp index 211e9fbfc..1bf8810d3 100644 --- a/src/ArduinoJson/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Serialization/JsonSerializer.hpp @@ -36,6 +36,47 @@ class JsonSerializer { template static void serialize(const JsonObjectSubscript &, Writer &); static void serialize(const JsonVariant &, Writer &); + + struct Visitor { + Visitor(Writer *writer) : _writer(writer) {} + + void acceptFloat(JsonFloat value) { + _writer->writeFloat(value); + } + + void acceptArray(const JsonArray &value) { + serialize(value, *_writer); + } + + void acceptObject(const JsonObject &value) { + serialize(value, *_writer); + } + + void acceptString(const char *value) { + _writer->writeString(value); + } + + void acceptRawJson(const char *value) { + _writer->writeRaw(value); + } + + void acceptNegativeInteger(JsonUInt value) { + _writer->writeRaw('-'); + _writer->writeInteger(value); + } + + void acceptPositiveInteger(JsonUInt value) { + _writer->writeInteger(value); + } + + void acceptBoolean(bool value) { + _writer->writeBoolean(value); + } + + void acceptUndefined() {} + + Writer *_writer; + }; }; } // namespace Internals diff --git a/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp b/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp index 0faae2769..da24cd93f 100644 --- a/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp +++ b/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp @@ -65,39 +65,5 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize( template inline void ArduinoJson::Internals::JsonSerializer::serialize( const JsonVariant& variant, Writer& writer) { - switch (variant._type) { - case JSON_FLOAT: - writer.writeFloat(variant._content.asFloat); - return; - - case JSON_ARRAY: - serialize(*variant._content.asArray, writer); - return; - - case JSON_OBJECT: - serialize(*variant._content.asObject, writer); - return; - - case JSON_STRING: - writer.writeString(variant._content.asString); - return; - - case JSON_UNPARSED: - writer.writeRaw(variant._content.asString); - return; - - case JSON_NEGATIVE_INTEGER: - writer.writeRaw('-'); // Falls through. - - case JSON_POSITIVE_INTEGER: - writer.writeInteger(variant._content.asInteger); - return; - - case JSON_BOOLEAN: - writer.writeBoolean(variant._content.asInteger != 0); - return; - - default: // JSON_UNDEFINED - return; - } + variant.visit(Visitor(&writer)); } From cb723840d9ad24bb1db6d4dc800f7e5c730aba5f Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Tue, 10 Apr 2018 17:43:27 +0200 Subject: [PATCH 0024/1079] Added `deserializeMsgPack()` (issue #358) --- .travis.yml | 6 - CHANGELOG.md | 1 + src/ArduinoJson.hpp | 6 +- src/ArduinoJson/Configuration.hpp | 10 + src/ArduinoJson/Data/ValueSaver.hpp | 2 +- .../{ => Json}/Deserialization/Comments.hpp | 0 .../{ => Json}/Deserialization/JsonParser.hpp | 10 +- .../Deserialization/JsonParserImpl.hpp | 2 +- src/ArduinoJson/{Data => Json}/Encoding.hpp | 0 .../{ => Json}/Serialization/FloatParts.hpp | 10 +- .../Serialization/IndentedPrint.hpp | 0 .../Serialization/JsonSerializer.hpp | 14 +- .../Serialization/JsonSerializerImpl.hpp | 10 +- .../{ => Json}/Serialization/JsonWriter.hpp | 8 +- .../{ => Json}/Serialization/Prettyfier.hpp | 0 src/ArduinoJson/JsonArray.hpp | 2 +- src/ArduinoJson/JsonError.hpp | 17 +- src/ArduinoJson/JsonObject.hpp | 2 +- src/ArduinoJson/JsonVariantComparisons.hpp | 6 +- src/ArduinoJson/JsonVariantImpl.hpp | 8 +- src/ArduinoJson/JsonVariantSubscripts.hpp | 6 +- .../MsgPack/MsgPackDeserializer.hpp | 328 ++++++++++++++++++ src/ArduinoJson/MsgPack/MsgPackError.hpp | 67 ++++ src/ArduinoJson/MsgPack/endianess.hpp | 47 +++ src/ArduinoJson/MsgPack/ieee754.hpp | 18 + .../{Serialization => Print}/DummyPrint.hpp | 0 .../DynamicStringBuilder.hpp | 6 +- .../StaticStringBuilder.hpp | 0 .../StreamPrintAdapter.hpp | 0 .../ArduinoStream.hpp | 0 .../{StringTraits => Strings}/CharPointer.hpp | 0 .../{StringTraits => Strings}/FlashString.hpp | 0 .../{StringTraits => Strings}/StdStream.hpp | 0 .../{StringTraits => Strings}/StdString.hpp | 0 .../StringTraits.hpp | 0 .../StringWriter.hpp | 0 .../{Polyfills => Text}/isFloat.hpp | 6 +- .../{Polyfills => Text}/isInteger.hpp | 6 +- .../{Polyfills => Text}/parseFloat.hpp | 8 +- .../{Polyfills => Text}/parseInteger.hpp | 6 +- src/ArduinoJson/deserializeJson.hpp | 2 +- src/ArduinoJson/deserializeMsgPack.hpp | 49 +++ test/CMakeLists.txt | 1 + test/JsonWriter/writeFloat.cpp | 4 +- test/JsonWriter/writeString.cpp | 4 +- test/Misc/FloatParts.cpp | 2 +- test/MsgPack/CMakeLists.txt | 16 + test/MsgPack/MsgPackError.cpp | 40 +++ test/MsgPack/deserializationErrors.cpp | 58 ++++ test/MsgPack/deserializeArray.cpp | 85 +++++ test/MsgPack/deserializeObject.cpp | 86 +++++ test/MsgPack/deserializeStaticVariant.cpp | 131 +++++++ test/MsgPack/deserializeVariant.cpp | 277 +++++++++++++++ test/MsgPack/doubleToFloat.cpp | 25 ++ test/Polyfills/isFloat.cpp | 2 +- test/Polyfills/isInteger.cpp | 2 +- test/Polyfills/parseFloat.cpp | 2 +- test/Polyfills/parseInteger.cpp | 2 +- 58 files changed, 1311 insertions(+), 89 deletions(-) rename src/ArduinoJson/{ => Json}/Deserialization/Comments.hpp (100%) rename src/ArduinoJson/{ => Json}/Deserialization/JsonParser.hpp (94%) rename src/ArduinoJson/{ => Json}/Deserialization/JsonParserImpl.hpp (99%) rename src/ArduinoJson/{Data => Json}/Encoding.hpp (100%) rename src/ArduinoJson/{ => Json}/Serialization/FloatParts.hpp (92%) rename src/ArduinoJson/{ => Json}/Serialization/IndentedPrint.hpp (100%) rename src/ArduinoJson/{ => Json}/Serialization/JsonSerializer.hpp (95%) rename src/ArduinoJson/{ => Json}/Serialization/JsonSerializerImpl.hpp (90%) rename src/ArduinoJson/{ => Json}/Serialization/JsonWriter.hpp (95%) rename src/ArduinoJson/{ => Json}/Serialization/Prettyfier.hpp (100%) create mode 100644 src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp create mode 100644 src/ArduinoJson/MsgPack/MsgPackError.hpp create mode 100644 src/ArduinoJson/MsgPack/endianess.hpp create mode 100644 src/ArduinoJson/MsgPack/ieee754.hpp rename src/ArduinoJson/{Serialization => Print}/DummyPrint.hpp (100%) rename src/ArduinoJson/{Serialization => Print}/DynamicStringBuilder.hpp (87%) rename src/ArduinoJson/{Serialization => Print}/StaticStringBuilder.hpp (100%) rename src/ArduinoJson/{Serialization => Print}/StreamPrintAdapter.hpp (100%) rename src/ArduinoJson/{StringTraits => Strings}/ArduinoStream.hpp (100%) rename src/ArduinoJson/{StringTraits => Strings}/CharPointer.hpp (100%) rename src/ArduinoJson/{StringTraits => Strings}/FlashString.hpp (100%) rename src/ArduinoJson/{StringTraits => Strings}/StdStream.hpp (100%) rename src/ArduinoJson/{StringTraits => Strings}/StdString.hpp (100%) rename src/ArduinoJson/{StringTraits => Strings}/StringTraits.hpp (100%) rename src/ArduinoJson/{Deserialization => Strings}/StringWriter.hpp (100%) rename src/ArduinoJson/{Polyfills => Text}/isFloat.hpp (87%) rename src/ArduinoJson/{Polyfills => Text}/isInteger.hpp (76%) rename src/ArduinoJson/{Polyfills => Text}/parseFloat.hpp (94%) rename src/ArduinoJson/{Polyfills => Text}/parseInteger.hpp (87%) create mode 100644 src/ArduinoJson/deserializeMsgPack.hpp create mode 100644 test/MsgPack/CMakeLists.txt create mode 100644 test/MsgPack/MsgPackError.cpp create mode 100644 test/MsgPack/deserializationErrors.cpp create mode 100644 test/MsgPack/deserializeArray.cpp create mode 100644 test/MsgPack/deserializeObject.cpp create mode 100644 test/MsgPack/deserializeStaticVariant.cpp create mode 100644 test/MsgPack/deserializeVariant.cpp create mode 100644 test/MsgPack/doubleToFloat.cpp diff --git a/.travis.yml b/.travis.yml index 9a9dddcd3..9605e80cc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,6 @@ sudo: false language: cpp matrix: include: - - compiler: gcc - addons: - apt: - sources: ['ubuntu-toolchain-r-test'] - packages: ['g++-4.4'] - env: SCRIPT=cmake GCC=4.4 - compiler: gcc addons: apt: diff --git a/CHANGELOG.md b/CHANGELOG.md index cf06e9422..0783de862 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ HEAD * Added `deserializeJson()` * Added `serializeJson()` and `serializeJsonPretty()` * Added `measureJson()` and `measureJsonPretty()` +* Added `deserializeMsgPack()` (issue #358) * Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` * Removed `JsonBuffer::createArray()` and `createObject()` * Removed `printTo()` and `prettyPrintTo()` diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index c06d01163..2830ce261 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -7,13 +7,15 @@ #include "ArduinoJson/DynamicJsonArray.hpp" #include "ArduinoJson/DynamicJsonObject.hpp" #include "ArduinoJson/DynamicJsonVariant.hpp" +#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" #include "ArduinoJson/StaticJsonArray.hpp" #include "ArduinoJson/StaticJsonObject.hpp" #include "ArduinoJson/StaticJsonVariant.hpp" #include "ArduinoJson/deserializeJson.hpp" +#include "ArduinoJson/deserializeMsgPack.hpp" -#include "ArduinoJson/Deserialization/JsonParserImpl.hpp" +#include "ArduinoJson/Json/Deserialization/JsonParserImpl.hpp" +#include "ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp" #include "ArduinoJson/JsonArrayImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp" #include "ArduinoJson/JsonVariantImpl.hpp" -#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp" diff --git a/src/ArduinoJson/Configuration.hpp b/src/ArduinoJson/Configuration.hpp index 2d0d14761..af4ea0b58 100644 --- a/src/ArduinoJson/Configuration.hpp +++ b/src/ArduinoJson/Configuration.hpp @@ -144,3 +144,13 @@ #if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64 #error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together #endif + +#ifndef ARDUINOJSON_LITTLE_ENDIAN +#if defined(_MSC_VER) || \ + (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ + (defined(__LITTLE_ENDIAN__)) +#define ARDUINOJSON_LITTLE_ENDIAN 1 +#else +#define ARDUINOJSON_LITTLE_ENDIAN 0 +#endif +#endif diff --git a/src/ArduinoJson/Data/ValueSaver.hpp b/src/ArduinoJson/Data/ValueSaver.hpp index 4e1904d6b..4416ebc91 100644 --- a/src/ArduinoJson/Data/ValueSaver.hpp +++ b/src/ArduinoJson/Data/ValueSaver.hpp @@ -6,7 +6,7 @@ #include "../JsonVariant.hpp" #include "../Memory/JsonBuffer.hpp" -#include "../StringTraits/StringTraits.hpp" +#include "../Strings/StringTraits.hpp" #include "../TypeTraits/EnableIf.hpp" namespace ArduinoJson { diff --git a/src/ArduinoJson/Deserialization/Comments.hpp b/src/ArduinoJson/Json/Deserialization/Comments.hpp similarity index 100% rename from src/ArduinoJson/Deserialization/Comments.hpp rename to src/ArduinoJson/Json/Deserialization/Comments.hpp diff --git a/src/ArduinoJson/Deserialization/JsonParser.hpp b/src/ArduinoJson/Json/Deserialization/JsonParser.hpp similarity index 94% rename from src/ArduinoJson/Deserialization/JsonParser.hpp rename to src/ArduinoJson/Json/Deserialization/JsonParser.hpp index d4a9c8f41..c1a34a70e 100644 --- a/src/ArduinoJson/Deserialization/JsonParser.hpp +++ b/src/ArduinoJson/Json/Deserialization/JsonParser.hpp @@ -4,11 +4,11 @@ #pragma once -#include "../JsonError.hpp" -#include "../JsonVariant.hpp" -#include "../Memory/JsonBuffer.hpp" -#include "../TypeTraits/IsConst.hpp" -#include "StringWriter.hpp" +#include "../../JsonError.hpp" +#include "../../JsonVariant.hpp" +#include "../../Memory/JsonBuffer.hpp" +#include "../../Strings/StringWriter.hpp" +#include "../../TypeTraits/IsConst.hpp" namespace ArduinoJson { namespace Internals { diff --git a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp similarity index 99% rename from src/ArduinoJson/Deserialization/JsonParserImpl.hpp rename to src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp index e9cbd2cf4..dd43c0cae 100644 --- a/src/ArduinoJson/Deserialization/JsonParserImpl.hpp +++ b/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp @@ -4,7 +4,7 @@ #pragma once -#include "../Data/Encoding.hpp" +#include "../Encoding.hpp" #include "Comments.hpp" #include "JsonParser.hpp" diff --git a/src/ArduinoJson/Data/Encoding.hpp b/src/ArduinoJson/Json/Encoding.hpp similarity index 100% rename from src/ArduinoJson/Data/Encoding.hpp rename to src/ArduinoJson/Json/Encoding.hpp diff --git a/src/ArduinoJson/Serialization/FloatParts.hpp b/src/ArduinoJson/Json/Serialization/FloatParts.hpp similarity index 92% rename from src/ArduinoJson/Serialization/FloatParts.hpp rename to src/ArduinoJson/Json/Serialization/FloatParts.hpp index c14e3b553..4f42a9c22 100644 --- a/src/ArduinoJson/Serialization/FloatParts.hpp +++ b/src/ArduinoJson/Json/Serialization/FloatParts.hpp @@ -4,9 +4,9 @@ #pragma once -#include "../Configuration.hpp" -#include "../Polyfills/math.hpp" -#include "../TypeTraits/FloatTraits.hpp" +#include "../../Configuration.hpp" +#include "../../Polyfills/math.hpp" +#include "../../TypeTraits/FloatTraits.hpp" namespace ArduinoJson { namespace Internals { @@ -85,5 +85,5 @@ struct FloatParts { return powersOf10; } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Serialization/IndentedPrint.hpp b/src/ArduinoJson/Json/Serialization/IndentedPrint.hpp similarity index 100% rename from src/ArduinoJson/Serialization/IndentedPrint.hpp rename to src/ArduinoJson/Json/Serialization/IndentedPrint.hpp diff --git a/src/ArduinoJson/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp similarity index 95% rename from src/ArduinoJson/Serialization/JsonSerializer.hpp rename to src/ArduinoJson/Json/Serialization/JsonSerializer.hpp index 1bf8810d3..a8c6e3286 100644 --- a/src/ArduinoJson/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp @@ -4,15 +4,15 @@ #pragma once -#include "DummyPrint.hpp" -#include "DynamicStringBuilder.hpp" -#include "IndentedPrint.hpp" -#include "JsonWriter.hpp" -#include "Prettyfier.hpp" -#include "StaticStringBuilder.hpp" +#include "../../Print/DummyPrint.hpp" +#include "../../Print/DynamicStringBuilder.hpp" +#include "../../Print/StaticStringBuilder.hpp" +#include "./IndentedPrint.hpp" +#include "./JsonWriter.hpp" +#include "./Prettyfier.hpp" #if ARDUINOJSON_ENABLE_STD_STREAM -#include "StreamPrintAdapter.hpp" +#include "../../Print/StreamPrintAdapter.hpp" #endif namespace ArduinoJson { diff --git a/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp b/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp similarity index 90% rename from src/ArduinoJson/Serialization/JsonSerializerImpl.hpp rename to src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp index da24cd93f..2060cae54 100644 --- a/src/ArduinoJson/Serialization/JsonSerializerImpl.hpp +++ b/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp @@ -4,11 +4,11 @@ #pragma once -#include "../JsonArray.hpp" -#include "../JsonArraySubscript.hpp" -#include "../JsonObject.hpp" -#include "../JsonObjectSubscript.hpp" -#include "../JsonVariant.hpp" +#include "../../JsonArray.hpp" +#include "../../JsonArraySubscript.hpp" +#include "../../JsonObject.hpp" +#include "../../JsonObjectSubscript.hpp" +#include "../../JsonVariant.hpp" #include "JsonSerializer.hpp" template diff --git a/src/ArduinoJson/Serialization/JsonWriter.hpp b/src/ArduinoJson/Json/Serialization/JsonWriter.hpp similarity index 95% rename from src/ArduinoJson/Serialization/JsonWriter.hpp rename to src/ArduinoJson/Json/Serialization/JsonWriter.hpp index d56828636..f613f7e5b 100644 --- a/src/ArduinoJson/Serialization/JsonWriter.hpp +++ b/src/ArduinoJson/Json/Serialization/JsonWriter.hpp @@ -5,10 +5,10 @@ #pragma once #include -#include "../Data/Encoding.hpp" -#include "../Data/JsonInteger.hpp" -#include "../Polyfills/attributes.hpp" -#include "../Serialization/FloatParts.hpp" +#include "../../Data/JsonInteger.hpp" +#include "../../Polyfills/attributes.hpp" +#include "../Encoding.hpp" +#include "./FloatParts.hpp" namespace ArduinoJson { namespace Internals { diff --git a/src/ArduinoJson/Serialization/Prettyfier.hpp b/src/ArduinoJson/Json/Serialization/Prettyfier.hpp similarity index 100% rename from src/ArduinoJson/Serialization/Prettyfier.hpp rename to src/ArduinoJson/Json/Serialization/Prettyfier.hpp diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 2a77cf819..51757f207 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -9,7 +9,7 @@ #include "Data/ValueSaver.hpp" #include "JsonVariant.hpp" #include "Memory/JsonBufferAllocated.hpp" -#include "StringTraits/StringTraits.hpp" +#include "Strings/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsArray.hpp" #include "TypeTraits/IsFloatingPoint.hpp" diff --git a/src/ArduinoJson/JsonError.hpp b/src/ArduinoJson/JsonError.hpp index 6349a98bf..d7f4c903c 100644 --- a/src/ArduinoJson/JsonError.hpp +++ b/src/ArduinoJson/JsonError.hpp @@ -42,15 +42,7 @@ class JsonError { } const char* c_str() const { - return to_string(_code); - } - - friend const char* to_string(const JsonError err) { - return to_string(err._code); - } - - friend const char* to_string(JsonError::Code code) { - switch (code) { + switch (_code) { case Ok: return "Ok"; case OpeningBraceExpected: @@ -78,12 +70,7 @@ class JsonError { #if ARDUINOJSON_ENABLE_STD_STREAM inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { - s << to_string(e); - return s; -} - -inline std::ostream& operator<<(std::ostream& s, JsonError::Code e) { - s << to_string(e); + s << e.c_str(); return s; } #endif diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 8c432c44d..43e39ec73 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -9,7 +9,7 @@ #include "Data/ValueSaver.hpp" #include "JsonPair.hpp" #include "Memory/JsonBufferAllocated.hpp" -#include "StringTraits/StringTraits.hpp" +#include "Strings/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsArray.hpp" #include "TypeTraits/IsFloatingPoint.hpp" diff --git a/src/ArduinoJson/JsonVariantComparisons.hpp b/src/ArduinoJson/JsonVariantComparisons.hpp index cae533729..dbd84d978 100644 --- a/src/ArduinoJson/JsonVariantComparisons.hpp +++ b/src/ArduinoJson/JsonVariantComparisons.hpp @@ -4,7 +4,7 @@ #pragma once -#include "StringTraits/StringTraits.hpp" +#include "Strings/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" #include "TypeTraits/IsVariant.hpp" @@ -134,5 +134,5 @@ class JsonVariantComparisons { return false; } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonVariantImpl.hpp b/src/ArduinoJson/JsonVariantImpl.hpp index 93f70f096..138827cba 100644 --- a/src/ArduinoJson/JsonVariantImpl.hpp +++ b/src/ArduinoJson/JsonVariantImpl.hpp @@ -8,10 +8,10 @@ #include "JsonArray.hpp" #include "JsonObject.hpp" #include "JsonVariant.hpp" -#include "Polyfills/isFloat.hpp" -#include "Polyfills/isInteger.hpp" -#include "Polyfills/parseFloat.hpp" -#include "Polyfills/parseInteger.hpp" +#include "Text/isFloat.hpp" +#include "Text/isInteger.hpp" +#include "Text/parseFloat.hpp" +#include "Text/parseInteger.hpp" #include // for strcmp diff --git a/src/ArduinoJson/JsonVariantSubscripts.hpp b/src/ArduinoJson/JsonVariantSubscripts.hpp index 279ee019f..ec28c6862 100644 --- a/src/ArduinoJson/JsonVariantSubscripts.hpp +++ b/src/ArduinoJson/JsonVariantSubscripts.hpp @@ -6,7 +6,7 @@ #include "Data/JsonVariantAs.hpp" #include "Polyfills/attributes.hpp" -#include "StringTraits/StringTraits.hpp" +#include "Strings/StringTraits.hpp" #include "TypeTraits/EnableIf.hpp" namespace ArduinoJson { @@ -82,5 +82,5 @@ class JsonVariantSubscripts { return static_cast(this); } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp new file mode 100644 index 000000000..0cf05c56f --- /dev/null +++ b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -0,0 +1,328 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "../JsonVariant.hpp" +#include "../Memory/JsonBuffer.hpp" +#include "../Strings/StringWriter.hpp" +#include "../TypeTraits/IsConst.hpp" +#include "./MsgPackError.hpp" +#include "./endianess.hpp" +#include "./ieee754.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 +class MsgPackDeserializer { + public: + MsgPackDeserializer(JsonBuffer *buffer, TReader reader, TWriter writer, + uint8_t nestingLimit) + : _buffer(buffer), + _reader(reader), + _writer(writer), + _nestingLimit(nestingLimit) {} + + MsgPackError parse(JsonArray &array) { + uint8_t c = readOne(); + size_t n; + + if ((c & 0xF0) == 0x90) { + n = c & 0x0F; + } else if (c == 0xdc) { + n = readInteger(); + } else if (c == 0xdd) { + n = readInteger(); + } 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(); + } else if (c == 0xdf) { + n = readInteger(); + } else { + return MsgPackError::NotAnObject; + } + + return readObject(object, n); + } + + MsgPackError parse(JsonVariant &variant) { + uint8_t c = readOne(); + + if ((c & 0x80) == 0) { + variant = c; + return MsgPackError::Ok; + } + + if ((c & 0xe0) == 0xe0) { + variant = static_cast(c); + return MsgPackError::Ok; + } + + if ((c & 0xe0) == 0xa0) { + return readString(variant, c & 0x1f); + } + + if ((c & 0xf0) == 0x90) return readArray(variant, c & 0x0F); + + if ((c & 0xf0) == 0x80) return readObject(variant, c & 0x0F); + + switch (c) { + case 0xc0: + variant = static_cast(0); + return MsgPackError::Ok; + + case 0xc2: + variant = false; + return MsgPackError::Ok; + + case 0xc3: + variant = true; + return MsgPackError::Ok; + + case 0xcc: + variant = readInteger(); + return MsgPackError::Ok; + + case 0xcd: + variant = readInteger(); + return MsgPackError::Ok; + + case 0xce: + variant = readInteger(); + return MsgPackError::Ok; + + case 0xcf: +#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 + variant = readInteger(); +#else + readInteger(); + variant = readInteger(); +#endif + return MsgPackError::Ok; + + case 0xd0: + variant = readInteger(); + return MsgPackError::Ok; + + case 0xd1: + variant = readInteger(); + return MsgPackError::Ok; + + case 0xd2: + variant = readInteger(); + return MsgPackError::Ok; + + case 0xd3: +#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 + variant = readInteger(); +#else + readInteger(); + variant = readInteger(); +#endif + return MsgPackError::Ok; + + case 0xca: + variant = readFloat(); + return MsgPackError::Ok; + + case 0xcb: + variant = readDouble(); + return MsgPackError::Ok; + + case 0xd9: { + uint8_t n = readInteger(); + return readString(variant, n); + } + + case 0xda: { + uint16_t n = readInteger(); + return readString(variant, n); + } + + case 0xdb: { + uint32_t n = readInteger(); + return readString(variant, n); + } + + case 0xdc: + return readArray(variant, readInteger()); + + case 0xdd: + return readArray(variant, readInteger()); + + case 0xde: + return readObject(variant, readInteger()); + + case 0xdf: + return readObject(variant, readInteger()); + + default: + return MsgPackError::NotSupported; + } + } + + private: + // Prevent VS warning "assignment operator could not be generated" + MsgPackDeserializer &operator=(const MsgPackDeserializer &); + + uint8_t readOne() { + char c = _reader.current(); + _reader.move(); + return static_cast(c); + } + + void read(uint8_t *p, size_t n) { + for (size_t i = 0; i < n; i++) p[i] = readOne(); + } + + template + void read(T &value) { + read(reinterpret_cast(&value), sizeof(value)); + } + + template + T readInteger() { + T value; + read(value); + fixEndianess(value); + return value; + } + + template + typename EnableIf::type readFloat() { + T value; + read(value); + fixEndianess(value); + return value; + } + + template + typename EnableIf::type readDouble() { + T value; + read(value); + fixEndianess(value); + return value; + } + + template + typename EnableIf::type readDouble() { + uint8_t i[8]; // input is 8 bytes + T value; // output is 4 bytes + uint8_t *o = reinterpret_cast(&value); + read(i, 8); + doubleToFloat(i, o); + fixEndianess(value); + return value; + } + + MsgPackError readString(JsonVariant &variant, size_t n) { + typename RemoveReference::type::String str = _writer.startString(); + for (; n; --n) str.append(static_cast(readOne())); + const char *s = str.c_str(); + if (s == NULL) return MsgPackError::NoMemory; + variant = s; + return MsgPackError::Ok; + } + + MsgPackError readArray(JsonVariant &variant, size_t n) { + JsonArray *array = new (_buffer) JsonArray(_buffer); + if (!array) return MsgPackError::NoMemory; + variant = array; + return readArray(*array, n); + } + + MsgPackError readArray(JsonArray &array, size_t n) { + if (_nestingLimit == 0) return MsgPackError::TooDeep; + --_nestingLimit; + for (; n; --n) { + JsonVariant variant; + MsgPackError err = parse(variant); + if (err) return err; + if (!array.add(variant)) return MsgPackError::NoMemory; + } + ++_nestingLimit; + return MsgPackError::Ok; + } + + MsgPackError readObject(JsonVariant &variant, size_t n) { + JsonObject *object = new (_buffer) JsonObject(_buffer); + if (!object) return MsgPackError::NoMemory; + variant = object; + return readObject(*object, n); + } + + MsgPackError readObject(JsonObject &object, size_t n) { + if (_nestingLimit == 0) return MsgPackError::TooDeep; + --_nestingLimit; + for (; n; --n) { + MsgPackError err; + JsonVariant variant; + err = parse(variant); + if (err) return err; + const char *key = variant.as(); + if (!key) return MsgPackError::NotSupported; + err = parse(variant); + if (err) return err; + if (!object.set(key, variant)) return MsgPackError::NoMemory; + } + ++_nestingLimit; + return MsgPackError::Ok; + } + + JsonBuffer *_buffer; + TReader _reader; + TWriter _writer; + uint8_t _nestingLimit; +}; + +template +struct MsgPackDeserializerBuilder { + typedef typename StringTraits::Reader InputReader; + typedef MsgPackDeserializer TParser; + + static TParser makeMsgPackDeserializer(TJsonBuffer *buffer, TString &json, + uint8_t nestingLimit) { + return TParser(buffer, InputReader(json), *buffer, nestingLimit); + } +}; + +template +struct MsgPackDeserializerBuilder< + TJsonBuffer, TChar *, typename EnableIf::value>::type> { + typedef typename StringTraits::Reader TReader; + typedef StringWriter TWriter; + typedef MsgPackDeserializer TParser; + + static TParser makeMsgPackDeserializer(TJsonBuffer *buffer, TChar *json, + uint8_t nestingLimit) { + return TParser(buffer, TReader(json), TWriter(json), nestingLimit); + } +}; + +template +inline typename MsgPackDeserializerBuilder::TParser +makeMsgPackDeserializer(TJsonBuffer *buffer, TString &json, + uint8_t nestingLimit) { + return MsgPackDeserializerBuilder< + TJsonBuffer, TString>::makeMsgPackDeserializer(buffer, json, + nestingLimit); +} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/MsgPack/MsgPackError.hpp b/src/ArduinoJson/MsgPack/MsgPackError.hpp new file mode 100644 index 000000000..0162aac63 --- /dev/null +++ b/src/ArduinoJson/MsgPack/MsgPackError.hpp @@ -0,0 +1,67 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { + +class MsgPackError { + public: + enum Code { Ok, NotSupported, NoMemory, NotAnArray, NotAnObject, TooDeep }; + + MsgPackError() {} + + MsgPackError(Code code) : _code(code) {} + + operator bool() const { + return _code != Ok; + } + + friend bool operator==(const MsgPackError& err, Code code) { + return err._code == code; + } + + friend bool operator==(Code code, const MsgPackError& err) { + return err._code == code; + } + + friend bool operator!=(const MsgPackError& err, Code code) { + return err._code != code; + } + + friend bool operator!=(Code code, const MsgPackError& err) { + return err._code != code; + } + + const char* c_str() const { + switch (_code) { + case Ok: + return "Ok"; + case NotSupported: + return "NotSupported"; + case NoMemory: + return "NoMemory"; + case NotAnArray: + return "NotAnArray"; + case NotAnObject: + return "NotAnObject"; + case TooDeep: + return "TooDeep"; + default: + return "???"; + } + } + + private: + Code _code; +}; + +#if ARDUINOJSON_ENABLE_STD_STREAM +inline std::ostream& operator<<(std::ostream& os, const MsgPackError& err) { + os << err.c_str(); + return os; +} +#endif + +} // namespace ArduinoJson diff --git a/src/ArduinoJson/MsgPack/endianess.hpp b/src/ArduinoJson/MsgPack/endianess.hpp new file mode 100644 index 000000000..26f2b9063 --- /dev/null +++ b/src/ArduinoJson/MsgPack/endianess.hpp @@ -0,0 +1,47 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +template +struct integral_constant {}; + +template +inline void swap(T& a, T& b) { + T t(a); + a = b; + b = t; +} + +inline void fixEndianess(uint8_t* p, integral_constant) { + swap(p[0], p[7]); + swap(p[1], p[6]); + swap(p[2], p[5]); + swap(p[3], p[4]); +} + +inline void fixEndianess(uint8_t* p, integral_constant) { + swap(p[0], p[3]); + swap(p[1], p[2]); +} + +inline void fixEndianess(uint8_t* p, integral_constant) { + swap(p[0], p[1]); +} + +inline void fixEndianess(uint8_t*, integral_constant) {} + +template +inline void fixEndianess(T& value) { +#if ARDUINOJSON_LITTLE_ENDIAN + fixEndianess(reinterpret_cast(&value), + integral_constant()); +#endif +} + +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/MsgPack/ieee754.hpp b/src/ArduinoJson/MsgPack/ieee754.hpp new file mode 100644 index 000000000..19e7f2851 --- /dev/null +++ b/src/ArduinoJson/MsgPack/ieee754.hpp @@ -0,0 +1,18 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +inline void doubleToFloat(const uint8_t d[8], uint8_t f[4]) { + f[0] = uint8_t((d[0] & 0xC0) | (d[0] << 3 & 0x3f) | (d[1] >> 5)); + f[1] = uint8_t((d[1] << 3) | (d[2] >> 5)); + f[2] = uint8_t((d[2] << 3) | (d[3] >> 5)); + f[3] = uint8_t((d[3] << 3) | (d[4] >> 5)); +} + +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Serialization/DummyPrint.hpp b/src/ArduinoJson/Print/DummyPrint.hpp similarity index 100% rename from src/ArduinoJson/Serialization/DummyPrint.hpp rename to src/ArduinoJson/Print/DummyPrint.hpp diff --git a/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp b/src/ArduinoJson/Print/DynamicStringBuilder.hpp similarity index 87% rename from src/ArduinoJson/Serialization/DynamicStringBuilder.hpp rename to src/ArduinoJson/Print/DynamicStringBuilder.hpp index 41be6392c..931066ae7 100644 --- a/src/ArduinoJson/Serialization/DynamicStringBuilder.hpp +++ b/src/ArduinoJson/Print/DynamicStringBuilder.hpp @@ -4,7 +4,7 @@ #pragma once -#include "../StringTraits/StringTraits.hpp" +#include "../Strings/StringTraits.hpp" namespace ArduinoJson { namespace Internals { @@ -31,5 +31,5 @@ class DynamicStringBuilder { TString &_str; }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Serialization/StaticStringBuilder.hpp b/src/ArduinoJson/Print/StaticStringBuilder.hpp similarity index 100% rename from src/ArduinoJson/Serialization/StaticStringBuilder.hpp rename to src/ArduinoJson/Print/StaticStringBuilder.hpp diff --git a/src/ArduinoJson/Serialization/StreamPrintAdapter.hpp b/src/ArduinoJson/Print/StreamPrintAdapter.hpp similarity index 100% rename from src/ArduinoJson/Serialization/StreamPrintAdapter.hpp rename to src/ArduinoJson/Print/StreamPrintAdapter.hpp diff --git a/src/ArduinoJson/StringTraits/ArduinoStream.hpp b/src/ArduinoJson/Strings/ArduinoStream.hpp similarity index 100% rename from src/ArduinoJson/StringTraits/ArduinoStream.hpp rename to src/ArduinoJson/Strings/ArduinoStream.hpp diff --git a/src/ArduinoJson/StringTraits/CharPointer.hpp b/src/ArduinoJson/Strings/CharPointer.hpp similarity index 100% rename from src/ArduinoJson/StringTraits/CharPointer.hpp rename to src/ArduinoJson/Strings/CharPointer.hpp diff --git a/src/ArduinoJson/StringTraits/FlashString.hpp b/src/ArduinoJson/Strings/FlashString.hpp similarity index 100% rename from src/ArduinoJson/StringTraits/FlashString.hpp rename to src/ArduinoJson/Strings/FlashString.hpp diff --git a/src/ArduinoJson/StringTraits/StdStream.hpp b/src/ArduinoJson/Strings/StdStream.hpp similarity index 100% rename from src/ArduinoJson/StringTraits/StdStream.hpp rename to src/ArduinoJson/Strings/StdStream.hpp diff --git a/src/ArduinoJson/StringTraits/StdString.hpp b/src/ArduinoJson/Strings/StdString.hpp similarity index 100% rename from src/ArduinoJson/StringTraits/StdString.hpp rename to src/ArduinoJson/Strings/StdString.hpp diff --git a/src/ArduinoJson/StringTraits/StringTraits.hpp b/src/ArduinoJson/Strings/StringTraits.hpp similarity index 100% rename from src/ArduinoJson/StringTraits/StringTraits.hpp rename to src/ArduinoJson/Strings/StringTraits.hpp diff --git a/src/ArduinoJson/Deserialization/StringWriter.hpp b/src/ArduinoJson/Strings/StringWriter.hpp similarity index 100% rename from src/ArduinoJson/Deserialization/StringWriter.hpp rename to src/ArduinoJson/Strings/StringWriter.hpp diff --git a/src/ArduinoJson/Polyfills/isFloat.hpp b/src/ArduinoJson/Text/isFloat.hpp similarity index 87% rename from src/ArduinoJson/Polyfills/isFloat.hpp rename to src/ArduinoJson/Text/isFloat.hpp index 973b89fe9..5e241ede9 100644 --- a/src/ArduinoJson/Polyfills/isFloat.hpp +++ b/src/ArduinoJson/Text/isFloat.hpp @@ -5,7 +5,7 @@ #pragma once #include // for strcmp -#include "./ctype.hpp" +#include "../Polyfills/ctype.hpp" namespace ArduinoJson { namespace Internals { @@ -34,5 +34,5 @@ inline bool isFloat(const char* s) { return *s == '\0'; } -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/isInteger.hpp b/src/ArduinoJson/Text/isInteger.hpp similarity index 76% rename from src/ArduinoJson/Polyfills/isInteger.hpp rename to src/ArduinoJson/Text/isInteger.hpp index 21f166897..b87ebc25a 100644 --- a/src/ArduinoJson/Polyfills/isInteger.hpp +++ b/src/ArduinoJson/Text/isInteger.hpp @@ -4,7 +4,7 @@ #pragma once -#include "./ctype.hpp" +#include "../Polyfills/ctype.hpp" namespace ArduinoJson { namespace Internals { @@ -15,5 +15,5 @@ inline bool isInteger(const char* s) { while (isdigit(*s)) s++; return *s == '\0'; } -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/parseFloat.hpp b/src/ArduinoJson/Text/parseFloat.hpp similarity index 94% rename from src/ArduinoJson/Polyfills/parseFloat.hpp rename to src/ArduinoJson/Text/parseFloat.hpp index 49b0f6fcd..763ab3d83 100644 --- a/src/ArduinoJson/Polyfills/parseFloat.hpp +++ b/src/ArduinoJson/Text/parseFloat.hpp @@ -4,9 +4,9 @@ #pragma once +#include "../Polyfills/ctype.hpp" +#include "../Polyfills/math.hpp" #include "../TypeTraits/FloatTraits.hpp" -#include "./ctype.hpp" -#include "./math.hpp" namespace ArduinoJson { namespace Internals { @@ -86,5 +86,5 @@ inline T parseFloat(const char* s) { return negative_result ? -result : result; } -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/parseInteger.hpp b/src/ArduinoJson/Text/parseInteger.hpp similarity index 87% rename from src/ArduinoJson/Polyfills/parseInteger.hpp rename to src/ArduinoJson/Text/parseInteger.hpp index e8f197494..11f2257b3 100644 --- a/src/ArduinoJson/Polyfills/parseInteger.hpp +++ b/src/ArduinoJson/Text/parseInteger.hpp @@ -7,7 +7,7 @@ #include #include "../Configuration.hpp" -#include "./ctype.hpp" +#include "../Polyfills/ctype.hpp" namespace ArduinoJson { namespace Internals { @@ -37,5 +37,5 @@ T parseInteger(const char *s) { return negative_result ? T(~result + 1) : result; } -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index b6e4659f7..d0932a996 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -4,7 +4,7 @@ #pragma once -#include "Deserialization/JsonParser.hpp" +#include "Json/Deserialization/JsonParser.hpp" namespace ArduinoJson { // JsonError deserializeJson(TDestination& destination, TString json); diff --git a/src/ArduinoJson/deserializeMsgPack.hpp b/src/ArduinoJson/deserializeMsgPack.hpp new file mode 100644 index 000000000..d55a7e778 --- /dev/null +++ b/src/ArduinoJson/deserializeMsgPack.hpp @@ -0,0 +1,49 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "MsgPack/MsgPackDeserializer.hpp" + +namespace ArduinoJson { +// MsgPackError deserializeMsgPack(TDestination& destination, TString json); +// TDestination = JsonArray, JsonObject, JsonVariant +// TString = const std::string&, const String& +template +typename Internals::EnableIf::value, + MsgPackError>::type +deserializeMsgPack(TDestination &destination, const TString &json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + destination.clear(); + return Internals::makeMsgPackDeserializer(&destination.buffer(), json, + nestingLimit) + .parse(destination); +} +// +// MsgPackError deserializeMsgPack(TDestination& destination, TString json); +// TDestination = JsonArray, JsonObject, JsonVariant +// TString = const char*, const char[N], const FlashStringHelper* +template +MsgPackError deserializeMsgPack( + TDestination &destination, TString *json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + destination.clear(); + return Internals::makeMsgPackDeserializer(&destination.buffer(), json, + nestingLimit) + .parse(destination); +} +// +// MsgPackError deserializeMsgPack(TDestination& destination, TString json); +// TDestination = JsonArray, JsonObject, JsonVariant +// TString = std::istream&, Stream& +template +MsgPackError deserializeMsgPack( + TDestination &destination, TString &json, + uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { + destination.clear(); + return Internals::makeMsgPackDeserializer(&destination.buffer(), json, + nestingLimit) + .parse(destination); +} +} // namespace ArduinoJson diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 578937a9d..b33dfbb45 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -73,5 +73,6 @@ add_subdirectory(JsonSerializer) add_subdirectory(JsonVariant) add_subdirectory(JsonWriter) add_subdirectory(Misc) +add_subdirectory(MsgPack) add_subdirectory(Polyfills) add_subdirectory(StaticJsonBuffer) diff --git a/test/JsonWriter/writeFloat.cpp b/test/JsonWriter/writeFloat.cpp index 532de5dc6..aa06552b1 100644 --- a/test/JsonWriter/writeFloat.cpp +++ b/test/JsonWriter/writeFloat.cpp @@ -6,8 +6,8 @@ #include #include -#include -#include +#include +#include using namespace ArduinoJson::Internals; diff --git a/test/JsonWriter/writeString.cpp b/test/JsonWriter/writeString.cpp index e583fbcf5..eded06e32 100644 --- a/test/JsonWriter/writeString.cpp +++ b/test/JsonWriter/writeString.cpp @@ -4,8 +4,8 @@ #include -#include -#include +#include +#include using namespace ArduinoJson::Internals; diff --git a/test/Misc/FloatParts.cpp b/test/Misc/FloatParts.cpp index aeed52e75..d9cf18a1f 100644 --- a/test/Misc/FloatParts.cpp +++ b/test/Misc/FloatParts.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/MsgPack/CMakeLists.txt b/test/MsgPack/CMakeLists.txt new file mode 100644 index 000000000..b816549e8 --- /dev/null +++ b/test/MsgPack/CMakeLists.txt @@ -0,0 +1,16 @@ +# ArduinoJson - arduinojson.org +# Copyright Benoit Blanchon 2014-2018 +# MIT License + +add_executable(MsgPackTests + deserializationErrors.cpp + deserializeArray.cpp + deserializeObject.cpp + deserializeVariant.cpp + deserializeStaticVariant.cpp + doubleToFloat.cpp + MsgPackError.cpp +) + +target_link_libraries(MsgPackTests catch) +add_test(MsgPack MsgPackTests) diff --git a/test/MsgPack/MsgPackError.cpp b/test/MsgPack/MsgPackError.cpp new file mode 100644 index 000000000..8de7c79a6 --- /dev/null +++ b/test/MsgPack/MsgPackError.cpp @@ -0,0 +1,40 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +void testStringification(MsgPackError error, std::string expected) { + REQUIRE(error.c_str() == expected); +} + +void testBoolification(MsgPackError error, bool expected) { + CHECK(error == expected); +} + +#define TEST_STRINGIFICATION(symbol) \ + testStringification(MsgPackError::symbol, #symbol) + +#define TEST_BOOLIFICATION(symbol, expected) \ + testBoolification(MsgPackError::symbol, expected) + +TEST_CASE("MsgPackError") { + SECTION("c_str()") { + TEST_STRINGIFICATION(Ok); + TEST_STRINGIFICATION(NotSupported); + TEST_STRINGIFICATION(NoMemory); + TEST_STRINGIFICATION(NotAnArray); + TEST_STRINGIFICATION(NotAnObject); + TEST_STRINGIFICATION(TooDeep); + } + + SECTION("as boolean") { + TEST_BOOLIFICATION(Ok, false); + TEST_BOOLIFICATION(NotSupported, true); + TEST_BOOLIFICATION(NoMemory, true); + TEST_BOOLIFICATION(NotAnArray, true); + TEST_BOOLIFICATION(NotAnObject, true); + TEST_BOOLIFICATION(TooDeep, true); + } +} diff --git a/test/MsgPack/deserializationErrors.cpp b/test/MsgPack/deserializationErrors.cpp new file mode 100644 index 000000000..8483674b1 --- /dev/null +++ b/test/MsgPack/deserializationErrors.cpp @@ -0,0 +1,58 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +static void check(const char* input, MsgPackError expected, + uint8_t nestingLimit = 10) { + DynamicJsonVariant variant; + + MsgPackError error = deserializeMsgPack(variant, input, nestingLimit); + + REQUIRE(error == expected); +} + +TEST_CASE("Errors returned by deserializeMsgPack()") { + SECTION("unsupported") { + check("\xc4", MsgPackError::NotSupported); // bin 8 + check("\xc5", MsgPackError::NotSupported); // bin 16 + check("\xc6", MsgPackError::NotSupported); // bin 32 + check("\xc7", MsgPackError::NotSupported); // ext 8 + check("\xc8", MsgPackError::NotSupported); // ext 16 + check("\xc9", MsgPackError::NotSupported); // ext 32 + check("\xd4", MsgPackError::NotSupported); // fixext 1 + check("\xd5", MsgPackError::NotSupported); // fixext 2 + check("\xd6", MsgPackError::NotSupported); // fixext 4 + check("\xd7", MsgPackError::NotSupported); // fixext 8 + check("\xd8", MsgPackError::NotSupported); // fixext 16 + } + + SECTION("unsupported in array") { + check("\x91\xc4", MsgPackError::NotSupported); + } + + SECTION("unsupported in map") { + check("\x81\xc4\x00\xA1H", MsgPackError::NotSupported); + check("\x81\xA1H\xc4\x00", MsgPackError::NotSupported); + } + + SECTION("integer as key") { + check("\x81\x01\xA1H", MsgPackError::NotSupported); + } + + SECTION("object too deep") { + check("\x80", MsgPackError::TooDeep, 0); // {} + check("\x80", MsgPackError::Ok, 1); // {} + check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}} + check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}} + } + + SECTION("array too deep") { + check("\x90", MsgPackError::TooDeep, 0); // [] + check("\x90", MsgPackError::Ok, 1); // [] + check("\x91\x90", MsgPackError::TooDeep, 1); // [[]] + check("\x91\x90", MsgPackError::Ok, 2); // [[]] + } +} diff --git a/test/MsgPack/deserializeArray.cpp b/test/MsgPack/deserializeArray.cpp new file mode 100644 index 000000000..a0c492d64 --- /dev/null +++ b/test/MsgPack/deserializeArray.cpp @@ -0,0 +1,85 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeMsgPack(JsonArray&)") { + DynamicJsonArray array; + + SECTION("not an array") { + const char* input = "\xA0"; + + MsgPackError error = deserializeMsgPack(array, input); + + REQUIRE(error == MsgPackError::NotAnArray); + } + + SECTION("fixarray") { + SECTION("empty") { + const char* input = "\x90"; + + MsgPackError error = deserializeMsgPack(array, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(array.size() == 0); + } + + SECTION("two integers") { + const char* input = "\x92\x01\x02"; + + MsgPackError error = deserializeMsgPack(array, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(array.size() == 2); + REQUIRE(array[0] == 1); + REQUIRE(array[1] == 2); + } + } + + SECTION("array 16") { + SECTION("empty") { + const char* input = "\xDC\x00\x00"; + + MsgPackError error = deserializeMsgPack(array, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(array.size() == 0); + } + + SECTION("two strings") { + const char* input = "\xDC\x00\x02\xA5hello\xA5world"; + + MsgPackError error = deserializeMsgPack(array, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(array.size() == 2); + REQUIRE(array[0] == "hello"); + REQUIRE(array[1] == "world"); + } + } + + SECTION("array 32") { + SECTION("empty") { + const char* input = "\xDD\x00\x00\x00\x00"; + + MsgPackError error = deserializeMsgPack(array, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(array.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(array, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(array.size() == 2); + REQUIRE(array[0] == 0.0f); + REQUIRE(array[1] == 3.14f); + } + } +} diff --git a/test/MsgPack/deserializeObject.cpp b/test/MsgPack/deserializeObject.cpp new file mode 100644 index 000000000..508b93bce --- /dev/null +++ b/test/MsgPack/deserializeObject.cpp @@ -0,0 +1,86 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeMsgPack(JsonObject&)") { + DynamicJsonObject object; + + SECTION("not an object") { + const char* input = "\xA0"; + + MsgPackError error = deserializeMsgPack(object, input); + + REQUIRE(error == MsgPackError::NotAnObject); + } + + SECTION("fixmap") { + SECTION("empty") { + const char* input = "\x80"; + + MsgPackError error = deserializeMsgPack(object, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(object.size() == 0); + } + + SECTION("two integers") { + const char* input = "\x82\xA3one\x01\xA3two\x02"; + + MsgPackError error = deserializeMsgPack(object, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(object.size() == 2); + REQUIRE(object["one"] == 1); + REQUIRE(object["two"] == 2); + } + } + + SECTION("map 16") { + SECTION("empty") { + const char* input = "\xDE\x00\x00"; + + MsgPackError error = deserializeMsgPack(object, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(object.size() == 0); + } + + SECTION("two strings") { + const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; + + MsgPackError error = deserializeMsgPack(object, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(object.size() == 2); + REQUIRE(object["H"] == "hello"); + REQUIRE(object["W"] == "world"); + } + } + + SECTION("map 32") { + SECTION("empty") { + const char* input = "\xDF\x00\x00\x00\x00"; + + MsgPackError error = deserializeMsgPack(object, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(object.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(object, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(object.size() == 2); + REQUIRE(object["zero"] == 0.0f); + REQUIRE(object["pi"] == 3.14f); + } + } +} diff --git a/test/MsgPack/deserializeStaticVariant.cpp b/test/MsgPack/deserializeStaticVariant.cpp new file mode 100644 index 000000000..01ceb21d9 --- /dev/null +++ b/test/MsgPack/deserializeStaticVariant.cpp @@ -0,0 +1,131 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +static const size_t epsilon = sizeof(void*); + +template +static void check(const char* input, MsgPackError expected) { + StaticJsonVariant variant; + + MsgPackError error = deserializeMsgPack(variant, input); + + REQUIRE(error == expected); +} + +TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { + SECTION("single values always fit") { + check<0>("\xc0", MsgPackError::Ok); // nil + check<0>("\xc2", MsgPackError::Ok); // false + check<0>("\xc3", MsgPackError::Ok); // true + check<0>("\xcc\x00", MsgPackError::Ok); // uint 8 + check<0>("\xcd\x30\x39", MsgPackError::Ok); // uint 16 + check<0>("\xCE\x12\x34\x56\x78", MsgPackError::Ok); // uint 32 + } + + SECTION("fixstr") { + check<0>("\xA0", MsgPackError::Ok); + check<0>("\xA1H", MsgPackError::NoMemory); + check<4>("\xA1H", MsgPackError::Ok); + check<4>("\xA5Hello", MsgPackError::NoMemory); + } + + SECTION("str 8") { + check<0>("\xD9\x00", MsgPackError::Ok); + check<0>("\xD9\x01H", MsgPackError::NoMemory); + check<4>("\xD9\x01H", MsgPackError::Ok); + check<4>("\xD9\x05Hello", MsgPackError::NoMemory); + } + + SECTION("str 16") { + check<0>("\xDA\x00\x00", MsgPackError::Ok); + check<0>("\xDA\x00\x01H", MsgPackError::NoMemory); + check<4>("\xDA\x00\x01H", MsgPackError::Ok); + check<4>("\xDA\x00\x05Hello", MsgPackError::NoMemory); + } + + SECTION("str 32") { + check<0>("\xDB\x00\x00\x00\x00", MsgPackError::Ok); + check<0>("\xDB\x00\x00\x00\x01H", MsgPackError::NoMemory); + check<4>("\xDB\x00\x00\x00\x01H", MsgPackError::Ok); + check<4>("\xDB\x00\x00\x00\x05Hello", MsgPackError::NoMemory); + } + + SECTION("fixarray") { + check("\x90", MsgPackError::Ok); // [] + check("\x91\x01", MsgPackError::NoMemory); // [1] + check("\x91\x01", MsgPackError::Ok); // [1] + check("\x92\x01\x02", MsgPackError::NoMemory); // [1,2] + } + + SECTION("array 16") { + check("\xDC\x00\x00", MsgPackError::Ok); + check("\xDC\x00\x01\x01", MsgPackError::NoMemory); + check("\xDC\x00\x01\x01", MsgPackError::Ok); + check("\xDC\x00\x02\x01\x02", MsgPackError::NoMemory); + } + + SECTION("array 32") { + check("\xDD\x00\x00\x00\x00", MsgPackError::Ok); + check("\xDD\x00\x00\x00\x01\x01", + MsgPackError::NoMemory); + check("\xDD\x00\x00\x00\x01\x01", MsgPackError::Ok); + check("\xDD\x00\x00\x00\x02\x01\x02", + MsgPackError::NoMemory); + } + + SECTION("fixmap") { + SECTION("{}") { + check("\x80", MsgPackError::Ok); + } + SECTION("{H:1}") { + check("\x81\xA1H\x01", + MsgPackError::NoMemory); + check("\x81\xA1H\x01", MsgPackError::Ok); + } + SECTION("{H:1,W:2}") { + check("\x82\xA1H\x01\xA1W\x02", + MsgPackError::NoMemory); + check("\x82\xA1H\x01\xA1W\x02", + MsgPackError::Ok); + } + } + + SECTION("map 16") { + SECTION("{}") { + check("\xDE\x00\x00", MsgPackError::Ok); + } + SECTION("{H:1}") { + check("\xDE\x00\x01\xA1H\x01", + MsgPackError::NoMemory); + check("\xDE\x00\x01\xA1H\x01", MsgPackError::Ok); + } + SECTION("{H:1,W:2}") { + check("\xDE\x00\x02\xA1H\x01\xA1W\x02", + MsgPackError::NoMemory); + check("\xDE\x00\x02\xA1H\x01\xA1W\x02", + MsgPackError::Ok); + } + } + + SECTION("map 32") { + SECTION("{}") { + check("\xDF\x00\x00\x00\x00", MsgPackError::Ok); + } + SECTION("{H:1}") { + check("\xDF\x00\x00\x00\x01\xA1H\x01", + MsgPackError::NoMemory); + check("\xDF\x00\x00\x00\x01\xA1H\x01", + MsgPackError::Ok); + } + SECTION("{H:1,W:2}") { + check("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", + MsgPackError::NoMemory); + check("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", + MsgPackError::Ok); + } + } +} diff --git a/test/MsgPack/deserializeVariant.cpp b/test/MsgPack/deserializeVariant.cpp new file mode 100644 index 000000000..f25ed8979 --- /dev/null +++ b/test/MsgPack/deserializeVariant.cpp @@ -0,0 +1,277 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +template +static void check(const char* input, U expected) { + DynamicJsonVariant variant; + + MsgPackError error = deserializeMsgPack(variant, input); + + REQUIRE(error == MsgPackError::Ok); + REQUIRE(variant.is()); + REQUIRE(variant.as() == expected); +} + +TEST_CASE("deserializeMsgPack(JsonVariant&)") { + SECTION("nil") { + const char* nil = 0; // ArduinoJson uses a string for null + check("\xc0", nil); + } + + SECTION("bool") { + check("\xc2", false); + check("\xc3", true); + } + + SECTION("positive fixint") { + check("\x00", 0); + check("\x7F", 127); + } + + SECTION("negative fixint") { + check("\xe0", -32); + check("\xff", -1); + } + + SECTION("uint 8") { + check("\xcc\x00", 0); + check("\xcc\xff", 255); + } + + SECTION("uint 16") { + check("\xcd\x00\x00", 0); + check("\xcd\xFF\xFF", 65535); + check("\xcd\x30\x39", 12345); + } + + SECTION("uint 32") { + check("\xCE\x00\x00\x00\x00", 0x00000000U); + check("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU); + check("\xCE\x12\x34\x56\x78", 0x12345678U); + } + + SECTION("uint 64") { +#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 + check("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); + check("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + 0xFFFFFFFFFFFFFFFFU); + check("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", + 0x123456789ABCDEF0U); +#else + check("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U); + check("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0xFFFFFFFF); + check("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", 0x9ABCDEF0); +#endif + } + + SECTION("int 8") { + check("\xd0\x00", 0); + check("\xd0\xff", -1); + } + + SECTION("int 16") { + check("\xD1\x00\x00", 0); + check("\xD1\xFF\xFF", -1); + check("\xD1\xCF\xC7", -12345); + } + + SECTION("int 32") { + check("\xD2\x00\x00\x00\x00", 0); + check("\xD2\xFF\xFF\xFF\xFF", -1); + check("\xD2\xB6\x69\xFD\x2E", -1234567890); + } + + SECTION("int 64") { +#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 + check("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", 0U); + check("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + 0xFFFFFFFFFFFFFFFFU); + check("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", + 0x123456789ABCDEF0U); +#else + check("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", 0U); + check("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0xFFFFFFFF); + check("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", 0x9ABCDEF0); +#endif + } + + SECTION("float 32") { + check("\xCA\x00\x00\x00\x00", 0.0f); + check("\xCA\x40\x48\xF5\xC3", 3.14f); + } + + SECTION("float 64") { + check("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0); + check("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415); + } + + SECTION("fixstr") { + check("\xA0", std::string("")); + check("\xABhello world", std::string("hello world")); + check("\xBFhello world hello world hello !", + std::string("hello world hello world hello !")); + } + + SECTION("str 8") { + check("\xd9\x05hello", std::string("hello")); + } + + SECTION("str 16") { + check("\xda\x00\x05hello", std::string("hello")); + } + + SECTION("str 32") { + check("\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); + } + } +} diff --git a/test/MsgPack/doubleToFloat.cpp b/test/MsgPack/doubleToFloat.cpp new file mode 100644 index 000000000..da37bd56e --- /dev/null +++ b/test/MsgPack/doubleToFloat.cpp @@ -0,0 +1,25 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +using namespace ArduinoJson::Internals; + +template +static void check(const char* input, T expected) { + T actual; + uint8_t* f = reinterpret_cast(&actual); + const uint8_t* d = reinterpret_cast(input); + doubleToFloat(d, f); + fixEndianess(actual); + CHECK(actual == expected); +} + +TEST_CASE("Internals::doubleToFloat()") { + check("\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415f); + check("\x00\x00\x00\x00\x00\x00\x00\x00", 0.0f); + check("\x80\x00\x00\x00\x00\x00\x00\x00", -0.0f); + check("\xC0\x5E\xDC\xCC\xCC\xCC\xCC\xCD", -123.45f); +} diff --git a/test/Polyfills/isFloat.cpp b/test/Polyfills/isFloat.cpp index 225d52214..f4fbe16b8 100644 --- a/test/Polyfills/isFloat.cpp +++ b/test/Polyfills/isFloat.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Polyfills/isInteger.cpp b/test/Polyfills/isInteger.cpp index f0bec4ae2..8cc74dd11 100644 --- a/test/Polyfills/isInteger.cpp +++ b/test/Polyfills/isInteger.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Polyfills/parseFloat.cpp b/test/Polyfills/parseFloat.cpp index 362e46d6f..bd481ea27 100644 --- a/test/Polyfills/parseFloat.cpp +++ b/test/Polyfills/parseFloat.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Polyfills/parseInteger.cpp b/test/Polyfills/parseInteger.cpp index 3d25bdb25..afac3bf51 100644 --- a/test/Polyfills/parseInteger.cpp +++ b/test/Polyfills/parseInteger.cpp @@ -3,7 +3,7 @@ // MIT License #include -#include +#include #include using namespace ArduinoJson::Internals; From a13b9e8bdc4743d171a6df54005d20f82824a6f9 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Tue, 10 Apr 2018 17:55:51 +0200 Subject: [PATCH 0025/1079] Added example `MsgPackParser.ino` (issue #358) --- CHANGELOG.md | 1 + .../JsonParserExample/JsonParserExample.ino | 2 +- examples/MsgPackParser/MsgPackParser.ino | 87 +++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 examples/MsgPackParser/MsgPackParser.ino diff --git a/CHANGELOG.md b/CHANGELOG.md index 0783de862..e4de80750 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ HEAD * Added `serializeJson()` and `serializeJsonPretty()` * Added `measureJson()` and `measureJsonPretty()` * Added `deserializeMsgPack()` (issue #358) +* Added example `MsgPackParser.ino` (issue #358) * Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` * Removed `JsonBuffer::createArray()` and `createObject()` * Removed `printTo()` and `prettyPrintTo()` diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 1f9cb3068..72bc6e85c 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -40,7 +40,7 @@ void setup() { // Test if parsing succeeds. if (error) { - Serial.println("parseObject() failed"); + Serial.println("deserializeJson() failed"); return; } diff --git a/examples/MsgPackParser/MsgPackParser.ino b/examples/MsgPackParser/MsgPackParser.ino new file mode 100644 index 000000000..deb2d546d --- /dev/null +++ b/examples/MsgPackParser/MsgPackParser.ino @@ -0,0 +1,87 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License +// +// This example shows how to deserialize a MessagePack document with +// ArduinoJson. + +#include + +void setup() { + // Initialize serial port + Serial.begin(9600); + while (!Serial) continue; + + // Root JSON object + // + // Inside the brackets, 200 is the size of the memory pool in bytes. + // Don't forget to change this value to match your JSON document. + // Use arduinojson.org/assistant to compute the capacity. + StaticJsonObject<200> root; + + // StaticJsonObject allocates memory on the stack, it can be + // replaced by DynamicJsonObject which allocates in the heap. + // + // DynamicJsonObject root(200); + + // MessagePack input string. + // + // It's better to use a char[] as shown here. + // If you use a const char* or a String, ArduinoJson will + // have to make a copy of the input in the JsonBuffer. + uint8_t input[] = {131, 166, 115, 101, 110, 115, 111, 114, 163, 103, 112, 115, + 164, 116, 105, 109, 101, 206, 80, 147, 50, 248, 164, 100, + 97, 116, 97, 146, 203, 64, 72, 96, 199, 58, 188, 148, + 112, 203, 64, 2, 106, 146, 230, 33, 49, 169}; + // This MessagePack document contains: + // { + // "sensor": "gps", + // "time": 1351824120, + // "data": [48.75608, 2.302038] + // } + + // Root of the object tree. + // + // It's a reference to the JsonObject, the actual bytes are inside the + // JsonBuffer with all the other nodes of the object tree. + // Memory is freed when jsonBuffer goes out of scope. + MsgPackError error = deserializeMsgPack(root, input); + + // Test if parsing succeeds. + if (error) { + Serial.println("deserializeMsgPack() failed"); + return; + } + + // Fetch values. + // + // Most of the time, you can rely on the implicit casts. + // In other case, you can do root["time"].as(); + const char* sensor = root["sensor"]; + long time = root["time"]; + double latitude = root["data"][0]; + double longitude = root["data"][1]; + + // Print values. + Serial.println(sensor); + Serial.println(time); + Serial.println(latitude, 6); + Serial.println(longitude, 6); +} + +void loop() { + // not used in this example +} + +// See also +// -------- +// +// The website arduinojson.org contains the documentation for all the functions +// used above. It also includes an FAQ that will help you solve any +// deserialization problem. +// Please check it out at: https://arduinojson.org/ +// +// The book "Mastering ArduinoJson" contains a tutorial on deserialization. +// It begins with a simple example, like the one above, and then adds more +// features like deserializing directly from a file or an HTTP request. +// Please check it out at: https://arduinojson.org/book/ From 1feb92679da887955e3a6b2994c6c25cdaf6039e Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Tue, 17 Apr 2018 21:27:45 +0200 Subject: [PATCH 0026/1079] Added StaticJsonDocument and DynamicJsonDocument. Removed StaticJsonArray and DynamicJsonArray. Removed StaticJsonObject and DynamicJsonObject. Removed StaticJsonVariant and DynamicJsonVariant. --- CHANGELOG.md | 14 +- README.md | 11 +- examples/JsonConfigFile/JsonConfigFile.ino | 29 ++- .../JsonGeneratorExample.ino | 19 +- examples/JsonHttpClient/JsonHttpClient.ino | 10 +- .../JsonParserExample/JsonParserExample.ino | 22 +- examples/JsonServer/JsonServer.ino | 7 +- examples/JsonUdpBeacon/JsonUdpBeacon.ino | 7 +- examples/MsgPackParser/MsgPackParser.ino | 18 +- examples/ProgmemExample/ProgmemExample.ino | 17 +- examples/StringExample/StringExample.ino | 25 +- fuzzing/fuzzer.cpp | 8 +- keywords.txt | 10 +- src/ArduinoJson.hpp | 12 +- src/ArduinoJson/DynamicJsonArray.hpp | 32 --- src/ArduinoJson/DynamicJsonDocument.hpp | 83 +++++++ src/ArduinoJson/DynamicJsonObject.hpp | 32 --- src/ArduinoJson/DynamicJsonVariant.hpp | 45 ---- .../Json/Deserialization/JsonDeserializer.hpp | 218 ++++++++++++++++++ .../Json/Deserialization/JsonParser.hpp | 95 -------- .../Json/Deserialization/JsonParserImpl.hpp | 166 ------------- .../Json/Serialization/JsonSerializer.hpp | 53 +++-- .../Json/Serialization/JsonSerializerImpl.hpp | 69 ------ src/ArduinoJson/JsonArray.hpp | 5 + src/ArduinoJson/JsonArraySubscript.hpp | 5 + src/ArduinoJson/JsonError.hpp | 28 +-- src/ArduinoJson/JsonObject.hpp | 5 + src/ArduinoJson/JsonObjectSubscript.hpp | 5 + src/ArduinoJson/Memory/DynamicJsonBuffer.hpp | 12 +- src/ArduinoJson/Memory/StaticJsonBuffer.hpp | 2 +- .../MsgPack/MsgPackDeserializer.hpp | 34 --- src/ArduinoJson/MsgPack/MsgPackError.hpp | 11 +- src/ArduinoJson/StaticJsonArray.hpp | 32 --- src/ArduinoJson/StaticJsonDocument.hpp | 80 +++++++ src/ArduinoJson/StaticJsonObject.hpp | 32 --- src/ArduinoJson/StaticJsonVariant.hpp | 43 ---- src/ArduinoJson/TypeTraits/Max.hpp | 2 + src/ArduinoJson/deserializeJson.hpp | 41 ++-- src/ArduinoJson/deserializeMsgPack.hpp | 42 ++-- test/CMakeLists.txt | 2 +- test/DynamicJsonBuffer/alloc.cpp | 3 +- test/DynamicJsonBuffer/no_memory.cpp | 14 +- test/DynamicJsonBuffer/size.cpp | 4 +- test/DynamicJsonBuffer/startString.cpp | 4 +- test/IntegrationTests/CMakeLists.txt | 2 +- test/IntegrationTests/gbathree.cpp | 49 ++-- test/IntegrationTests/round_trip.cpp | 10 +- test/JsonArray/add.cpp | 25 +- test/JsonArray/basics.cpp | 3 +- test/JsonArray/copyFrom.cpp | 12 +- test/JsonArray/copyTo.cpp | 11 +- test/JsonArray/iterator.cpp | 3 +- test/JsonArray/remove.cpp | 3 +- test/JsonArray/set.cpp | 21 +- test/JsonArray/size.cpp | 3 +- test/JsonArray/subscript.cpp | 21 +- test/JsonDeserializer/CMakeLists.txt | 16 ++ .../JsonError.cpp | 18 +- .../deserializeJsonArray.cpp} | 161 +++++++------ .../deserializeJsonArrayStatic.cpp | 105 +++++++++ .../deserializeJsonObject.cpp} | 134 ++++++++--- .../deserializeJsonObjectStatic.cpp} | 40 ++-- .../JsonDeserializer/deserializeJsonValue.cpp | 103 +++++++++ test/JsonDeserializer/nestingLimit.cpp | 32 +++ test/JsonObject/basics.cpp | 9 +- test/JsonObject/containsKey.cpp | 17 +- test/JsonObject/get.cpp | 3 +- test/JsonObject/iterator.cpp | 3 +- test/JsonObject/remove.cpp | 7 +- test/JsonObject/set.cpp | 111 ++++----- test/JsonObject/size.cpp | 17 +- test/JsonObject/subscript.cpp | 140 +++++------ test/JsonParser/CMakeLists.txt | 17 -- test/JsonParser/DynamicJsonVariant.cpp | 98 -------- test/JsonParser/StaticJsonArray.cpp | 90 -------- test/JsonParser/StaticJsonVariant.cpp | 35 --- test/JsonParser/nestingLimit.cpp | 70 ------ test/JsonSerializer/JsonArray.cpp | 3 +- test/JsonSerializer/JsonArrayPretty.cpp | 3 +- test/JsonSerializer/JsonObject.cpp | 18 +- test/JsonSerializer/JsonObjectPretty.cpp | 3 +- test/JsonVariant/as.cpp | 12 +- test/JsonVariant/compare.cpp | 26 ++- test/JsonVariant/copy.cpp | 8 +- test/JsonVariant/is.cpp | 5 +- test/JsonVariant/set_get.cpp | 3 +- test/JsonVariant/subscript.cpp | 20 +- test/JsonVariant/success.cpp | 6 +- test/Misc/std_stream.cpp | 26 ++- test/Misc/std_string.cpp | 147 +++++++----- test/Misc/unsigned_char.cpp | 85 ++++--- test/Misc/vla.cpp | 87 ++++--- test/MsgPack/MsgPackError.cpp | 10 +- test/MsgPack/deserializationErrors.cpp | 2 +- test/MsgPack/deserializeArray.cpp | 28 ++- test/MsgPack/deserializeObject.cpp | 60 ++--- test/MsgPack/deserializeStaticVariant.cpp | 32 +-- test/MsgPack/deserializeVariant.cpp | 149 +----------- test/StaticJsonBuffer/alloc.cpp | 4 +- test/StaticJsonBuffer/size.cpp | 4 +- 100 files changed, 1695 insertions(+), 1843 deletions(-) delete mode 100644 src/ArduinoJson/DynamicJsonArray.hpp create mode 100644 src/ArduinoJson/DynamicJsonDocument.hpp delete mode 100644 src/ArduinoJson/DynamicJsonObject.hpp delete mode 100644 src/ArduinoJson/DynamicJsonVariant.hpp create mode 100644 src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp delete mode 100644 src/ArduinoJson/Json/Deserialization/JsonParser.hpp delete mode 100644 src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp delete mode 100644 src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp delete mode 100644 src/ArduinoJson/StaticJsonArray.hpp create mode 100644 src/ArduinoJson/StaticJsonDocument.hpp delete mode 100644 src/ArduinoJson/StaticJsonObject.hpp delete mode 100644 src/ArduinoJson/StaticJsonVariant.hpp create mode 100644 test/JsonDeserializer/CMakeLists.txt rename test/{JsonParser => JsonDeserializer}/JsonError.cpp (62%) rename test/{JsonParser/DynamicJsonArray.cpp => JsonDeserializer/deserializeJsonArray.cpp} (56%) create mode 100644 test/JsonDeserializer/deserializeJsonArrayStatic.cpp rename test/{JsonParser/DynamicJsonObject.cpp => JsonDeserializer/deserializeJsonObject.cpp} (52%) rename test/{JsonParser/StaticJsonObject.cpp => JsonDeserializer/deserializeJsonObjectStatic.cpp} (50%) create mode 100644 test/JsonDeserializer/deserializeJsonValue.cpp create mode 100644 test/JsonDeserializer/nestingLimit.cpp delete mode 100644 test/JsonParser/CMakeLists.txt delete mode 100644 test/JsonParser/DynamicJsonVariant.cpp delete mode 100644 test/JsonParser/StaticJsonArray.cpp delete mode 100644 test/JsonParser/StaticJsonVariant.cpp delete mode 100644 test/JsonParser/nestingLimit.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index e4de80750..e03c7e079 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,7 @@ HEAD * Fixed `JsonBuffer::parse()` not respecting nesting limit correctly (issue #693) * Fixed inconsistencies in nesting level counting (PR #695 from Zhenyu Wu) -* Added `DynamicJsonArray` and `StaticJsonArray` -* Added `DynamicJsonObject` and `StaticJsonObject` -* Added `DynamicJsonVariant` and `StaticJsonVariant` +* Added `DynamicJsonDocument` and `StaticJsonDocument` * Added `deserializeJson()` * Added `serializeJson()` and `serializeJsonPretty()` * Added `measureJson()` and `measureJsonPretty()` @@ -37,11 +35,12 @@ HEAD > New code: > > ```c++ -> DynamicJsonObject obj; -> JsonError error = deserializeJson(obj, json); +> DynamicJsonDocument doc; +> JsonError error = deserializeJson(doc, json); > if (error) { > > } +> JsonObject& obj = doc.as(); > ``` > > #### Serialization @@ -58,9 +57,10 @@ HEAD > New code: > > ```c++ -> DynamicJsonObject obj; +> DynamicJsonDocument obj; +> JsonObject& obj = doc.to(); > obj["key"] = "value"; -> serializeJson(obj, Serial); +> serializeJson(doc, Serial); > ``` v5.13.1 diff --git a/README.md b/README.md index 31fc6266e..9434e775a 100644 --- a/README.md +++ b/README.md @@ -59,9 +59,10 @@ Here is a program that parses a JSON document with ArduinoJson. ```c++ char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; -DynamicJsonObject root; -deserializeJson(root, json); +DynamicJsonDocument doc; +deserializeJson(doc, json); +JsonObject& root = doc.as(); const char* sensor = root["sensor"]; long time = root["time"]; double latitude = root["data"][0]; @@ -75,7 +76,9 @@ See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_ Here is a program that generates a JSON document with ArduinoJson: ```c++ -DynamicJsonObject root; +DynamicJsonDocument doc; + +JsonObject& root = doc.to(); root["sensor"] = "gps"; root["time"] = 1351824120; @@ -83,7 +86,7 @@ JsonArray& data = root.createNestedArray("data"); data.add(48.756080); data.add(2.302038); -serializeJson(root, Serial); +serializeJson(doc, Serial); // This prints: // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} ``` diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index ebf03738b..6134f5873 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -29,17 +29,19 @@ void loadConfiguration(const char *filename, Config &config) { // Open file for reading File file = SD.open(filename); - // Allocate the memory pool on the stack. - // Don't forget to change the capacity to match your JSON document. + // Allocate the document on the stack. + // Don't forget to change the capacity to match your requirements. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<512> root; - - // Parse the root object - JsonError error = deserializeJson(root, file); + StaticJsonDocument<512> doc; + // Deserialize the JSON document + JsonError error = deserializeJson(doc, file); if (error) Serial.println(F("Failed to read file, using default configuration")); + // Get the root object in the document + JsonObject &root = doc.as(); + // Copy values from the JsonObject to the Config config.port = root["port"] | 2731; strlcpy(config.hostname, // <- destination @@ -62,17 +64,20 @@ void saveConfiguration(const char *filename, const Config &config) { return; } - // Allocate the memory pool on the stack - // Don't forget to change the capacity to match your JSON document. - // Use https://arduinojson.org/assistant/ to compute the capacity. - StaticJsonObject<256> root; + // Allocate the document on the stack. + // Don't forget to change the capacity to match your requirements. + // Use arduinojson.org/assistant to compute the capacity. + StaticJsonDocument<256> doc; + + // Make our document contain an object + JsonObject &root = doc.to(); - // Set the values + // Set the values in the object root["hostname"] = config.hostname; root["port"] = config.port; // Serialize JSON to file - if (serializeJson(root, file) == 0) { + if (serializeJson(doc, file) == 0) { Serial.println(F("Failed to write to file")); } diff --git a/examples/JsonGeneratorExample/JsonGeneratorExample.ino b/examples/JsonGeneratorExample/JsonGeneratorExample.ino index ee22fe716..b74e2c0d2 100644 --- a/examples/JsonGeneratorExample/JsonGeneratorExample.ino +++ b/examples/JsonGeneratorExample/JsonGeneratorExample.ino @@ -11,17 +11,20 @@ void setup() { Serial.begin(9600); while (!Serial) continue; - // Root JSON object + // The JSON document // - // Inside the brackets, 200 is the size of the memory pool in bytes. - // Don't forget to change this value to match your JSON document. + // Inside the brackets, 200 is the RAM allocated to this document. + // Don't forget to change this value to match your requirement. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<200> root; + StaticJsonDocument<200> doc; // StaticJsonObject allocates memory on the stack, it can be - // replaced by DynamicJsonObject which allocates in the heap. + // replaced by DynamicJsonDocument which allocates in the heap. // - // DynamicJsonObject root(200); + // DynamicJsonDocument doc(200); + + // Make our document be an object + JsonObject& root = doc.to(); // Add values in the object // @@ -30,10 +33,8 @@ void setup() { root["sensor"] = "gps"; root["time"] = 1351824120; - // Add a nested array. + // Add an array. // - // It's also possible to create the array separately and add it to the - // JsonObject but it's less efficient. JsonArray& data = root.createNestedArray("data"); data.add(48.756080); data.add(2.302038); diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index aeae598a2..41b130ef8 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -70,19 +70,21 @@ void setup() { return; } - // Allocate JsonBuffer + // Allocate the JSON document // Use arduinojson.org/assistant to compute the capacity. const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60; - DynamicJsonObject root(capacity); + DynamicJsonDocument doc(capacity); // Parse JSON object - JsonError error = deserializeJson(root, client); + JsonError error = deserializeJson(doc, client); if (error) { - Serial.println(F("Parsing failed!")); + Serial.print(F("deserializeJson() failed: ")); + Serial.println(error.c_str()); return; } // Extract values + JsonObject& root = doc.as(); Serial.println(F("Response:")); Serial.println(root["sensor"].as()); Serial.println(root["time"].as()); diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index 72bc6e85c..d7926cf9f 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -16,12 +16,12 @@ void setup() { // Inside the brackets, 200 is the size of the memory pool in bytes. // Don't forget to change this value to match your JSON document. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<200> root; + StaticJsonDocument<200> doc; - // StaticJsonObject allocates memory on the stack, it can be + // StaticJsonDocument allocates memory on the stack, it can be // replaced by DynamicJsonObject which allocates in the heap. // - // DynamicJsonObject root(200); + // DynamicJsonObject doc(200); // JSON input string. // @@ -31,23 +31,23 @@ void setup() { char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; - // Root of the object tree. - // - // It's a reference to the JsonObject, the actual bytes are inside the - // JsonBuffer with all the other nodes of the object tree. - // Memory is freed when jsonBuffer goes out of scope. - JsonError error = deserializeJson(root, json); + // Deserialize the JSON document + JsonError error = deserializeJson(doc, json); // Test if parsing succeeds. if (error) { - Serial.println("deserializeJson() failed"); + Serial.print(F("deserializeJson() failed: ")); + Serial.println(error.c_str()); return; } + // Get the root object in the document + JsonObject& root = doc.as(); + // Fetch values. // // Most of the time, you can rely on the implicit casts. - // In other case, you can do root["time"].as(); + // In other case, you can do doc["time"].as(); const char* sensor = root["sensor"]; long time = root["time"]; double latitude = root["data"][0]; diff --git a/examples/JsonServer/JsonServer.ino b/examples/JsonServer/JsonServer.ino index 677d5039a..92dcc790a 100644 --- a/examples/JsonServer/JsonServer.ino +++ b/examples/JsonServer/JsonServer.ino @@ -51,9 +51,12 @@ void loop() { // Read the request (we ignore the content in this example) while (client.available()) client.read(); - // Allocate the root JsonObject + // Allocate the JSON document // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<500> root; + StaticJsonDocument<500> doc; + + // Make our document represent an object + JsonObject& root = doc.to(); // Create the "analog" array JsonArray& analogValues = root.createNestedArray("analog"); diff --git a/examples/JsonUdpBeacon/JsonUdpBeacon.ino b/examples/JsonUdpBeacon/JsonUdpBeacon.ino index 82c8b8ffe..1af13d9a7 100644 --- a/examples/JsonUdpBeacon/JsonUdpBeacon.ino +++ b/examples/JsonUdpBeacon/JsonUdpBeacon.ino @@ -43,9 +43,12 @@ void setup() { } void loop() { - // Allocate the root JsonObject + // Allocate the JSON document // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<500> root; + StaticJsonDocument<500> doc; + + // Make our document represent an object + JsonObject& root = doc.to(); // Create the "analog" array JsonArray& analogValues = root.createNestedArray("analog"); diff --git a/examples/MsgPackParser/MsgPackParser.ino b/examples/MsgPackParser/MsgPackParser.ino index deb2d546d..381fffd15 100644 --- a/examples/MsgPackParser/MsgPackParser.ino +++ b/examples/MsgPackParser/MsgPackParser.ino @@ -12,17 +12,17 @@ void setup() { Serial.begin(9600); while (!Serial) continue; - // Root JSON object + // Allocate the JSON document // // Inside the brackets, 200 is the size of the memory pool in bytes. // Don't forget to change this value to match your JSON document. // Use arduinojson.org/assistant to compute the capacity. - StaticJsonObject<200> root; + StaticJsonDocument<200> doc; // StaticJsonObject allocates memory on the stack, it can be // replaced by DynamicJsonObject which allocates in the heap. // - // DynamicJsonObject root(200); + // DynamicJsonObject doc(200); // MessagePack input string. // @@ -40,23 +40,27 @@ void setup() { // "data": [48.75608, 2.302038] // } - // Root of the object tree. + // doc of the object tree. // // It's a reference to the JsonObject, the actual bytes are inside the // JsonBuffer with all the other nodes of the object tree. // Memory is freed when jsonBuffer goes out of scope. - MsgPackError error = deserializeMsgPack(root, input); + MsgPackError error = deserializeMsgPack(doc, input); // Test if parsing succeeds. if (error) { - Serial.println("deserializeMsgPack() failed"); + Serial.print("deserializeMsgPack() failed: "); + Serial.println(error.c_str()); return; } + // Get the root object in the document + JsonObject& root = doc.as(); + // Fetch values. // // Most of the time, you can rely on the implicit casts. - // In other case, you can do root["time"].as(); + // In other case, you can do doc["time"].as(); const char* sensor = root["sensor"]; long time = root["time"]; double latitude = root["data"][0]; diff --git a/examples/ProgmemExample/ProgmemExample.ino b/examples/ProgmemExample/ProgmemExample.ino index 87740bb42..3302fc2d3 100644 --- a/examples/ProgmemExample/ProgmemExample.ino +++ b/examples/ProgmemExample/ProgmemExample.ino @@ -14,33 +14,34 @@ void setup() { #ifdef PROGMEM // <- check that Flash strings are supported - DynamicJsonObject root; + DynamicJsonDocument doc; // You can use a Flash String as your JSON input. // WARNING: the content of the Flash String will be duplicated in the // JsonBuffer. - deserializeJson(root, F("{\"sensor\":\"gps\",\"time\":1351824120," - "\"data\":[48.756080,2.302038]}")); + deserializeJson(doc, F("{\"sensor\":\"gps\",\"time\":1351824120," + "\"data\":[48.756080,2.302038]}")); + JsonObject& obj = doc.as(); // You can use a Flash String to get an element of a JsonObject // No duplication is done. - long time = root[F("time")]; + long time = obj[F("time")]; // You can use a Flash String to set an element of a JsonObject // WARNING: the content of the Flash String will be duplicated in the // JsonBuffer. - root[F("time")] = time; + obj[F("time")] = time; // You can set a Flash String to a JsonObject or JsonArray: // WARNING: the content of the Flash String will be duplicated in the // JsonBuffer. - root["sensor"] = F("gps"); + obj["sensor"] = F("gps"); // It works with RawJson too: - root["sensor"] = RawJson(F("\"gps\"")); + obj["sensor"] = RawJson(F("\"gps\"")); // You can compare the content of a JsonVariant to a Flash String - if (root["sensor"] == F("gps")) { + if (obj["sensor"] == F("gps")) { // ... } diff --git a/examples/StringExample/StringExample.ino b/examples/StringExample/StringExample.ino index a497651ae..d888e6204 100644 --- a/examples/StringExample/StringExample.ino +++ b/examples/StringExample/StringExample.ino @@ -11,50 +11,51 @@ #include void setup() { - DynamicJsonObject root; + DynamicJsonDocument doc; // You can use a String as your JSON input. // WARNING: the content of the String will be duplicated in the JsonBuffer. String input = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; - deserializeJson(root, input); + deserializeJson(doc, input); + JsonObject& obj = doc.as(); // You can use a String to get an element of a JsonObject // No duplication is done. - long time = root[String("time")]; + long time = obj[String("time")]; // You can use a String to set an element of a JsonObject // WARNING: the content of the String will be duplicated in the JsonBuffer. - root[String("time")] = time; + obj[String("time")] = time; // You can get a String from a JsonObject or JsonArray: // No duplication is done, at least not in the JsonBuffer. - String sensor = root["sensor"]; + String sensor = obj["sensor"]; // Unfortunately, the following doesn't work (issue #118): - // sensor = root["sensor"]; // <- error "ambiguous overload for 'operator='" + // sensor = obj["sensor"]; // <- error "ambiguous overload for 'operator='" // As a workaround, you need to replace by: - sensor = root["sensor"].as(); + sensor = obj["sensor"].as(); // You can set a String to a JsonObject or JsonArray: // WARNING: the content of the String will be duplicated in the JsonBuffer. - root["sensor"] = sensor; + obj["sensor"] = sensor; // It works with RawJson too: - root["sensor"] = RawJson(sensor); + obj["sensor"] = RawJson(sensor); // You can also concatenate strings // WARNING: the content of the String will be duplicated in the JsonBuffer. - root[String("sen") + "sor"] = String("gp") + "s"; + obj[String("sen") + "sor"] = String("gp") + "s"; // You can compare the content of a JsonObject with a String - if (root["sensor"] == sensor) { + if (obj["sensor"] == sensor) { // ... } // Lastly, you can print the resulting JSON to a String String output; - serializeJson(root, output); + serializeJson(doc, output); } void loop() { diff --git a/fuzzing/fuzzer.cpp b/fuzzing/fuzzer.cpp index 358273c38..0c5a19af1 100644 --- a/fuzzing/fuzzer.cpp +++ b/fuzzing/fuzzer.cpp @@ -16,11 +16,11 @@ class memstream : public std::istream { }; extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - DynamicJsonVariant variant; + DynamicJsonDocument doc; memstream json(data, size); - JsonError error = deserializeJson(variant, json); - JsonVariant variant = jsonBuffer.parse(json); - if (!error) { + JsonError error = deserializeJson(doc, json); + if (error == JsonError::Ok) { + JsonVariant variant = doc.as(); variant.as(); // <- serialize to JSON } return 0; diff --git a/keywords.txt b/keywords.txt index ae31a74c9..647ae987e 100644 --- a/keywords.txt +++ b/keywords.txt @@ -3,9 +3,8 @@ as KEYWORD2 createNestedArray KEYWORD2 createNestedObject KEYWORD2 deserializeJson KEYWORD2 -DynamicJsonArray KEYWORD1 -DynamicJsonObject KEYWORD1 -DynamicJsonVariant KEYWORD1 +deserializeMsgPack KEYWORD2 +DynamicJsonDocument KEYWORD1 get KEYWORD2 JsonArray KEYWORD1 JsonObject KEYWORD1 @@ -13,6 +12,5 @@ JsonVariant KEYWORD1 serializeJson KEYWORD2 serializeJsonPretty KEYWORD2 set KEYWORD2 -StaticJsonArray KEYWORD1 -StaticJsonObject KEYWORD1 -StaticJsonVariant KEYWORD1 +StaticJsonDocument KEYWORD1 +to KEYWORD2 diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 2830ce261..71bc18e1a 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -4,18 +4,14 @@ #pragma once -#include "ArduinoJson/DynamicJsonArray.hpp" -#include "ArduinoJson/DynamicJsonObject.hpp" -#include "ArduinoJson/DynamicJsonVariant.hpp" +#include "ArduinoJson/DynamicJsonDocument.hpp" #include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" -#include "ArduinoJson/StaticJsonArray.hpp" -#include "ArduinoJson/StaticJsonObject.hpp" -#include "ArduinoJson/StaticJsonVariant.hpp" +#include "ArduinoJson/StaticJsonDocument.hpp" #include "ArduinoJson/deserializeJson.hpp" #include "ArduinoJson/deserializeMsgPack.hpp" -#include "ArduinoJson/Json/Deserialization/JsonParserImpl.hpp" -#include "ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp" +#include "ArduinoJson/Json/Deserialization/JsonDeserializer.hpp" +#include "ArduinoJson/Json/Serialization/JsonSerializer.hpp" #include "ArduinoJson/JsonArrayImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp" #include "ArduinoJson/JsonVariantImpl.hpp" diff --git a/src/ArduinoJson/DynamicJsonArray.hpp b/src/ArduinoJson/DynamicJsonArray.hpp deleted file mode 100644 index 6b82c6e24..000000000 --- a/src/ArduinoJson/DynamicJsonArray.hpp +++ /dev/null @@ -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::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonArray); - } - - DynamicJsonBuffer& buffer() { - return _buffer; - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonDocument.hpp b/src/ArduinoJson/DynamicJsonDocument.hpp new file mode 100644 index 000000000..9cbda37f9 --- /dev/null +++ b/src/ArduinoJson/DynamicJsonDocument.hpp @@ -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 + bool is() const { + return _root.is(); + } + + template + typename Internals::JsonVariantAs::type as() const { + return _root.as(); + } + + // JsonObject& to() + template + typename Internals::EnableIf::value, + JsonObject&>::type + to() { + clear(); + JsonObject* object = new (&_buffer) JsonObject(&_buffer); + if (!object) return JsonObject::invalid(); + _root = object; + return *object; + } + + // JsonArray& to() + template + typename Internals::EnableIf::value, + JsonArray&>::type + to() { + clear(); + JsonArray* array = new (&_buffer) JsonArray(&_buffer); + if (!array) return JsonArray::invalid(); + _root = array; + return *array; + } + + // JsonVariant& to() + template + typename Internals::EnableIf::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 + void visit(Visitor visitor) const { + return _root.visit(visitor); + } +}; +} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonObject.hpp b/src/ArduinoJson/DynamicJsonObject.hpp deleted file mode 100644 index c442377cc..000000000 --- a/src/ArduinoJson/DynamicJsonObject.hpp +++ /dev/null @@ -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::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonObject); - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/DynamicJsonVariant.hpp b/src/ArduinoJson/DynamicJsonVariant.hpp deleted file mode 100644 index 3f67ec42f..000000000 --- a/src/ArduinoJson/DynamicJsonVariant.hpp +++ /dev/null @@ -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 - DynamicJsonVariant& operator=(const T& value) { - _buffer.clear(); - JsonVariant::operator=(value); - return *this; - } - - template - 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 diff --git a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp new file mode 100644 index 000000000..c8db8ffd6 --- /dev/null +++ b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp @@ -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 +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::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 +struct JsonParserBuilder { + typedef typename StringTraits::Reader InputReader; + typedef JsonDeserializer TParser; + + static TParser makeParser(TJsonBuffer *buffer, TString &json, + uint8_t nestingLimit) { + return TParser(buffer, InputReader(json), *buffer, nestingLimit); + } +}; + +template +struct JsonParserBuilder::value>::type> { + typedef typename StringTraits::Reader TReader; + typedef StringWriter TWriter; + typedef JsonDeserializer TParser; + + static TParser makeParser(TJsonBuffer *buffer, TChar *json, + uint8_t nestingLimit) { + return TParser(buffer, TReader(json), TWriter(json), nestingLimit); + } +}; + +template +inline typename JsonParserBuilder::TParser makeParser( + TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { + return JsonParserBuilder::makeParser(buffer, json, + nestingLimit); +} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Json/Deserialization/JsonParser.hpp b/src/ArduinoJson/Json/Deserialization/JsonParser.hpp deleted file mode 100644 index c1a34a70e..000000000 --- a/src/ArduinoJson/Json/Deserialization/JsonParser.hpp +++ /dev/null @@ -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 -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 -struct JsonParserBuilder { - typedef typename StringTraits::Reader InputReader; - typedef JsonParser TParser; - - static TParser makeParser(TJsonBuffer *buffer, TString &json, - uint8_t nestingLimit) { - return TParser(buffer, InputReader(json), *buffer, nestingLimit); - } -}; - -template -struct JsonParserBuilder::value>::type> { - typedef typename StringTraits::Reader TReader; - typedef StringWriter TWriter; - typedef JsonParser TParser; - - static TParser makeParser(TJsonBuffer *buffer, TChar *json, - uint8_t nestingLimit) { - return TParser(buffer, TReader(json), TWriter(json), nestingLimit); - } -}; - -template -inline typename JsonParserBuilder::TParser makeParser( - TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { - return JsonParserBuilder::makeParser(buffer, json, - nestingLimit); -} -} // namespace Internals -} // namespace ArduinoJson diff --git a/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp b/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp deleted file mode 100644 index dd43c0cae..000000000 --- a/src/ArduinoJson/Json/Deserialization/JsonParserImpl.hpp +++ /dev/null @@ -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 -inline bool ArduinoJson::Internals::JsonParser::eat( - TReader &reader, char charToSkip) { - skipSpacesAndComments(reader); - if (reader.current() != charToSkip) return false; - reader.move(); - return true; -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::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 -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::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 -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parse( - JsonVariant &variant) { - skipSpacesAndComments(_reader); - - switch (_reader.current()) { - case '[': - return parseArray(variant); - - case '{': - return parseObject(variant); - - default: - return parseValue(variant); - } -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parseArray( - JsonVariant &variant) { - JsonArray *array = new (_buffer) JsonArray(_buffer); - if (!array) return JsonError::NoMemory; - variant = array; - return parse(*array); -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::parseObject( - JsonVariant &variant) { - JsonObject *object = new (_buffer) JsonObject(_buffer); - if (!object) return JsonError::NoMemory; - variant = object; - return parse(*object); -} - -template -inline ArduinoJson::JsonError -ArduinoJson::Internals::JsonParser::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 -inline const char * -ArduinoJson::Internals::JsonParser::parseString() { - typename RemoveReference::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(); -} diff --git a/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp index a8c6e3286..cae6ac84d 100644 --- a/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp @@ -16,26 +16,15 @@ #endif namespace ArduinoJson { - -class JsonArray; -class JsonObject; -class JsonVariant; - namespace Internals { -class JsonArraySubscript; -template -class JsonObjectSubscript; - template class JsonSerializer { public: - static void serialize(const JsonArray &, Writer &); - static void serialize(const JsonArraySubscript &, Writer &); - static void serialize(const JsonObject &, Writer &); - template - static void serialize(const JsonObjectSubscript &, Writer &); - static void serialize(const JsonVariant &, Writer &); + template + static void serialize(const TSource &source, Writer &writer) { + source.visit(Visitor(&writer)); + } struct Visitor { Visitor(Writer *writer) : _writer(writer) {} @@ -44,12 +33,38 @@ class JsonSerializer { _writer->writeFloat(value); } - void acceptArray(const JsonArray &value) { - serialize(value, *_writer); + void acceptArray(const JsonArray &array) { + _writer->beginArray(); + + JsonArray::const_iterator it = array.begin(); + while (it != array.end()) { + it->visit(*this); + + ++it; + if (it == array.end()) break; + + _writer->writeComma(); + } + + _writer->endArray(); } - void acceptObject(const JsonObject &value) { - 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) { diff --git a/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp b/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp deleted file mode 100644 index 2060cae54..000000000 --- a/src/ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp +++ /dev/null @@ -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 -inline void ArduinoJson::Internals::JsonSerializer::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 -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonArraySubscript& arraySubscript, Writer& writer) { - serialize(arraySubscript.as(), writer); -} - -template -inline void ArduinoJson::Internals::JsonSerializer::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 -template -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonObjectSubscript& objectSubscript, Writer& writer) { - serialize(objectSubscript.template as(), writer); -} - -template -inline void ArduinoJson::Internals::JsonSerializer::serialize( - const JsonVariant& variant, Writer& writer) { - variant.visit(Visitor(&writer)); -} diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index 51757f207..d52430fd8 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -180,6 +180,11 @@ class JsonArray : public Internals::ReferenceType, } } + template + void visit(Visitor visitor) const { + return visitor.acceptArray(*this); + } + private: template bool set_impl(size_t index, TValueRef value) { diff --git a/src/ArduinoJson/JsonArraySubscript.hpp b/src/ArduinoJson/JsonArraySubscript.hpp index a96339914..839182fff 100644 --- a/src/ArduinoJson/JsonArraySubscript.hpp +++ b/src/ArduinoJson/JsonArraySubscript.hpp @@ -74,6 +74,11 @@ class JsonArraySubscript : public JsonVariantBase { return _array.set(_index, value); } + template + void visit(Visitor visitor) const { + return _array.get(_index).visit(visitor); + } + private: JsonArray& _array; const size_t _index; diff --git a/src/ArduinoJson/JsonError.hpp b/src/ArduinoJson/JsonError.hpp index d7f4c903c..440604159 100644 --- a/src/ArduinoJson/JsonError.hpp +++ b/src/ArduinoJson/JsonError.hpp @@ -8,16 +8,7 @@ namespace ArduinoJson { class JsonError { public: - enum Code { - Ok, - OpeningBraceExpected, - ClosingBraceExpected, - OpeningBracketExpected, - ClosingBracketExpected, - ColonExpected, - TooDeep, - NoMemory - }; + enum Code { Ok, TooDeep, NoMemory, InvalidInput }; JsonError(Code code) : _code(code) {} @@ -45,20 +36,12 @@ class JsonError { switch (_code) { case Ok: return "Ok"; - case OpeningBraceExpected: - return "OpeningBraceExpected"; - case ClosingBraceExpected: - return "ClosingBraceExpected"; - case OpeningBracketExpected: - return "OpeningBracketExpected"; - case ClosingBracketExpected: - return "ClosingBracketExpected"; - case ColonExpected: - return "ColonExpected"; case TooDeep: return "TooDeep"; case NoMemory: return "NoMemory"; + case InvalidInput: + return "InvalidInput"; default: return "???"; } @@ -73,6 +56,11 @@ inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { s << e.c_str(); return s; } + +inline std::ostream& operator<<(std::ostream& s, JsonError::Code c) { + s << JsonError(c).c_str(); + return s; +} #endif } // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index 43e39ec73..def89b956 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -229,6 +229,11 @@ class JsonObject : public Internals::ReferenceType, return instance; } + template + void visit(Visitor visitor) const { + return visitor.acceptObject(*this); + } + private: // Returns the list node that matches the specified key. template diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index 832d0ca91..f323fb328 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -82,6 +82,11 @@ class JsonObjectSubscript return _object.set(_key, value); } + template + void visit(Visitor visitor) const { + return _object.get(_key).visit(visitor); + } + private: JsonObject& _object; TStringRef _key; diff --git a/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp b/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp index 9570e489a..3b67deea1 100644 --- a/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp +++ b/src/ArduinoJson/Memory/DynamicJsonBuffer.hpp @@ -151,6 +151,12 @@ class DynamicJsonBufferBase : public JsonBuffer { Block* _head; size_t _nextBlockCapacity; }; + +// Implements a JsonBuffer with dynamic memory allocation. +// You are strongly encouraged to consider using StaticJsonBuffer which is much +// more suitable for embedded systems. +typedef Internals::DynamicJsonBufferBase + DynamicJsonBuffer; } // namespace Internals #if defined(__clang__) @@ -160,10 +166,4 @@ class DynamicJsonBufferBase : public JsonBuffer { #pragma GCC diagnostic pop #endif #endif - -// Implements a JsonBuffer with dynamic memory allocation. -// You are strongly encouraged to consider using StaticJsonBuffer which is much -// more suitable for embedded systems. -typedef Internals::DynamicJsonBufferBase - DynamicJsonBuffer; } // namespace ArduinoJson diff --git a/src/ArduinoJson/Memory/StaticJsonBuffer.hpp b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp index 237221d48..eb4fc36e2 100644 --- a/src/ArduinoJson/Memory/StaticJsonBuffer.hpp +++ b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp @@ -92,7 +92,6 @@ class StaticJsonBufferBase : public JsonBuffer { size_t _capacity; size_t _size; }; -} // namespace Internals #if defined(__clang__) #pragma clang diagnostic push @@ -118,6 +117,7 @@ class StaticJsonBuffer : public Internals::StaticJsonBufferBase { private: char _buffer[ACTUAL_CAPACITY]; }; +} // namespace Internals } // namespace ArduinoJson #if defined(__clang__) diff --git a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index 0cf05c56f..e1a923b79 100644 --- a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -28,40 +28,6 @@ class MsgPackDeserializer { _writer(writer), _nestingLimit(nestingLimit) {} - MsgPackError parse(JsonArray &array) { - uint8_t c = readOne(); - size_t n; - - if ((c & 0xF0) == 0x90) { - n = c & 0x0F; - } else if (c == 0xdc) { - n = readInteger(); - } else if (c == 0xdd) { - n = readInteger(); - } 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(); - } else if (c == 0xdf) { - n = readInteger(); - } else { - return MsgPackError::NotAnObject; - } - - return readObject(object, n); - } - MsgPackError parse(JsonVariant &variant) { uint8_t c = readOne(); diff --git a/src/ArduinoJson/MsgPack/MsgPackError.hpp b/src/ArduinoJson/MsgPack/MsgPackError.hpp index 0162aac63..0134a723b 100644 --- a/src/ArduinoJson/MsgPack/MsgPackError.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackError.hpp @@ -8,7 +8,7 @@ namespace ArduinoJson { class MsgPackError { public: - enum Code { Ok, NotSupported, NoMemory, NotAnArray, NotAnObject, TooDeep }; + enum Code { Ok, NotSupported, NoMemory, TooDeep }; MsgPackError() {} @@ -42,10 +42,6 @@ class MsgPackError { return "NotSupported"; case NoMemory: return "NoMemory"; - case NotAnArray: - return "NotAnArray"; - case NotAnObject: - return "NotAnObject"; case TooDeep: return "TooDeep"; default: @@ -62,6 +58,11 @@ inline std::ostream& operator<<(std::ostream& os, const MsgPackError& err) { os << err.c_str(); return os; } + +inline std::ostream& operator<<(std::ostream& os, MsgPackError::Code code) { + os << MsgPackError(code).c_str(); + return os; +} #endif } // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonArray.hpp b/src/ArduinoJson/StaticJsonArray.hpp deleted file mode 100644 index 21b3a2207..000000000 --- a/src/ArduinoJson/StaticJsonArray.hpp +++ /dev/null @@ -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 -class StaticJsonArray : public JsonArray { - StaticJsonBuffer _buffer; - - public: - StaticJsonArray() : JsonArray(&_buffer) {} - - void clear() { - Internals::List::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonArray); - } - - Internals::StaticJsonBufferBase& buffer() { - return _buffer; - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonDocument.hpp b/src/ArduinoJson/StaticJsonDocument.hpp new file mode 100644 index 000000000..a1821ca31 --- /dev/null +++ b/src/ArduinoJson/StaticJsonDocument.hpp @@ -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 +class StaticJsonDocument { + Internals::StaticJsonBuffer _buffer; + JsonVariant _root; + + public: + Internals::StaticJsonBufferBase& buffer() { + return _buffer; + } + + template + bool is() const { + return _root.is(); + } + + template + typename Internals::JsonVariantAs::type as() const { + return _root.as(); + } + + // JsonObject& to() + template + typename Internals::EnableIf::value, + JsonObject&>::type + to() { + clear(); + JsonObject* object = new (&_buffer) JsonObject(&_buffer); + if (!object) return JsonObject::invalid(); + _root = object; + return *object; + } + + // JsonArray& to() + template + typename Internals::EnableIf::value, + JsonArray&>::type + to() { + clear(); + JsonArray* array = new (&_buffer) JsonArray(&_buffer); + if (!array) return JsonArray::invalid(); + _root = array; + return *array; + } + + // JsonVariant to() + template + typename Internals::EnableIf::value, + T&>::type + to() { + clear(); + return _root; + } + + void clear() { + _buffer.clear(); + _root = JsonVariant(); + } + + size_t memoryUsage() const { + return _buffer.size(); + } + + template + void visit(Visitor visitor) const { + return _root.visit(visitor); + } +}; + +} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonObject.hpp b/src/ArduinoJson/StaticJsonObject.hpp deleted file mode 100644 index 0b5912a84..000000000 --- a/src/ArduinoJson/StaticJsonObject.hpp +++ /dev/null @@ -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 -class StaticJsonObject : public JsonObject { - StaticJsonBuffer _buffer; - - public: - StaticJsonObject() : JsonObject(&_buffer) {} - - void clear() { - Internals::List::clear(); - _buffer.clear(); - } - - size_t memoryUsage() const { - return _buffer.size() + sizeof(JsonObject); - } - - Internals::StaticJsonBufferBase& buffer() { - return _buffer; - } -}; -} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonVariant.hpp b/src/ArduinoJson/StaticJsonVariant.hpp deleted file mode 100644 index 250e17549..000000000 --- a/src/ArduinoJson/StaticJsonVariant.hpp +++ /dev/null @@ -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 -class StaticJsonVariant : public JsonVariant { - StaticJsonBuffer _buffer; - - public: - template - StaticJsonVariant& operator=(const T& value) { - _buffer.clear(); - JsonVariant::operator=(value); - return *this; - } - - template - 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 diff --git a/src/ArduinoJson/TypeTraits/Max.hpp b/src/ArduinoJson/TypeTraits/Max.hpp index e046910d4..13d653711 100644 --- a/src/ArduinoJson/TypeTraits/Max.hpp +++ b/src/ArduinoJson/TypeTraits/Max.hpp @@ -4,6 +4,8 @@ #pragma once +#include // for size_t + namespace ArduinoJson { namespace Internals { diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index d0932a996..46ffbfff3 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -4,43 +4,40 @@ #pragma once -#include "Json/Deserialization/JsonParser.hpp" +#include "Json/Deserialization/JsonDeserializer.hpp" namespace ArduinoJson { -// JsonError deserializeJson(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// JsonError deserializeJson(TDocument& doc, TString json); +// TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& -template +template typename Internals::EnableIf::value, JsonError>::type -deserializeJson(TDestination &destination, const TString &json, +deserializeJson(TDocument &doc, const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeParser(&destination.buffer(), json, nestingLimit) - .parse(destination); + return Internals::makeParser(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// JsonError deserializeJson(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// JsonError deserializeJson(TDocument& doc, TString json); +// TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const char*, const char[N], const FlashStringHelper* -template +template JsonError deserializeJson( - TDestination &destination, TString *json, + TDocument &doc, TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeParser(&destination.buffer(), json, nestingLimit) - .parse(destination); + return Internals::makeParser(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// JsonError deserializeJson(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// JsonError deserializeJson(TDocument& doc, TString json); +// TDocument = DynamicJsonDocument, StaticJsonDocument // TString = std::istream&, Stream& -template +template JsonError deserializeJson( - TDestination &destination, TString &json, + TDocument &doc, TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeParser(&destination.buffer(), json, nestingLimit) - .parse(destination); + return Internals::makeParser(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeMsgPack.hpp b/src/ArduinoJson/deserializeMsgPack.hpp index d55a7e778..60493d35a 100644 --- a/src/ArduinoJson/deserializeMsgPack.hpp +++ b/src/ArduinoJson/deserializeMsgPack.hpp @@ -7,43 +7,37 @@ #include "MsgPack/MsgPackDeserializer.hpp" namespace ArduinoJson { -// MsgPackError deserializeMsgPack(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// MsgPackError deserializeMsgPack(TDocument& doc, TString json); +// TDocument = DynamicJsonArray | StaticJsonArray // TString = const std::string&, const String& -template +template typename Internals::EnableIf::value, MsgPackError>::type -deserializeMsgPack(TDestination &destination, const TString &json, +deserializeMsgPack(TDocument &doc, const TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeMsgPackDeserializer(&destination.buffer(), json, - nestingLimit) - .parse(destination); + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// MsgPackError deserializeMsgPack(TDocument& doc, TString json); +// TDocument = DynamicJsonArray | StaticJsonArray // TString = const char*, const char[N], const FlashStringHelper* -template +template MsgPackError deserializeMsgPack( - TDestination &destination, TString *json, + TDocument &doc, TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeMsgPackDeserializer(&destination.buffer(), json, - nestingLimit) - .parse(destination); + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDestination& destination, TString json); -// TDestination = JsonArray, JsonObject, JsonVariant +// MsgPackError deserializeMsgPack(TDocument& doc, TString json); +// TDocument = DynamicJsonArray | StaticJsonArray // TString = std::istream&, Stream& -template +template MsgPackError deserializeMsgPack( - TDestination &destination, TString &json, + TDocument &doc, TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - destination.clear(); - return Internals::makeMsgPackDeserializer(&destination.buffer(), json, - nestingLimit) - .parse(destination); + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) + .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b33dfbb45..d255347f5 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -68,7 +68,7 @@ add_subdirectory(DynamicJsonBuffer) add_subdirectory(IntegrationTests) add_subdirectory(JsonArray) add_subdirectory(JsonObject) -add_subdirectory(JsonParser) +add_subdirectory(JsonDeserializer) add_subdirectory(JsonSerializer) add_subdirectory(JsonVariant) add_subdirectory(JsonWriter) diff --git a/test/DynamicJsonBuffer/alloc.cpp b/test/DynamicJsonBuffer/alloc.cpp index 0d1994f65..c45e6866a 100644 --- a/test/DynamicJsonBuffer/alloc.cpp +++ b/test/DynamicJsonBuffer/alloc.cpp @@ -18,8 +18,7 @@ std::stringstream allocatorLog; struct SpyingAllocator : DefaultAllocator { void* allocate(size_t n) { - allocatorLog << static_cast("A") - << (n - DynamicJsonBuffer::EmptyBlockSize); + allocatorLog << "A" << (n - DynamicJsonBuffer::EmptyBlockSize); return DefaultAllocator::allocate(n); } void deallocate(void* p) { diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index 5587a1cea..ecb82b8c0 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -23,19 +23,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { } // TODO: uncomment - // SECTION("parseArray()") { - // char json[] = "[{}]"; - // DynamicJsonArray arr; - - // JsonError err = deserializeJson(arr, json); - - // REQUIRE(err != JsonError::Ok); - // } - - // TODO: uncomment - // SECTION("parseObject()") { + // SECTION("deserializeJson()") { // char json[] = "{[]}"; - // DynamicJsonObject obj; + // DynamicJsonDocument obj; // JsonError err = deserializeJson(obj, json); diff --git a/test/DynamicJsonBuffer/size.cpp b/test/DynamicJsonBuffer/size.cpp index 8ebba424c..06b187d58 100644 --- a/test/DynamicJsonBuffer/size.cpp +++ b/test/DynamicJsonBuffer/size.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + TEST_CASE("DynamicJsonBuffer::size()") { DynamicJsonBuffer buffer; diff --git a/test/DynamicJsonBuffer/startString.cpp b/test/DynamicJsonBuffer/startString.cpp index 2e5bef7fe..3253f1ad6 100644 --- a/test/DynamicJsonBuffer/startString.cpp +++ b/test/DynamicJsonBuffer/startString.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + TEST_CASE("DynamicJsonBuffer::startString()") { SECTION("WorksWhenBufferIsBigEnough") { DynamicJsonBuffer jsonBuffer(6); diff --git a/test/IntegrationTests/CMakeLists.txt b/test/IntegrationTests/CMakeLists.txt index 9294bbbf9..c158367ec 100644 --- a/test/IntegrationTests/CMakeLists.txt +++ b/test/IntegrationTests/CMakeLists.txt @@ -2,7 +2,7 @@ # Copyright Benoit Blanchon 2014-2018 # MIT License -add_executable(IntegrationTests +add_executable(IntegrationTests gbathree.cpp round_trip.cpp ) diff --git a/test/IntegrationTests/gbathree.cpp b/test/IntegrationTests/gbathree.cpp index dd6b293f0..965022ae8 100644 --- a/test/IntegrationTests/gbathree.cpp +++ b/test/IntegrationTests/gbathree.cpp @@ -6,10 +6,10 @@ #include TEST_CASE("Gbathree") { - DynamicJsonObject _object; + DynamicJsonDocument doc; JsonError error = deserializeJson( - _object, + doc, "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" "baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":" @@ -20,67 +20,68 @@ TEST_CASE("Gbathree") { "\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15," "15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15]," "[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); + JsonObject& root = doc.as(); SECTION("Success") { REQUIRE(error == JsonError::Ok); } SECTION("ProtocolName") { - REQUIRE("fluorescence" == _object["protocol_name"]); + REQUIRE("fluorescence" == root["protocol_name"]); } SECTION("Repeats") { - REQUIRE(1 == _object["repeats"]); + REQUIRE(1 == root["repeats"]); } SECTION("Wait") { - REQUIRE(0 == _object["wait"]); + REQUIRE(0 == root["wait"]); } SECTION("Measurements") { - REQUIRE(3 == _object["measurements"]); + REQUIRE(3 == root["measurements"]); } SECTION("Meas2_Light") { - REQUIRE(15 == _object["meas2_light"]); + REQUIRE(15 == root["meas2_light"]); } SECTION("Meas1_Baseline") { - REQUIRE(0 == _object["meas1_baseline"]); + REQUIRE(0 == root["meas1_baseline"]); } SECTION("Act_Light") { - REQUIRE(20 == _object["act_light"]); + REQUIRE(20 == root["act_light"]); } SECTION("Pulsesize") { - REQUIRE(25 == _object["pulsesize"]); + REQUIRE(25 == root["pulsesize"]); } SECTION("Pulsedistance") { - REQUIRE(10000 == _object["pulsedistance"]); + REQUIRE(10000 == root["pulsedistance"]); } SECTION("Actintensity1") { - REQUIRE(50 == _object["actintensity1"]); + REQUIRE(50 == root["actintensity1"]); } SECTION("Actintensity2") { - REQUIRE(255 == _object["actintensity2"]); + REQUIRE(255 == root["actintensity2"]); } SECTION("Measintensity") { - REQUIRE(255 == _object["measintensity"]); + REQUIRE(255 == root["measintensity"]); } SECTION("Calintensity") { - REQUIRE(255 == _object["calintensity"]); + REQUIRE(255 == root["calintensity"]); } SECTION("Pulses") { // "pulses":[50,50,50] - JsonArray& array = _object["pulses"]; + JsonArray& array = root["pulses"]; REQUIRE(array.success()); REQUIRE(3 == array.size()); @@ -93,7 +94,7 @@ TEST_CASE("Gbathree") { SECTION("Act") { // "act":[2,1,2,2] - JsonArray& array = _object["act"]; + JsonArray& array = root["act"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -106,7 +107,7 @@ TEST_CASE("Gbathree") { SECTION("Detectors") { // "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]] - JsonArray& array = _object["detectors"]; + JsonArray& array = root["detectors"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -123,7 +124,7 @@ TEST_CASE("Gbathree") { SECTION("Alta") { // alta:[2,2,2,2] - JsonArray& array = _object["alta"]; + JsonArray& array = root["alta"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -136,7 +137,7 @@ TEST_CASE("Gbathree") { SECTION("Altb") { // altb:[2,2,2,2] - JsonArray& array = _object["altb"]; + JsonArray& array = root["altb"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -149,7 +150,7 @@ TEST_CASE("Gbathree") { SECTION("Measlights") { // "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] - JsonArray& array = _object["measlights"]; + JsonArray& array = root["measlights"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -167,7 +168,7 @@ TEST_CASE("Gbathree") { SECTION("Measlights2") { // "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] - JsonArray& array = _object["measlights2"]; + JsonArray& array = root["measlights2"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -184,7 +185,7 @@ TEST_CASE("Gbathree") { SECTION("Altc") { // altc:[2,2,2,2] - JsonArray& array = _object["altc"]; + JsonArray& array = root["altc"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); @@ -197,7 +198,7 @@ TEST_CASE("Gbathree") { SECTION("Altd") { // altd:[2,2,2,2] - JsonArray& array = _object["altd"]; + JsonArray& array = root["altd"]; REQUIRE(array.success()); REQUIRE(4 == array.size()); diff --git a/test/IntegrationTests/round_trip.cpp b/test/IntegrationTests/round_trip.cpp index 487dbb740..ac2218351 100644 --- a/test/IntegrationTests/round_trip.cpp +++ b/test/IntegrationTests/round_trip.cpp @@ -6,15 +6,15 @@ #include void check(std::string originalJson) { - DynamicJsonObject obj; + DynamicJsonDocument doc; std::string prettyJson; - deserializeJson(obj, originalJson); - serializeJsonPretty(obj, prettyJson); + deserializeJson(doc, originalJson); + serializeJsonPretty(doc, prettyJson); std::string finalJson; - deserializeJson(obj, originalJson); - serializeJson(obj, finalJson); + deserializeJson(doc, originalJson); + serializeJson(doc, finalJson); REQUIRE(originalJson == finalJson); } diff --git a/test/JsonArray/add.cpp b/test/JsonArray/add.cpp index 61f6ec6f6..b2d6034d7 100644 --- a/test/JsonArray/add.cpp +++ b/test/JsonArray/add.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray::add()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); SECTION("int") { _array.add(123); @@ -38,7 +39,8 @@ TEST_CASE("JsonArray::add()") { } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); _array.add(arr); @@ -48,7 +50,8 @@ TEST_CASE("JsonArray::add()") { } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); _array.add(obj); @@ -59,7 +62,8 @@ TEST_CASE("JsonArray::add()") { SECTION("array subscript") { const char* str = "hello"; - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add(str); _array.add(arr[0]); @@ -69,7 +73,8 @@ TEST_CASE("JsonArray::add()") { SECTION("object subscript") { const char* str = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); obj["x"] = str; _array.add(obj["x"]); @@ -80,30 +85,30 @@ TEST_CASE("JsonArray::add()") { SECTION("should not duplicate const char*") { _array.add("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char*") { _array.add(const_cast("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string") { _array.add(std::string("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should not duplicate RawJson(const char*)") { _array.add(RawJson("{}")); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate RawJson(char*)") { _array.add(RawJson(const_cast("{}"))); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } } diff --git a/test/JsonArray/basics.cpp b/test/JsonArray/basics.cpp index 0e9d06177..9c0b727d4 100644 --- a/test/JsonArray/basics.cpp +++ b/test/JsonArray/basics.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray basics") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); SECTION("SuccessIsTrue") { REQUIRE(array.success()); diff --git a/test/JsonArray/copyFrom.cpp b/test/JsonArray/copyFrom.cpp index fa2045bce..60ba95eae 100644 --- a/test/JsonArray/copyFrom.cpp +++ b/test/JsonArray/copyFrom.cpp @@ -7,7 +7,8 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("OneDimension") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[] = {1, 2, 3}; @@ -20,7 +21,8 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("OneDimension_JsonBufferTooSmall") { const size_t SIZE = JSON_ARRAY_SIZE(2); - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[] = {1, 2, 3}; @@ -32,7 +34,8 @@ TEST_CASE("JsonArray::copyFrom()") { } SECTION("TwoDimensions") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; @@ -46,7 +49,8 @@ TEST_CASE("JsonArray::copyFrom()") { SECTION("TwoDimensions_JsonBufferTooSmall") { const size_t SIZE = JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2); - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray& array = doc.to(); char json[32]; int source[][3] = {{1, 2, 3}, {4, 5, 6}}; diff --git a/test/JsonArray/copyTo.cpp b/test/JsonArray/copyTo.cpp index 9c31e880c..87c9801ee 100644 --- a/test/JsonArray/copyTo.cpp +++ b/test/JsonArray/copyTo.cpp @@ -6,12 +6,13 @@ #include TEST_CASE("JsonArray::copyTo()") { - DynamicJsonArray array; + DynamicJsonDocument doc; SECTION("BiggerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonError err = deserializeJson(array, json); + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); + JsonArray& array = doc.as(); int destination[4] = {0}; size_t result = array.copyTo(destination); @@ -25,8 +26,9 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("SmallerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonError err = deserializeJson(array, json); + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); + JsonArray& array = doc.as(); int destination[2] = {0}; size_t result = array.copyTo(destination); @@ -39,8 +41,9 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("TwoOneDimensionIntegerArray") { char json[] = "[[1,2],[3],[4]]"; - JsonError err = deserializeJson(array, json); + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); + JsonArray& array = doc.as(); int destination[3][2] = {{0}}; array.copyTo(destination); diff --git a/test/JsonArray/iterator.cpp b/test/JsonArray/iterator.cpp index ef0c7785a..91efc2435 100644 --- a/test/JsonArray/iterator.cpp +++ b/test/JsonArray/iterator.cpp @@ -7,7 +7,8 @@ template static void run_iterator_test() { - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray& array = doc.to(); array.add(12); array.add(34); diff --git a/test/JsonArray/remove.cpp b/test/JsonArray/remove.cpp index 61ea011d7..27f149ac1 100644 --- a/test/JsonArray/remove.cpp +++ b/test/JsonArray/remove.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray::remove()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); _array.add(1); _array.add(2); _array.add(3); diff --git a/test/JsonArray/set.cpp b/test/JsonArray/set.cpp index f0f55016d..498b2668e 100644 --- a/test/JsonArray/set.cpp +++ b/test/JsonArray/set.cpp @@ -8,7 +8,8 @@ using namespace Catch::Matchers; TEST_CASE("JsonArray::set()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); _array.add(0); SECTION("int") { @@ -40,7 +41,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); _array.set(0, arr); @@ -50,7 +52,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); _array.set(0, obj); @@ -60,7 +63,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add("hello"); _array.set(0, arr[0]); @@ -69,7 +73,8 @@ TEST_CASE("JsonArray::set()") { } SECTION("object subscript") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); obj["x"] = "hello"; _array.set(0, obj["x"]); @@ -80,18 +85,18 @@ TEST_CASE("JsonArray::set()") { SECTION("should not duplicate const char*") { _array.set(0, "world"); const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char*") { _array.set(0, const_cast("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string") { _array.set(0, std::string("world")); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } } diff --git a/test/JsonArray/size.cpp b/test/JsonArray/size.cpp index de409a794..48edee071 100644 --- a/test/JsonArray/size.cpp +++ b/test/JsonArray/size.cpp @@ -6,7 +6,8 @@ #include TEST_CASE("JsonArray::size()") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); SECTION("increases after add()") { _array.add("hello"); diff --git a/test/JsonArray/subscript.cpp b/test/JsonArray/subscript.cpp index 17f3e7a4f..d763e4b11 100644 --- a/test/JsonArray/subscript.cpp +++ b/test/JsonArray/subscript.cpp @@ -7,7 +7,8 @@ #include TEST_CASE("JsonArray::operator[]") { - DynamicJsonArray _array; + DynamicJsonDocument doc; + JsonArray& _array = doc.to(); _array.add(0); SECTION("int") { @@ -51,7 +52,8 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); _array[0] = arr; @@ -64,7 +66,8 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); _array[0] = obj; @@ -77,7 +80,8 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); const char* str = "hello"; arr.add(str); @@ -88,8 +92,9 @@ TEST_CASE("JsonArray::operator[]") { } SECTION("object subscript") { - DynamicJsonObject obj; const char* str = "hello"; + DynamicJsonDocument doc2; + JsonObject& obj = doc2.to(); obj["x"] = str; @@ -101,18 +106,18 @@ TEST_CASE("JsonArray::operator[]") { SECTION("should not duplicate const char*") { _array[0] = "world"; const size_t expectedSize = JSON_ARRAY_SIZE(1); - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char*") { _array[0] = const_cast("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string") { _array[0] = std::string("world"); const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; - REQUIRE(expectedSize == _array.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } } diff --git a/test/JsonDeserializer/CMakeLists.txt b/test/JsonDeserializer/CMakeLists.txt new file mode 100644 index 000000000..6201ea701 --- /dev/null +++ b/test/JsonDeserializer/CMakeLists.txt @@ -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) diff --git a/test/JsonParser/JsonError.cpp b/test/JsonDeserializer/JsonError.cpp similarity index 62% rename from test/JsonParser/JsonError.cpp rename to test/JsonDeserializer/JsonError.cpp index 21714ba00..edcad063f 100644 --- a/test/JsonParser/JsonError.cpp +++ b/test/JsonDeserializer/JsonError.cpp @@ -22,23 +22,21 @@ void testBoolification(JsonError error, bool expected) { TEST_CASE("JsonError") { SECTION("c_str()") { TEST_STRINGIFICATION(Ok); - TEST_STRINGIFICATION(OpeningBraceExpected); - TEST_STRINGIFICATION(ClosingBraceExpected); - TEST_STRINGIFICATION(OpeningBracketExpected); - TEST_STRINGIFICATION(ClosingBracketExpected); - TEST_STRINGIFICATION(ColonExpected); TEST_STRINGIFICATION(TooDeep); TEST_STRINGIFICATION(NoMemory); + TEST_STRINGIFICATION(InvalidInput); } SECTION("as boolean") { TEST_BOOLIFICATION(Ok, false); - TEST_BOOLIFICATION(OpeningBraceExpected, true); - TEST_BOOLIFICATION(ClosingBraceExpected, true); - TEST_BOOLIFICATION(OpeningBracketExpected, true); - TEST_BOOLIFICATION(ClosingBracketExpected, true); - TEST_BOOLIFICATION(ColonExpected, true); TEST_BOOLIFICATION(TooDeep, true); TEST_BOOLIFICATION(NoMemory, true); + TEST_BOOLIFICATION(InvalidInput, true); + } + + SECTION("ostream") { + std::stringstream s; + s << JsonError::InvalidInput; + REQUIRE(s.str() == "InvalidInput"); } } diff --git a/test/JsonParser/DynamicJsonArray.cpp b/test/JsonDeserializer/deserializeJsonArray.cpp similarity index 56% rename from test/JsonParser/DynamicJsonArray.cpp rename to test/JsonDeserializer/deserializeJsonArray.cpp index cfb498f75..54dcc2d51 100644 --- a/test/JsonParser/DynamicJsonArray.cpp +++ b/test/JsonDeserializer/deserializeJsonArray.cpp @@ -5,11 +5,12 @@ #include #include -TEST_CASE("deserializeJson(DynamicJsonArray&)") { - DynamicJsonArray arr; +TEST_CASE("deserialize JSON array") { + DynamicJsonDocument doc; SECTION("An empty array") { - JsonError err = deserializeJson(arr, "[]"); + JsonError err = deserializeJson(doc, "[]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(0 == arr.size()); @@ -17,14 +18,16 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { SECTION("Spaces") { SECTION("Before the opening bracket") { - JsonError err = deserializeJson(arr, " []"); + JsonError err = deserializeJson(doc, " []"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(0 == arr.size()); } SECTION("Before first value") { - JsonError err = deserializeJson(arr, "[ \t\r\n42]"); + JsonError err = deserializeJson(doc, "[ \t\r\n42]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -32,7 +35,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After first value") { - JsonError err = deserializeJson(arr, "[42 \t\r\n]"); + JsonError err = deserializeJson(doc, "[42 \t\r\n]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -42,7 +46,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { SECTION("Values types") { SECTION("On integer") { - JsonError err = deserializeJson(arr, "[42]"); + JsonError err = deserializeJson(doc, "[42]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -50,7 +55,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Two integers") { - JsonError err = deserializeJson(arr, "[42,84]"); + JsonError err = deserializeJson(doc, "[42,84]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -59,7 +65,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Double") { - JsonError err = deserializeJson(arr, "[4.2,1e2]"); + JsonError err = deserializeJson(doc, "[4.2,1e2]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -68,7 +75,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Unsigned long") { - JsonError err = deserializeJson(arr, "[4294967295]"); + JsonError err = deserializeJson(doc, "[4294967295]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -76,7 +84,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Boolean") { - JsonError err = deserializeJson(arr, "[true,false]"); + JsonError err = deserializeJson(doc, "[true,false]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -85,18 +94,20 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Null") { - JsonError err = deserializeJson(arr, "[null,null]"); + JsonError err = deserializeJson(doc, "[null,null]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); - REQUIRE(arr[0].as() == 0); - REQUIRE(arr[1].as() == 0); + REQUIRE(arr[0].as() == 0); + REQUIRE(arr[1].as() == 0); } } SECTION("Quotes") { SECTION("Double quotes") { - JsonError err = deserializeJson(arr, "[ \"hello\" , \"world\" ]"); + JsonError err = deserializeJson(doc, "[ \"hello\" , \"world\" ]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -105,7 +116,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Single quotes") { - JsonError err = deserializeJson(arr, "[ 'hello' , 'world' ]"); + JsonError err = deserializeJson(doc, "[ 'hello' , 'world' ]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -114,7 +126,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("No quotes") { - JsonError err = deserializeJson(arr, "[ hello , world ]"); + JsonError err = deserializeJson(doc, "[ hello , world ]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -123,7 +136,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Double quotes (empty strings)") { - JsonError err = deserializeJson(arr, "[\"\",\"\"]"); + JsonError err = deserializeJson(doc, "[\"\",\"\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -132,7 +146,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Single quotes (empty strings)") { - JsonError err = deserializeJson(arr, "[\'\',\'\']"); + JsonError err = deserializeJson(doc, "[\'\',\'\']"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -141,30 +156,28 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("No quotes (empty strings)") { - JsonError err = deserializeJson(arr, "[,]"); + JsonError err = deserializeJson(doc, "[,]"); - REQUIRE(err == JsonError::Ok); - REQUIRE(2 == arr.size()); - REQUIRE(arr[0] == ""); - REQUIRE(arr[1] == ""); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Closing single quotes missing") { - JsonError err = deserializeJson(arr, "[\"]"); + JsonError err = deserializeJson(doc, "[\"]"); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Closing double quotes missing") { - JsonError err = deserializeJson(arr, "[\']"); + JsonError err = deserializeJson(doc, "[\']"); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::InvalidInput); } } SECTION("Block comments") { SECTION("Before opening bracket") { - JsonError err = deserializeJson(arr, "/*COMMENT*/ [\"hello\"]"); + JsonError err = deserializeJson(doc, "/*COMMENT*/ [\"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -172,7 +185,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After opening bracket") { - JsonError err = deserializeJson(arr, "[/*COMMENT*/ \"hello\"]"); + JsonError err = deserializeJson(doc, "[/*COMMENT*/ \"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -180,7 +194,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/]"); + JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -188,7 +203,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"]/*COMMENT*/"); + JsonError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -196,7 +212,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before comma") { - JsonError err = deserializeJson(arr, "[\"hello\"/*COMMENT*/,\"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -205,7 +222,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After comma") { - JsonError err = deserializeJson(arr, "[\"hello\",/*COMMENT*/ \"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -214,24 +232,25 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("/*/") { - JsonError err = deserializeJson(arr, "[/*/\n]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/*/\n]"); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Unfinished comment") { - JsonError err = deserializeJson(arr, "[/*COMMENT]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/*COMMENT]"); + REQUIRE(err == JsonError::InvalidInput); } SECTION("Final slash missing") { - JsonError err = deserializeJson(arr, "[/*COMMENT*]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/*COMMENT*]"); + REQUIRE(err == JsonError::InvalidInput); } } SECTION("Line comments") { SECTION("Before opening bracket") { - JsonError err = deserializeJson(arr, "//COMMENT\n\t[\"hello\"]"); + JsonError err = deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -239,7 +258,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After opening bracket") { - JsonError err = deserializeJson(arr, "[//COMMENT\n\"hello\"]"); + JsonError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -247,7 +267,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\r\n]"); + JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\r\n]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -255,7 +276,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After closing bracket") { - JsonError err = deserializeJson(arr, "[\"hello\"]//COMMENT\n"); + JsonError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -263,7 +285,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Before comma") { - JsonError err = deserializeJson(arr, "[\"hello\"//COMMENT\n,\"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -272,7 +295,8 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("After comma") { - JsonError err = deserializeJson(arr, "[\"hello\",//COMMENT\n\"world\"]"); + JsonError err = deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(2 == arr.size()); @@ -281,57 +305,55 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Invalid comment") { - JsonError err = deserializeJson(arr, "[/COMMENT\n]"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[/COMMENT\n]"); + REQUIRE(err == JsonError::InvalidInput); } SECTION("End document with comment") { - JsonError err = deserializeJson(arr, "[//COMMENT"); - REQUIRE(err != JsonError::Ok); + JsonError err = deserializeJson(doc, "[//COMMENT"); + REQUIRE(err == JsonError::InvalidInput); } } SECTION("Misc") { SECTION("Garbage") { - JsonError err = deserializeJson(arr, "%*$£¤"); + JsonError err = deserializeJson(doc, "%*$£¤"); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::InvalidInput); } SECTION("The opening bracket is missing") { - JsonError err = deserializeJson(arr, "]"); + JsonError err = deserializeJson(doc, "]"); - REQUIRE(err != JsonError::Ok); // TODO + REQUIRE(err == JsonError::InvalidInput); } SECTION("The closing bracket is missing") { - JsonError err = deserializeJson(arr, "["); - REQUIRE(err != JsonError::Ok); // TODO + JsonError err = deserializeJson(doc, "["); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("Escape sequences") { JsonError err = - deserializeJson(arr, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); + deserializeJson(doc, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); } - SECTION("Unterminated escape sequence") { - JsonError err = deserializeJson(arr, "\"\\\0\"", 4); - REQUIRE(err != JsonError::Ok); - } - SECTION("Nested objects") { char jsonString[] = " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; - JsonError err = deserializeJson(arr, jsonString); + JsonError err = deserializeJson(doc, jsonString); + JsonArray& arr = doc.as(); - JsonObject &object1 = arr[0]; - const JsonObject &object2 = arr[1]; - JsonObject &object3 = arr[2]; + JsonObject& object1 = arr[0]; + const JsonObject& object2 = arr[1]; + JsonObject& object3 = arr[2]; REQUIRE(err == JsonError::Ok); @@ -352,10 +374,11 @@ TEST_CASE("deserializeJson(DynamicJsonArray&)") { } SECTION("Should clear the JsonArray") { - deserializeJson(arr, "[1,2,3,4]"); - deserializeJson(arr, "[]"); + deserializeJson(doc, "[1,2,3,4]"); + deserializeJson(doc, "[]"); + JsonArray& arr = doc.as(); REQUIRE(arr.size() == 0); - REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); + REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); } } diff --git a/test/JsonDeserializer/deserializeJsonArrayStatic.cpp b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp new file mode 100644 index 000000000..45da9c03f --- /dev/null +++ b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp @@ -0,0 +1,105 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserialize JSON array with a StaticJsonDocument") { + SECTION("BufferOfTheRightSizeForEmptyArray") { + StaticJsonDocument doc; + char input[] = "[]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("TooSmallBufferForArrayWithOneValue") { + StaticJsonDocument doc; + char input[] = "[1]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("BufferOfTheRightSizeForArrayWithOneValue") { + StaticJsonDocument doc; + char input[] = "[1]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("TooSmallBufferForArrayWithNestedObject") { + StaticJsonDocument doc; + char input[] = "[{}]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { + StaticJsonDocument doc; + char input[] = "[{}]"; + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("CharPtrNull") { + StaticJsonDocument<100> doc; + + JsonError err = deserializeJson(doc, static_cast(0)); + + REQUIRE(err != JsonError::Ok); + } + + SECTION("ConstCharPtrNull") { + StaticJsonDocument<100> doc; + + JsonError err = deserializeJson(doc, static_cast(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 doc; + char input[] = "[1,2,3,4]"; + + deserializeJson(doc, input); + deserializeJson(doc, "[]"); + + JsonArray& arr = doc.as(); + REQUIRE(arr.size() == 0); + REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(0)); + } + + SECTION("Array") { + StaticJsonDocument doc; + char input[] = "[1,2]"; + + JsonError err = deserializeJson(doc, input); + JsonArray& arr = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); + REQUIRE(arr[0] == 1); + REQUIRE(arr[1] == 2); + } +} diff --git a/test/JsonParser/DynamicJsonObject.cpp b/test/JsonDeserializer/deserializeJsonObject.cpp similarity index 52% rename from test/JsonParser/DynamicJsonObject.cpp rename to test/JsonDeserializer/deserializeJsonObject.cpp index 72e6d2c50..f44a8e053 100644 --- a/test/JsonParser/DynamicJsonObject.cpp +++ b/test/JsonDeserializer/deserializeJsonObject.cpp @@ -5,40 +5,55 @@ #include #include -TEST_CASE("deserializeJson(DynamicJsonObject&)") { - DynamicJsonObject obj; +TEST_CASE("deserialize JSON object") { + DynamicJsonDocument doc; SECTION("An empty object") { - JsonError err = deserializeJson(obj, "{}"); + JsonError err = deserializeJson(doc, "{}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 0); } SECTION("Quotes") { SECTION("Double quotes") { - JsonError err = deserializeJson(obj, "{\"key\":\"value\"}"); + JsonError err = deserializeJson(doc, "{\"key\":\"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Single quotes") { - JsonError err = deserializeJson(obj, "{'key':'value'}"); + JsonError err = deserializeJson(doc, "{'key':'value'}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes") { - JsonError err = deserializeJson(obj, "{key:value}"); + JsonError err = deserializeJson(doc, "{key:value}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes, allow underscore in key") { - JsonError err = deserializeJson(obj, "{_k_e_y_:42}"); + JsonError err = deserializeJson(doc, "{_k_e_y_:42}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["_k_e_y_"] == 42); } @@ -46,37 +61,52 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("Spaces") { SECTION("Before the key") { - JsonError err = deserializeJson(obj, "{ \"key\":\"value\"}"); + JsonError err = deserializeJson(doc, "{ \"key\":\"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the key") { - JsonError err = deserializeJson(obj, "{\"key\" :\"value\"}"); + JsonError err = deserializeJson(doc, "{\"key\" :\"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the value") { - JsonError err = deserializeJson(obj, "{\"key\": \"value\"}"); + JsonError err = deserializeJson(doc, "{\"key\": \"value\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the value") { - JsonError err = deserializeJson(obj, "{\"key\":\"value\" }"); + JsonError err = deserializeJson(doc, "{\"key\":\"value\" }"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the colon") { JsonError err = - deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); @@ -84,8 +114,11 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("After the colon") { JsonError err = - deserializeJson(obj, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); @@ -95,53 +128,69 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("Values types") { SECTION("String") { JsonError err = - deserializeJson(obj, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); + deserializeJson(doc, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); REQUIRE(obj["key2"] == "value2"); } SECTION("Integer") { - JsonError err = deserializeJson(obj, "{\"key1\":42,\"key2\":-42}"); + JsonError err = deserializeJson(doc, "{\"key1\":42,\"key2\":-42}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 42); REQUIRE(obj["key2"] == -42); } SECTION("Double") { - JsonError err = deserializeJson(obj, "{\"key1\":12.345,\"key2\":-7E89}"); + JsonError err = deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 12.345); REQUIRE(obj["key2"] == -7E89); } SECTION("Booleans") { - JsonError err = deserializeJson(obj, "{\"key1\":true,\"key2\":false}"); + JsonError err = deserializeJson(doc, "{\"key1\":true,\"key2\":false}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == true); REQUIRE(obj["key2"] == false); } SECTION("Null") { - JsonError err = deserializeJson(obj, "{\"key1\":null,\"key2\":null}"); + JsonError err = deserializeJson(doc, "{\"key1\":null,\"key2\":null}"); + JsonObject& obj = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); REQUIRE(obj.size() == 2); - REQUIRE(obj["key1"].as() == 0); - REQUIRE(obj["key2"].as() == 0); + REQUIRE(obj["key1"].as() == 0); + REQUIRE(obj["key2"].as() == 0); } SECTION("Array") { char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; - JsonError err = deserializeJson(obj, jsonString); + JsonError err = deserializeJson(doc, jsonString); + JsonObject& obj = doc.as(); - JsonArray &array1 = obj["ab"]; - const JsonArray &array2 = obj["cd"]; - JsonArray &array3 = obj["ef"]; + JsonArray& array1 = obj["ab"]; + const JsonArray& array2 = obj["cd"]; + JsonArray& array3 = obj["ef"]; REQUIRE(err == JsonError::Ok); @@ -165,40 +214,49 @@ TEST_CASE("deserializeJson(DynamicJsonObject&)") { SECTION("Misc") { SECTION("The opening brace is missing") { - JsonError err = deserializeJson(obj, "}"); - REQUIRE(err == JsonError::OpeningBraceExpected); + JsonError err = deserializeJson(doc, "}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("The closing brace is missing") { - JsonError err = deserializeJson(obj, "{\"hello\":\"world\""); - REQUIRE(err == JsonError::ClosingBraceExpected); + JsonError err = deserializeJson(doc, "{\"hello\":\"world\""); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("A quoted key without value") { - JsonError err = deserializeJson(obj, "{\"key\"}"); - REQUIRE(err == JsonError::ColonExpected); + JsonError err = deserializeJson(doc, "{\"key\"}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("A non-quoted key without value") { - JsonError err = deserializeJson(obj, "{key}"); - REQUIRE(err == JsonError::ColonExpected); + JsonError err = deserializeJson(doc, "{key}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("A dangling comma") { - JsonError err = deserializeJson(obj, "{\"key1\":\"value1\",}"); - REQUIRE(err == JsonError::ColonExpected); + JsonError err = deserializeJson(doc, "{\"key1\":\"value1\",}"); + + REQUIRE(err == JsonError::InvalidInput); } SECTION("null as a key") { - JsonError err = deserializeJson(obj, "{null:\"value\"}"); + JsonError err = deserializeJson(doc, "{null:\"value\"}"); + REQUIRE(err == JsonError::Ok); } } SECTION("Should clear the JsonObject") { - deserializeJson(obj, "{\"hello\":\"world\"}"); - deserializeJson(obj, "{}"); + deserializeJson(doc, "{\"hello\":\"world\"}"); + deserializeJson(doc, "{}"); + JsonObject& obj = doc.as(); + + REQUIRE(doc.is()); REQUIRE(obj.size() == 0); - REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); } } diff --git a/test/JsonParser/StaticJsonObject.cpp b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp similarity index 50% rename from test/JsonParser/StaticJsonObject.cpp rename to test/JsonDeserializer/deserializeJsonObjectStatic.cpp index 525f5184f..ab44b2a18 100644 --- a/test/JsonParser/StaticJsonObject.cpp +++ b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp @@ -5,76 +5,76 @@ #include #include -TEST_CASE("deserializeJson(StaticJsonObject&)") { +TEST_CASE("deserialize JSON object with StaticJsonDocument") { SECTION("BufferOfTheRightSizeForEmptyObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithOneValue") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":1}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithOneValue") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":1}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err == JsonError::Ok); } SECTION("TooSmallBufferForObjectWithNestedObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":[]}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err != JsonError::Ok); } SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"a\":[]}"; - JsonError err = deserializeJson(obj, input); + JsonError err = deserializeJson(doc, input); REQUIRE(err == JsonError::Ok); } SECTION("CharPtrNull") { - StaticJsonObject<100> obj; + StaticJsonDocument<100> doc; - JsonError err = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(doc, static_cast(0)); REQUIRE(err != JsonError::Ok); } SECTION("ConstCharPtrNull") { - StaticJsonObject<100> obj; + StaticJsonDocument<100> doc; - JsonError err = deserializeJson(obj, static_cast(0)); + JsonError err = deserializeJson(doc, static_cast(0)); REQUIRE(err != JsonError::Ok); } SECTION("Should clear the JsonObject") { - StaticJsonObject obj; + StaticJsonDocument doc; char input[] = "{\"hello\":\"world\"}"; - deserializeJson(obj, input); - deserializeJson(obj, "{}"); + deserializeJson(doc, input); + deserializeJson(doc, "{}"); - REQUIRE(obj.size() == 0); - REQUIRE(obj.memoryUsage() == JSON_OBJECT_SIZE(0)); + REQUIRE(doc.as().size() == 0); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); } } diff --git a/test/JsonDeserializer/deserializeJsonValue.cpp b/test/JsonDeserializer/deserializeJsonValue.cpp new file mode 100644 index 000000000..4d374d5cf --- /dev/null +++ b/test/JsonDeserializer/deserializeJsonValue.cpp @@ -0,0 +1,103 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +using namespace Catch::Matchers; + +TEST_CASE("deserializeJson(DynamicJsonDocument&)") { + DynamicJsonDocument doc; + + SECTION("EmptyObject") { + JsonError err = deserializeJson(doc, "{}"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + } + + SECTION("EmptyArray") { + JsonError err = deserializeJson(doc, "[]"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + } + + SECTION("Integer") { + JsonError err = deserializeJson(doc, "-42"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE_FALSE(doc.is()); + REQUIRE(doc.as() == -42); + } + + SECTION("Double") { + JsonError err = deserializeJson(doc, "-1.23e+4"); + + REQUIRE(err == JsonError::Ok); + REQUIRE_FALSE(doc.is()); + REQUIRE(doc.is()); + REQUIRE(doc.as() == Approx(-1.23e+4)); + } + + SECTION("Double quoted string") { + JsonError err = deserializeJson(doc, "\"hello world\""); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE_THAT(doc.as(), Equals("hello world")); + } + + SECTION("Single quoted string") { + JsonError err = deserializeJson(doc, "\'hello world\'"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE_THAT(doc.as(), Equals("hello world")); + } + + SECTION("True") { + JsonError err = deserializeJson(doc, "true"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == true); + } + + SECTION("False") { + JsonError err = deserializeJson(doc, "false"); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.is()); + REQUIRE(doc.as() == 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()); + REQUIRE_THAT(doc.as(), 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()); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + } +} diff --git a/test/JsonDeserializer/nestingLimit.cpp b/test/JsonDeserializer/nestingLimit.cpp new file mode 100644 index 000000000..0eecb4ff4 --- /dev/null +++ b/test/JsonDeserializer/nestingLimit.cpp @@ -0,0 +1,32 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +#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)); + } +} diff --git a/test/JsonObject/basics.cpp b/test/JsonObject/basics.cpp index a5e584580..6a9f4e6c0 100644 --- a/test/JsonObject/basics.cpp +++ b/test/JsonObject/basics.cpp @@ -6,13 +6,10 @@ #include TEST_CASE("JsonObject basics") { - DynamicJsonObject _object; - - SECTION("InitialSizeIsZero") { - REQUIRE(0 == _object.size()); - } + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("SuccessIsTrue") { - REQUIRE(_object.success()); + REQUIRE(obj.success()); } } diff --git a/test/JsonObject/containsKey.cpp b/test/JsonObject/containsKey.cpp index c28d11e03..71e22ad44 100644 --- a/test/JsonObject/containsKey.cpp +++ b/test/JsonObject/containsKey.cpp @@ -6,24 +6,25 @@ #include TEST_CASE("JsonObject::containsKey()") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("ContainsKeyReturnsFalseForNonExistingKey") { - _object.set("hello", 42); + obj.set("hello", 42); - REQUIRE(false == _object.containsKey("world")); + REQUIRE(false == obj.containsKey("world")); } SECTION("ContainsKeyReturnsTrueForDefinedValue") { - _object.set("hello", 42); + obj.set("hello", 42); - REQUIRE(true == _object.containsKey("hello")); + REQUIRE(true == obj.containsKey("hello")); } SECTION("ContainsKeyReturnsFalseAfterRemove") { - _object.set("hello", 42); - _object.remove("hello"); + obj.set("hello", 42); + obj.remove("hello"); - REQUIRE(false == _object.containsKey("hello")); + REQUIRE(false == obj.containsKey("hello")); } } diff --git a/test/JsonObject/get.cpp b/test/JsonObject/get.cpp index d1fb8317b..ec6ed4ea9 100644 --- a/test/JsonObject/get.cpp +++ b/test/JsonObject/get.cpp @@ -8,7 +8,8 @@ using namespace Catch::Matchers; TEST_CASE("JsonObject::get()") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("GetConstCharPointer_GivenStringLiteral") { obj.set("hello", "world"); diff --git a/test/JsonObject/iterator.cpp b/test/JsonObject/iterator.cpp index 661f27d8c..306d1986f 100644 --- a/test/JsonObject/iterator.cpp +++ b/test/JsonObject/iterator.cpp @@ -8,7 +8,8 @@ using namespace Catch::Matchers; TEST_CASE("JsonObject::begin()/end()") { - StaticJsonObject obj; + StaticJsonDocument doc; + JsonObject& obj = doc.to(); obj["ab"] = 12; obj["cd"] = 34; diff --git a/test/JsonObject/remove.cpp b/test/JsonObject/remove.cpp index 4048ebd53..395e6b509 100644 --- a/test/JsonObject/remove.cpp +++ b/test/JsonObject/remove.cpp @@ -7,7 +7,8 @@ #include TEST_CASE("JsonObject::remove()") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("SizeDecreased_WhenValuesAreRemoved") { obj["hello"] = 1; @@ -26,7 +27,9 @@ TEST_CASE("JsonObject::remove()") { } SECTION("RemoveByIterator") { - deserializeJson(obj, "{\"a\":0,\"b\":1,\"c\":2}"); + obj["a"] = 0; + obj["b"] = 1; + obj["c"] = 2; for (JsonObject::iterator it = obj.begin(); it != obj.end(); ++it) { if (it->value == 1) obj.remove(it); diff --git a/test/JsonObject/set.cpp b/test/JsonObject/set.cpp index fbc32ee6f..25406c9d8 100644 --- a/test/JsonObject/set.cpp +++ b/test/JsonObject/set.cpp @@ -7,129 +7,136 @@ #include TEST_CASE("JsonObject::set()") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("int") { - _object.set("hello", 123); + obj.set("hello", 123); - REQUIRE(123 == _object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(123 == obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("double") { - _object.set("hello", 123.45); + obj.set("hello", 123.45); - REQUIRE(123.45 == _object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(123.45 == obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("bool") { - _object.set("hello", true); + obj.set("hello", true); - REQUIRE(_object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("const char*") { - _object.set("hello", "h3110"); + obj.set("hello", "h3110"); - REQUIRE(std::string("h3110") == _object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(std::string("h3110") == obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("nested array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); - _object.set("hello", arr); + obj.set("hello", arr); - REQUIRE(&arr == &_object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(&arr == &obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("nested object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - _object.set("hello", obj); + obj.set("hello", obj2); - REQUIRE(&obj == &_object["hello"].as()); - REQUIRE(_object["hello"].is()); - REQUIRE_FALSE(_object["hello"].is()); + REQUIRE(&obj2 == &obj["hello"].as()); + REQUIRE(obj["hello"].is()); + REQUIRE_FALSE(obj["hello"].is()); } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add(42); - _object.set("a", arr[0]); + obj.set("a", arr[0]); - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("object subscript") { - DynamicJsonObject obj; - obj.set("x", 42); + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); + obj2.set("x", 42); - _object.set("a", obj["x"]); + obj.set("a", obj2["x"]); - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("returns true when allocation succeeds") { - StaticJsonObject obj; + StaticJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - REQUIRE(true == obj.set(std::string("hello"), std::string("world"))); + REQUIRE(true == obj2.set(std::string("hello"), std::string("world"))); } SECTION("returns false when allocation fails") { - StaticJsonObject obj; + StaticJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - REQUIRE(false == obj.set(std::string("hello"), std::string("world"))); + REQUIRE(false == obj2.set(std::string("hello"), std::string("world"))); } SECTION("should not duplicate const char*") { - _object.set("hello", "world"); + obj.set("hello", "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* value") { - _object.set("hello", const_cast("world")); + obj.set("hello", const_cast("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key") { - _object.set(const_cast("hello"), "world"); + obj.set(const_cast("hello"), "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key&value") { - _object.set(const_cast("hello"), const_cast("world")); + obj.set(const_cast("hello"), const_cast("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } SECTION("should duplicate std::string value") { - _object.set("hello", std::string("world")); + obj.set("hello", std::string("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key") { - _object.set(std::string("hello"), "world"); + obj.set(std::string("hello"), "world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key&value") { - _object.set(std::string("hello"), std::string("world")); + obj.set(std::string("hello"), std::string("world")); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } } diff --git a/test/JsonObject/size.cpp b/test/JsonObject/size.cpp index ee3b413f8..5f6f0f2ab 100644 --- a/test/JsonObject/size.cpp +++ b/test/JsonObject/size.cpp @@ -7,16 +7,21 @@ #include TEST_CASE("JsonObject::size()") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + + SECTION("initial size is zero") { + REQUIRE(0 == obj.size()); + } SECTION("increases when values are added") { - _object.set("hello", 42); - REQUIRE(1 == _object.size()); + obj.set("hello", 42); + REQUIRE(1 == obj.size()); } SECTION("doesn't increase when the smae key is added twice") { - _object["hello"] = 1; - _object["hello"] = 2; - REQUIRE(1 == _object.size()); + obj["hello"] = 1; + obj["hello"] = 2; + REQUIRE(1 == obj.size()); } } diff --git a/test/JsonObject/subscript.cpp b/test/JsonObject/subscript.cpp index aecfb0ce7..1ac365cd6 100644 --- a/test/JsonObject/subscript.cpp +++ b/test/JsonObject/subscript.cpp @@ -6,146 +6,150 @@ #include TEST_CASE("JsonObject::operator[]") { - DynamicJsonObject _object; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); SECTION("int") { - _object["hello"] = 123; + obj["hello"] = 123; - REQUIRE(123 == _object["hello"].as()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(123 == obj["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("volatile int") { // issue #415 volatile int i = 123; - _object["hello"] = i; + obj["hello"] = i; - REQUIRE(123 == _object["hello"].as()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(123 == obj["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("double") { - _object["hello"] = 123.45; + obj["hello"] = 123.45; - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); - REQUIRE(123.45 == _object["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); + REQUIRE(123.45 == obj["hello"].as()); } SECTION("bool") { - _object["hello"] = true; + obj["hello"] = true; - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); - REQUIRE(true == _object["hello"].as()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); + REQUIRE(true == obj["hello"].as()); } SECTION("const char*") { - _object["hello"] = "h3110"; + obj["hello"] = "h3110"; - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); - REQUIRE(std::string("h3110") == _object["hello"].as()); - REQUIRE(std::string("h3110") == - _object["hello"].as()); // <- short hand + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); + REQUIRE(std::string("h3110") == obj["hello"].as()); + REQUIRE(std::string("h3110") == obj["hello"].as()); // <- short hand } SECTION("array") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); - _object["hello"] = arr; + obj["hello"] = arr; - REQUIRE(&arr == &_object["hello"].as()); - REQUIRE(&arr == &_object["hello"].as()); // <- short hand - REQUIRE(&arr == &_object["hello"].as()); - REQUIRE(&arr == &_object["hello"].as()); // <- short hand - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(&arr == &obj["hello"].as()); + REQUIRE(&arr == &obj["hello"].as()); // <- short hand + REQUIRE(&arr == &obj["hello"].as()); + REQUIRE(&arr == &obj["hello"].as()); // <- short hand + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("object") { - DynamicJsonObject obj; + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); - _object["hello"] = obj; + obj["hello"] = obj2; - REQUIRE(&obj == &_object["hello"].as()); - REQUIRE(&obj == &_object["hello"].as()); // <- short hand - REQUIRE(&obj == &_object["hello"].as()); - REQUIRE(&obj == &_object["hello"].as()); // <- short hand - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(true == _object["hello"].is()); - REQUIRE(false == _object["hello"].is()); + REQUIRE(&obj2 == &obj["hello"].as()); + REQUIRE(&obj2 == &obj["hello"].as()); // <- short hand + REQUIRE(&obj2 == &obj["hello"].as()); + REQUIRE(&obj2 == &obj["hello"].as()); // <- short hand + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(true == obj["hello"].is()); + REQUIRE(false == obj["hello"].is()); } SECTION("array subscript") { - DynamicJsonArray arr; + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); arr.add(42); - _object["a"] = arr[0]; + obj["a"] = arr[0]; - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("object subscript") { - DynamicJsonObject obj; - obj.set("x", 42); + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); + obj2.set("x", 42); - _object["a"] = obj["x"]; + obj["a"] = obj2["x"]; - REQUIRE(42 == _object["a"]); + REQUIRE(42 == obj["a"]); } SECTION("char key[]") { // issue #423 char key[] = "hello"; - _object[key] = 42; - REQUIRE(42 == _object[key]); + obj[key] = 42; + REQUIRE(42 == obj[key]); } SECTION("should not duplicate const char*") { - _object["hello"] = "world"; + obj["hello"] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1); - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* value") { - _object["hello"] = const_cast("world"); + obj["hello"] = const_cast("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key") { - _object[const_cast("hello")] = "world"; + obj[const_cast("hello")] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate char* key&value") { - _object[const_cast("hello")] = const_cast("world"); + obj[const_cast("hello")] = const_cast("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } SECTION("should duplicate std::string value") { - _object["hello"] = std::string("world"); + obj["hello"] = std::string("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key") { - _object[std::string("hello")] = "world"; + obj[std::string("hello")] = "world"; const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; - REQUIRE(expectedSize == _object.memoryUsage()); + REQUIRE(expectedSize == doc.memoryUsage()); } SECTION("should duplicate std::string key&value") { - _object[std::string("hello")] = std::string("world"); + obj[std::string("hello")] = std::string("world"); const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; - REQUIRE(expectedSize <= _object.memoryUsage()); + REQUIRE(expectedSize <= doc.memoryUsage()); } } diff --git a/test/JsonParser/CMakeLists.txt b/test/JsonParser/CMakeLists.txt deleted file mode 100644 index 35f8e57c2..000000000 --- a/test/JsonParser/CMakeLists.txt +++ /dev/null @@ -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) diff --git a/test/JsonParser/DynamicJsonVariant.cpp b/test/JsonParser/DynamicJsonVariant.cpp deleted file mode 100644 index 50449d9a5..000000000 --- a/test/JsonParser/DynamicJsonVariant.cpp +++ /dev/null @@ -1,98 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -using namespace Catch::Matchers; - -TEST_CASE("deserializeJson(DynamicJsonVariant&)") { - DynamicJsonVariant variant; - - SECTION("EmptyObject") { - JsonError err = deserializeJson(variant, "{}"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - } - - SECTION("EmptyArray") { - JsonError err = deserializeJson(variant, "[]"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - } - - SECTION("Integer") { - JsonError err = deserializeJson(variant, "-42"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE_FALSE(variant.is()); - REQUIRE(variant == -42); - } - - SECTION("Double") { - JsonError err = deserializeJson(variant, "-1.23e+4"); - - REQUIRE(err == JsonError::Ok); - REQUIRE_FALSE(variant.is()); - REQUIRE(variant.is()); - REQUIRE(variant.as() == Approx(-1.23e+4)); - } - - SECTION("Double quoted string") { - JsonError err = deserializeJson(variant, "\"hello world\""); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE_THAT(variant.as(), Equals("hello world")); - } - - SECTION("Single quoted string") { - JsonError err = deserializeJson(variant, "\'hello world\'"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE_THAT(variant.as(), Equals("hello world")); - } - - SECTION("True") { - JsonError err = deserializeJson(variant, "true"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE(variant == true); - } - - SECTION("False") { - JsonError err = deserializeJson(variant, "false"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - 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()); - REQUIRE_THAT(variant.as(), Equals("hello")); - } - - SECTION("Should clear the JsonVariant") { - deserializeJson(variant, "[1,2,3]"); - deserializeJson(variant, "{}"); - - REQUIRE(variant.is()); - REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); - } -} diff --git a/test/JsonParser/StaticJsonArray.cpp b/test/JsonParser/StaticJsonArray.cpp deleted file mode 100644 index 3a79749b3..000000000 --- a/test/JsonParser/StaticJsonArray.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -TEST_CASE("deserializeJson(StaticJsonArray&)") { - SECTION("BufferOfTheRightSizeForEmptyArray") { - StaticJsonArray arr; - char input[] = "[]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err == JsonError::Ok); - } - - SECTION("TooSmallBufferForArrayWithOneValue") { - StaticJsonArray arr; - char input[] = "[1]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("BufferOfTheRightSizeForArrayWithOneValue") { - StaticJsonArray arr; - char input[] = "[1]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err == JsonError::Ok); - } - - SECTION("TooSmallBufferForArrayWithNestedObject") { - StaticJsonArray arr; - char input[] = "[{}]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { - StaticJsonArray arr; - char input[] = "[{}]"; - - JsonError err = deserializeJson(arr, input); - - REQUIRE(err == JsonError::Ok); - } - - SECTION("CharPtrNull") { - StaticJsonArray<100> arr; - - JsonError err = deserializeJson(arr, static_cast(0)); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("ConstCharPtrNull") { - StaticJsonArray<100> arr; - - JsonError err = deserializeJson(arr, static_cast(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 arr; - char input[] = "[1,2,3,4]"; - - deserializeJson(arr, input); - deserializeJson(arr, "[]"); - - REQUIRE(arr.size() == 0); - REQUIRE(arr.memoryUsage() == JSON_ARRAY_SIZE(0)); - } -} diff --git a/test/JsonParser/StaticJsonVariant.cpp b/test/JsonParser/StaticJsonVariant.cpp deleted file mode 100644 index a3fba6e10..000000000 --- a/test/JsonParser/StaticJsonVariant.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -using namespace Catch::Matchers; - -TEST_CASE("deserializeJson(StaticJsonVariant&)") { - SECTION("Array") { - StaticJsonVariant variant; - - char input[] = "[1,2]"; - JsonError err = deserializeJson(variant, input); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE(variant[0] == 1); - REQUIRE(variant[1] == 2); - REQUIRE(variant.memoryUsage() == JSON_ARRAY_SIZE(2)); - } - - SECTION("Should clear the JsonVariant") { - StaticJsonVariant variant; - char input[] = "[1,2]"; - deserializeJson(variant, input); - - JsonError err = deserializeJson(variant, "{}"); - - REQUIRE(err == JsonError::Ok); - REQUIRE(variant.is()); - REQUIRE(variant.memoryUsage() == JSON_OBJECT_SIZE(0)); - } -} diff --git a/test/JsonParser/nestingLimit.cpp b/test/JsonParser/nestingLimit.cpp deleted file mode 100644 index 741489563..000000000 --- a/test/JsonParser/nestingLimit.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -#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)); - } - } -} diff --git a/test/JsonSerializer/JsonArray.cpp b/test/JsonSerializer/JsonArray.cpp index ced91238a..1556b495c 100644 --- a/test/JsonSerializer/JsonArray.cpp +++ b/test/JsonSerializer/JsonArray.cpp @@ -15,7 +15,8 @@ static void check(JsonArray &array, std::string expected) { } TEST_CASE("serializeJson(JsonArray)") { - StaticJsonArray array; + StaticJsonDocument doc; + JsonArray &array = doc.to(); SECTION("Empty") { check(array, "[]"); diff --git a/test/JsonSerializer/JsonArrayPretty.cpp b/test/JsonSerializer/JsonArrayPretty.cpp index 4785d6433..fc3af2e47 100644 --- a/test/JsonSerializer/JsonArrayPretty.cpp +++ b/test/JsonSerializer/JsonArrayPretty.cpp @@ -15,7 +15,8 @@ static void check(JsonArray& array, std::string expected) { } TEST_CASE("serializeJsonPretty(JsonArray)") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); SECTION("Empty") { check(array, "[]"); diff --git a/test/JsonSerializer/JsonObject.cpp b/test/JsonSerializer/JsonObject.cpp index 25476928a..3674b1b8b 100644 --- a/test/JsonSerializer/JsonObject.cpp +++ b/test/JsonSerializer/JsonObject.cpp @@ -17,7 +17,8 @@ void check(const JsonObject &obj, const std::string &expected) { } TEST_CASE("serializeJson(JsonObject)") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject &obj = doc.to(); SECTION("EmptyObject") { check(obj, "{}"); @@ -92,22 +93,23 @@ TEST_CASE("serializeJson(JsonObject)") { } SECTION("ThreeNestedArrays") { - DynamicJsonArray b, c; + DynamicJsonDocument b; + DynamicJsonDocument c; obj.createNestedArray("a"); - obj["b"] = b; - obj.set("c", c); + obj["b"] = b.to(); + obj.set("c", c.to()); check(obj, "{\"a\":[],\"b\":[],\"c\":[]}"); } SECTION("ThreeNestedObjects") { - DynamicJsonObject b; - DynamicJsonObject c; + DynamicJsonDocument b; + DynamicJsonDocument c; obj.createNestedObject("a"); - obj["b"] = b; - obj.set("c", c); + obj["b"] = b.to(); + obj.set("c", c.to()); check(obj, "{\"a\":{},\"b\":{},\"c\":{}}"); } diff --git a/test/JsonSerializer/JsonObjectPretty.cpp b/test/JsonSerializer/JsonObjectPretty.cpp index efcc947e4..ec3ef14b1 100644 --- a/test/JsonSerializer/JsonObjectPretty.cpp +++ b/test/JsonSerializer/JsonObjectPretty.cpp @@ -18,7 +18,8 @@ void check(const JsonObject &obj, const std::string expected) { } TEST_CASE("serializeJsonPretty(JsonObject)") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject &obj = doc.to(); SECTION("EmptyObject") { check(obj, "{}"); diff --git a/test/JsonVariant/as.cpp b/test/JsonVariant/as.cpp index bf03b1b65..8254b101d 100644 --- a/test/JsonVariant/as.cpp +++ b/test/JsonVariant/as.cpp @@ -192,7 +192,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ObjectAsString") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["key"] = "value"; @@ -201,7 +202,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ArrayAsString") { - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add(4); arr.add(2); @@ -210,7 +212,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ArrayAsJsonArray") { - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); JsonVariant variant = arr; REQUIRE(&arr == &variant.as()); @@ -218,7 +221,8 @@ TEST_CASE("JsonVariant::as()") { } SECTION("ObjectAsJsonObject") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); JsonVariant variant = obj; REQUIRE(&obj == &variant.as()); diff --git a/test/JsonVariant/compare.cpp b/test/JsonVariant/compare.cpp index 0364ec443..85010a5e8 100644 --- a/test/JsonVariant/compare.cpp +++ b/test/JsonVariant/compare.cpp @@ -97,8 +97,9 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("StringLiteral") { - DynamicJsonVariant variant; - deserializeJson(variant, "\"hello\""); + DynamicJsonDocument doc; + deserializeJson(doc, "\"hello\""); + JsonVariant variant = doc.as(); REQUIRE(variant == "hello"); REQUIRE_FALSE(variant != "hello"); @@ -114,8 +115,7 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("String") { - DynamicJsonVariant variant; - deserializeJson(variant, "\"hello\""); + JsonVariant variant = "hello"; REQUIRE(variant == std::string("hello")); REQUIRE_FALSE(variant != std::string("hello")); @@ -179,7 +179,10 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("ArrayInVariant") { - DynamicJsonArray array1, array2; + DynamicJsonDocument doc1; + JsonArray& array1 = doc1.to(); + DynamicJsonDocument doc2; + JsonArray& array2 = doc2.to(); JsonVariant variant1 = array1; JsonVariant variant2 = array1; @@ -193,8 +196,10 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("ObjectInVariant") { - DynamicJsonObject obj1; - DynamicJsonObject obj2; + DynamicJsonDocument doc1; + JsonObject& obj1 = doc1.to(); + DynamicJsonDocument doc2; + JsonObject& obj2 = doc2.to(); JsonVariant variant1 = obj1; JsonVariant variant2 = obj1; @@ -208,8 +213,11 @@ TEST_CASE("JsonVariant comparisons") { } SECTION("VariantsOfDifferentTypes") { - DynamicJsonObject obj; - DynamicJsonArray arr; + DynamicJsonDocument doc1; + JsonObject& obj = doc1.to(); + + DynamicJsonDocument doc2; + JsonArray& arr = doc2.to(); JsonVariant variants[] = { true, 42, 666.667, "hello", arr, obj, }; diff --git a/test/JsonVariant/copy.cpp b/test/JsonVariant/copy.cpp index ebd8b90b1..d894f6078 100644 --- a/test/JsonVariant/copy.cpp +++ b/test/JsonVariant/copy.cpp @@ -38,11 +38,12 @@ TEST_CASE("JsonVariant copy") { _variant2 = _variant1; _variant1 = "world"; - REQUIRE(std::string("hello") == _variant2.as()); + REQUIRE(std::string("hello") == _variant2.as()); } SECTION("ObjectsAreCopiedByReference") { - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); _variant1 = object; @@ -52,7 +53,8 @@ TEST_CASE("JsonVariant copy") { } SECTION("ArraysAreCopiedByReference") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); _variant1 = array; diff --git a/test/JsonVariant/is.cpp b/test/JsonVariant/is.cpp index 7ecfdcdf9..d57765535 100644 --- a/test/JsonVariant/is.cpp +++ b/test/JsonVariant/is.cpp @@ -69,10 +69,9 @@ void checkIsString(JsonVariant var) { } TEST_CASE("JsonVariant::is()") { - DynamicJsonBuffer jsonBuffer; - SECTION("JsonArray") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); checkIsArray(array); } diff --git a/test/JsonVariant/set_get.cpp b/test/JsonVariant/set_get.cpp index ef6a09a97..b63775ba4 100644 --- a/test/JsonVariant/set_get.cpp +++ b/test/JsonVariant/set_get.cpp @@ -122,7 +122,8 @@ TEST_CASE("JsonVariant set()/get()") { #endif SECTION("CanStoreObject") { - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject &object = doc.to(); checkReference(object); } diff --git a/test/JsonVariant/subscript.cpp b/test/JsonVariant/subscript.cpp index 122ba47c8..727832921 100644 --- a/test/JsonVariant/subscript.cpp +++ b/test/JsonVariant/subscript.cpp @@ -7,7 +7,8 @@ TEST_CASE("JsonVariant::operator[]") { SECTION("Array") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); array.add("element at index 0"); array.add("element at index 1"); @@ -24,7 +25,8 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("Object") { - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); object["a"] = "element at key \"a\""; object["b"] = "element at key \"b\""; @@ -52,7 +54,8 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("ObjectSetValue") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); JsonVariant var = obj; var["hello"] = "world"; REQUIRE(1 == var.size()); @@ -60,16 +63,19 @@ TEST_CASE("JsonVariant::operator[]") { } SECTION("ArraySetValue") { - DynamicJsonVariant var; - deserializeJson(var, "[\"hello\"]"); + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + JsonVariant var = arr; var[0] = "world"; REQUIRE(1 == var.size()); REQUIRE(std::string("world") == var[0]); } SECTION("NestedObjectSetValue") { - DynamicJsonVariant var; - deserializeJson(var, "[{}]"); + DynamicJsonDocument doc; + deserializeJson(doc, "[{}]"); + JsonVariant var = doc.as(); var[0]["hello"] = "world"; REQUIRE(1 == var.size()); REQUIRE(1 == var[0].size()); diff --git a/test/JsonVariant/success.cpp b/test/JsonVariant/success.cpp index a06fbf236..ecef9ac57 100644 --- a/test/JsonVariant/success.cpp +++ b/test/JsonVariant/success.cpp @@ -17,14 +17,16 @@ TEST_CASE("JsonVariant::success()") { } SECTION("ReturnsTrue_WhenEmptyArray") { - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); JsonVariant variant = array; REQUIRE(true == variant.success()); } SECTION("ReturnsTrue_WhenEmptyObject") { - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); JsonVariant variant = obj; REQUIRE(true == variant.success()); diff --git a/test/Misc/std_stream.cpp b/test/Misc/std_stream.cpp index b2b171a38..5ac6701f9 100644 --- a/test/Misc/std_stream.cpp +++ b/test/Misc/std_stream.cpp @@ -23,7 +23,8 @@ TEST_CASE("std::stream") { SECTION("JsonObject") { std::ostringstream os; - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); object["key"] = "value"; os << object; REQUIRE("{\"key\":\"value\"}" == os.str()); @@ -31,7 +32,8 @@ TEST_CASE("std::stream") { SECTION("JsonObjectSubscript") { std::ostringstream os; - DynamicJsonObject object; + DynamicJsonDocument doc; + JsonObject& object = doc.to(); object["key"] = "value"; os << object["key"]; REQUIRE("\"value\"" == os.str()); @@ -39,7 +41,8 @@ TEST_CASE("std::stream") { SECTION("JsonArray") { std::ostringstream os; - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); array.add("value"); os << array; REQUIRE("[\"value\"]" == os.str()); @@ -47,7 +50,8 @@ TEST_CASE("std::stream") { SECTION("JsonArraySubscript") { std::ostringstream os; - DynamicJsonArray array; + DynamicJsonDocument doc; + JsonArray& array = doc.to(); array.add("value"); os << array[0]; REQUIRE("\"value\"" == os.str()); @@ -55,8 +59,9 @@ TEST_CASE("std::stream") { SECTION("ParseArray") { std::istringstream json(" [ 42 /* comment */ ] "); - DynamicJsonArray arr; - JsonError err = deserializeJson(arr, json); + DynamicJsonDocument doc; + JsonError err = deserializeJson(doc, json); + JsonArray& arr = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == arr.size()); @@ -65,8 +70,9 @@ TEST_CASE("std::stream") { SECTION("ParseObject") { std::istringstream json(" { hello : world // comment\n }"); - DynamicJsonObject obj; - JsonError err = deserializeJson(obj, json); + DynamicJsonDocument doc; + JsonError err = deserializeJson(doc, json); + JsonObject& obj = doc.as(); REQUIRE(err == JsonError::Ok); REQUIRE(1 == obj.size()); @@ -75,8 +81,8 @@ TEST_CASE("std::stream") { SECTION("ShouldNotReadPastTheEnd") { std::istringstream json("{}123"); - DynamicJsonObject obj; - deserializeJson(obj, json); + DynamicJsonDocument doc; + deserializeJson(doc, json); REQUIRE('1' == json.get()); } } diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp index 9e58e0f1a..4765f7078 100644 --- a/test/Misc/std_string.cpp +++ b/test/Misc/std_string.cpp @@ -11,20 +11,21 @@ static void eraseString(std::string &str) { } TEST_CASE("std::string") { - DynamicJsonBuffer jb; + SECTION("deserializeJson duplicates content") { + std::string json("[\"hello\"]"); - SECTION("JsonArray") { - DynamicJsonArray array; - - SECTION("deserializeJson") { - std::string json("[\"hello\"]"); + DynamicJsonDocument doc; + JsonError err = deserializeJson(doc, json); + eraseString(json); - JsonError err = deserializeJson(array, json); - eraseString(json); + JsonArray &array = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(std::string("hello") == array[0]); + } - REQUIRE(err == JsonError::Ok); - REQUIRE(std::string("hello") == array[0]); - } + SECTION("JsonArray") { + DynamicJsonDocument doc; + JsonArray &array = doc.to(); SECTION("add()") { std::string value("hello"); @@ -67,168 +68,190 @@ TEST_CASE("std::string") { } SECTION("JsonObject") { - DynamicJsonObject object; + DynamicJsonDocument doc; SECTION("deserializeJson()") { std::string json("{\"hello\":\"world\"}"); - JsonError err = deserializeJson(object, json); + JsonError err = deserializeJson(doc, json); + JsonObject &obj = doc.as(); eraseString(json); REQUIRE(err == JsonError::Ok); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("operator[]") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); - REQUIRE(std::string("value") == object[std::string("key")]); + REQUIRE(std::string("value") == obj[std::string("key")]); } SECTION("operator[] const") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - const JsonObject &obj = object; + deserializeJson(doc, json); + JsonObject &obj = doc.as(); REQUIRE(std::string("value") == obj[std::string("key")]); } SECTION("set(key)") { + JsonObject &obj = doc.to(); std::string key("hello"); - object.set(key, "world"); + obj.set(key, "world"); eraseString(key); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(value)") { + JsonObject &obj = doc.to(); std::string value("world"); - object.set("hello", value); + obj.set("hello", value); eraseString(value); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(key,value)") { + JsonObject &obj = doc.to(); std::string key("hello"); std::string value("world"); - object.set(key, value); + obj.set(key, value); eraseString(key); eraseString(value); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(JsonArraySubscript)") { - DynamicJsonArray arr; + JsonObject &obj = doc.to(); + DynamicJsonDocument doc2; + JsonArray &arr = doc2.to(); arr.add("world"); - object.set(std::string("hello"), arr[0]); + obj.set(std::string("hello"), arr[0]); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("set(JsonObjectSubscript)") { - DynamicJsonObject obj; - obj.set("x", "world"); + JsonObject &obj = doc.to(); + DynamicJsonDocument doc2; + JsonObject &obj2 = doc2.to(); + 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()") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); REQUIRE(std::string("value") == - object.get(std::string("key"))); + obj.get(std::string("key"))); } SECTION("is()") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - REQUIRE(true == object.is(std::string("key"))); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + + REQUIRE(true == obj.is(std::string("key"))); } SECTION("createNestedObject()") { + JsonObject &obj = doc.to(); std::string key = "key"; char json[64]; - object.createNestedObject(key); + obj.createNestedObject(key); eraseString(key); - serializeJson(object, json, sizeof(json)); + serializeJson(doc, json, sizeof(json)); REQUIRE(std::string("{\"key\":{}}") == json); } SECTION("createNestedArray()") { + JsonObject &obj = doc.to(); std::string key = "key"; char json[64]; - object.createNestedArray(key); + obj.createNestedArray(key); eraseString(key); - serializeJson(object, json, sizeof(json)); + serializeJson(doc, json, sizeof(json)); REQUIRE(std::string("{\"key\":[]}") == json); } SECTION("containsKey()") { char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - REQUIRE(true == object.containsKey(std::string("key"))); + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + REQUIRE(true == obj.containsKey(std::string("key"))); } SECTION("remove()") { - char json[] = "{\"key\":\"value\"}"; - deserializeJson(object, json); - REQUIRE(1 == object.size()); - object.remove(std::string("key")); - REQUIRE(0 == object.size()); + JsonObject &obj = doc.to(); + obj["key"] = "value"; + + obj.remove(std::string("key")); + + REQUIRE(0 == obj.size()); } SECTION("operator[], set key") { std::string key("hello"); - object[key] = "world"; + JsonObject &obj = doc.to(); + obj[key] = "world"; eraseString(key); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("operator[], set value") { std::string value("world"); - object["hello"] = value; + JsonObject &obj = doc.to(); + obj["hello"] = value; eraseString(value); - REQUIRE(std::string("world") == object["hello"]); + REQUIRE(std::string("world") == obj["hello"]); } SECTION("serializeJson()") { - object["key"] = "value"; + JsonObject &obj = doc.to(); + obj["key"] = "value"; std::string json; - serializeJson(object, json); + serializeJson(doc, json); REQUIRE(std::string("{\"key\":\"value\"}") == json); } SECTION("serializeJsonPretty()") { - object["key"] = "value"; + JsonObject &obj = doc.to(); + obj["key"] = "value"; std::string json; - serializeJsonPretty(object, json); + serializeJsonPretty(doc, json); REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); } SECTION("memoryUsage() increases when adding a new key") { std::string key1("hello"), key2("world"); + JsonObject &obj = doc.to(); - object[key1] = 1; - size_t sizeBefore = object.memoryUsage(); - object[key2] = 2; - size_t sizeAfter = object.memoryUsage(); + obj[key1] = 1; + size_t sizeBefore = doc.memoryUsage(); + obj[key2] = 2; + size_t sizeAfter = doc.memoryUsage(); REQUIRE(sizeAfter - sizeBefore >= key2.size()); } SECTION("memoryUsage() remains when adding the same key") { std::string key("hello"); + JsonObject &obj = doc.to(); - object[key] = 1; - size_t sizeBefore = object.memoryUsage(); - object[key] = 2; - size_t sizeAfter = object.memoryUsage(); + obj[key] = 1; + size_t sizeBefore = doc.memoryUsage(); + obj[key] = 2; + size_t sizeAfter = doc.memoryUsage(); REQUIRE(sizeBefore == sizeAfter); } diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 23752b9e4..87f3cab63 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -13,8 +13,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonBuffer::parseArray") { unsigned char json[] = "[42]"; - StaticJsonArray arr; - JsonError err = deserializeJson(arr, json); + StaticJsonDocument doc; + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); } @@ -22,8 +22,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonBuffer::parseObject") { unsigned char json[] = "{\"a\":42}"; - StaticJsonObject obj; - JsonError err = deserializeJson(obj, json); + StaticJsonDocument doc; + JsonError err = deserializeJson(doc, json); REQUIRE(err == JsonError::Ok); } @@ -49,8 +49,9 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator[]") { unsigned char key[] = "hello"; - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[key]); } @@ -60,8 +61,9 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator[] const") { unsigned char key[] = "hello"; - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + const JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[key]); } @@ -70,7 +72,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator==") { unsigned char comparand[] = "hello"; - DynamicJsonVariant variant; + JsonVariant variant; variant = "hello"; REQUIRE(comparand == variant); @@ -82,7 +84,7 @@ TEST_CASE("unsigned char string") { SECTION("JsonVariant::operator!=") { unsigned char comparand[] = "hello"; - DynamicJsonVariant variant; + JsonVariant variant; variant = "world"; REQUIRE(comparand != variant); @@ -95,7 +97,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::operator[]") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj[key] = "world"; REQUIRE(std::string("world") == obj["hello"]); @@ -105,7 +108,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObjectSubscript::operator=") { // issue #416 unsigned char value[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"] = value; REQUIRE(std::string("world") == obj["hello"]); @@ -114,7 +118,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObjectSubscript::set()") { unsigned char value[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"].set(value); REQUIRE(std::string("world") == obj["hello"]); @@ -124,9 +129,10 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::operator[] const") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj[key]); } #endif @@ -134,16 +140,17 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::get()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); - + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj.get(key)); } SECTION("JsonObject::set() key") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(key, "world"); REQUIRE(std::string("world") == obj["hello"]); @@ -152,7 +159,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::set() value") { unsigned char value[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set("hello", value); REQUIRE(std::string("world") == obj["hello"]); @@ -161,7 +169,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::set key&value") { unsigned char key[] = "world"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(key, key); REQUIRE(std::string("world") == obj["world"]); @@ -170,17 +179,18 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::containsKey()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); - + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.containsKey(key)); } SECTION("JsonObject::remove()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); obj.remove(key); REQUIRE(0 == obj.size()); @@ -189,8 +199,9 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::is()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":42}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":42}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.is(key)); } @@ -198,21 +209,24 @@ TEST_CASE("unsigned char string") { SECTION("JsonObject::createNestedArray()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedArray(key); } SECTION("JsonObject::createNestedObject()") { unsigned char key[] = "hello"; - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedObject(key); } SECTION("JsonArray::add()") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add(value); REQUIRE(std::string("world") == arr[0]); @@ -221,7 +235,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonArray::set()") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr.set(0, value); @@ -231,7 +246,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonArraySubscript::set()") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0].set(value); @@ -241,7 +257,8 @@ TEST_CASE("unsigned char string") { SECTION("JsonArraySubscript::operator=") { unsigned char value[] = "world"; - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0] = value; diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 98a110d3e..2fd84453b 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -22,8 +22,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "[42]"); - StaticJsonArray arr; - JsonError err = deserializeJson(arr, vla); + StaticJsonDocument doc; + JsonError err = deserializeJson(doc, vla); REQUIRE(err == JsonError::Ok); } @@ -33,10 +33,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "{\"a\":42}"); - StaticJsonObject obj; - deserializeJson(obj, vla); + StaticJsonDocument doc; + JsonError error = deserializeJson(doc, vla); - REQUIRE(true == obj.success()); + REQUIRE(error == JsonError::Ok); } SECTION("Parse") { @@ -44,7 +44,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "42"); - StaticJsonVariant<> variant; + StaticJsonDocument<> variant; deserializeJson(variant, vla); REQUIRE(42 == variant.as()); @@ -77,8 +77,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[vla]); } @@ -90,8 +91,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; - deserializeJson(variant, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + const JsonVariant variant = doc.as(); REQUIRE(std::string("world") == variant[vla]); } @@ -102,7 +104,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; + JsonVariant variant; variant = "hello"; REQUIRE((vla == variant)); @@ -116,7 +118,7 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonVariant variant; + JsonVariant variant; variant = "world"; REQUIRE((vla != variant)); @@ -131,7 +133,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj[vla] = "world"; REQUIRE(std::string("world") == obj["hello"]); @@ -143,7 +146,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"] = vla; REQUIRE(std::string("world") == obj["hello"].as()); @@ -154,7 +158,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj["hello"].set(vla); REQUIRE(std::string("world") == obj["hello"].as()); @@ -166,9 +171,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj[vla]); } #endif @@ -178,9 +184,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(std::string("world") == obj.get(vla)); } @@ -189,7 +196,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(vla, "world"); REQUIRE(std::string("world") == obj["hello"]); @@ -200,7 +208,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set("hello", vla); REQUIRE(std::string("world") == obj["hello"]); @@ -211,7 +220,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.set(vla, vla); REQUIRE(std::string("world") == obj["world"]); @@ -222,9 +232,10 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.containsKey(vla)); } @@ -233,8 +244,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); obj.remove(vla); REQUIRE(0 == obj.size()); @@ -245,8 +257,9 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; - deserializeJson(obj, "{\"hello\":42}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":42}"); + JsonObject& obj = doc.as(); REQUIRE(true == obj.is(vla)); } @@ -256,7 +269,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedArray(vla); } @@ -265,7 +279,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "hello"); - DynamicJsonObject obj; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); obj.createNestedObject(vla); } @@ -274,7 +289,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add(vla); REQUIRE(std::string("world") == arr[0]); @@ -285,7 +301,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr.set(0, vla); @@ -297,7 +314,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0].set(vla); @@ -309,7 +327,8 @@ TEST_CASE("Variable Length Array") { char vla[i]; strcpy(vla, "world"); - DynamicJsonArray arr; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); arr.add("hello"); arr[0] = vla; diff --git a/test/MsgPack/MsgPackError.cpp b/test/MsgPack/MsgPackError.cpp index 8de7c79a6..3f070260b 100644 --- a/test/MsgPack/MsgPackError.cpp +++ b/test/MsgPack/MsgPackError.cpp @@ -24,8 +24,6 @@ TEST_CASE("MsgPackError") { TEST_STRINGIFICATION(Ok); TEST_STRINGIFICATION(NotSupported); TEST_STRINGIFICATION(NoMemory); - TEST_STRINGIFICATION(NotAnArray); - TEST_STRINGIFICATION(NotAnObject); TEST_STRINGIFICATION(TooDeep); } @@ -33,8 +31,12 @@ TEST_CASE("MsgPackError") { TEST_BOOLIFICATION(Ok, false); TEST_BOOLIFICATION(NotSupported, true); TEST_BOOLIFICATION(NoMemory, true); - TEST_BOOLIFICATION(NotAnArray, true); - TEST_BOOLIFICATION(NotAnObject, true); TEST_BOOLIFICATION(TooDeep, true); } + + SECTION("ostream") { + std::stringstream s; + s << MsgPackError::NotSupported; + REQUIRE(s.str() == "NotSupported"); + } } diff --git a/test/MsgPack/deserializationErrors.cpp b/test/MsgPack/deserializationErrors.cpp index 8483674b1..c9e0e94e6 100644 --- a/test/MsgPack/deserializationErrors.cpp +++ b/test/MsgPack/deserializationErrors.cpp @@ -7,7 +7,7 @@ static void check(const char* input, MsgPackError expected, uint8_t nestingLimit = 10) { - DynamicJsonVariant variant; + DynamicJsonDocument variant; MsgPackError error = deserializeMsgPack(variant, input, nestingLimit); diff --git a/test/MsgPack/deserializeArray.cpp b/test/MsgPack/deserializeArray.cpp index a0c492d64..c1b8beed1 100644 --- a/test/MsgPack/deserializeArray.cpp +++ b/test/MsgPack/deserializeArray.cpp @@ -6,21 +6,14 @@ #include TEST_CASE("deserializeMsgPack(JsonArray&)") { - DynamicJsonArray array; - - SECTION("not an array") { - const char* input = "\xA0"; - - MsgPackError error = deserializeMsgPack(array, input); - - REQUIRE(error == MsgPackError::NotAnArray); - } + DynamicJsonDocument doc; SECTION("fixarray") { SECTION("empty") { const char* input = "\x90"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 0); @@ -29,7 +22,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("two integers") { const char* input = "\x92\x01\x02"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 2); @@ -42,7 +36,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("empty") { const char* input = "\xDC\x00\x00"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 0); @@ -51,7 +46,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("two strings") { const char* input = "\xDC\x00\x02\xA5hello\xA5world"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 2); @@ -64,7 +60,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("empty") { const char* input = "\xDD\x00\x00\x00\x00"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 0); @@ -74,7 +71,8 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { const char* input = "\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3"; - MsgPackError error = deserializeMsgPack(array, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonArray& array = doc.as(); REQUIRE(error == MsgPackError::Ok); REQUIRE(array.size() == 2); diff --git a/test/MsgPack/deserializeObject.cpp b/test/MsgPack/deserializeObject.cpp index 508b93bce..9557a28e5 100644 --- a/test/MsgPack/deserializeObject.cpp +++ b/test/MsgPack/deserializeObject.cpp @@ -5,36 +5,32 @@ #include #include -TEST_CASE("deserializeMsgPack(JsonObject&)") { - DynamicJsonObject object; - - SECTION("not an object") { - const char* input = "\xA0"; - - MsgPackError error = deserializeMsgPack(object, input); - - REQUIRE(error == MsgPackError::NotAnObject); - } +TEST_CASE("deserialize MsgPack object") { + DynamicJsonDocument doc; SECTION("fixmap") { SECTION("empty") { const char* input = "\x80"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 0); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 0); } SECTION("two integers") { const char* input = "\x82\xA3one\x01\xA3two\x02"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 2); - REQUIRE(object["one"] == 1); - REQUIRE(object["two"] == 2); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["one"] == 1); + REQUIRE(obj["two"] == 2); } } @@ -42,21 +38,25 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { SECTION("empty") { const char* input = "\xDE\x00\x00"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 0); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 0); } SECTION("two strings") { const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 2); - REQUIRE(object["H"] == "hello"); - REQUIRE(object["W"] == "world"); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["H"] == "hello"); + REQUIRE(obj["W"] == "world"); } } @@ -64,10 +64,12 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { SECTION("empty") { const char* input = "\xDF\x00\x00\x00\x00"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 0); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 0); } SECTION("two floats") { @@ -75,12 +77,14 @@ TEST_CASE("deserializeMsgPack(JsonObject&)") { "\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48" "\xF5\xC3"; - MsgPackError error = deserializeMsgPack(object, input); + MsgPackError error = deserializeMsgPack(doc, input); + JsonObject& obj = doc.as(); REQUIRE(error == MsgPackError::Ok); - REQUIRE(object.size() == 2); - REQUIRE(object["zero"] == 0.0f); - REQUIRE(object["pi"] == 3.14f); + REQUIRE(doc.is()); + REQUIRE(obj.size() == 2); + REQUIRE(obj["zero"] == 0.0f); + REQUIRE(obj["pi"] == 3.14f); } } } diff --git a/test/MsgPack/deserializeStaticVariant.cpp b/test/MsgPack/deserializeStaticVariant.cpp index 01ceb21d9..f4eb831cf 100644 --- a/test/MsgPack/deserializeStaticVariant.cpp +++ b/test/MsgPack/deserializeStaticVariant.cpp @@ -9,14 +9,14 @@ static const size_t epsilon = sizeof(void*); template static void check(const char* input, MsgPackError expected) { - StaticJsonVariant variant; + StaticJsonDocument variant; MsgPackError error = deserializeMsgPack(variant, input); REQUIRE(error == expected); } -TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { +TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") { SECTION("single values always fit") { check<0>("\xc0", MsgPackError::Ok); // nil check<0>("\xc2", MsgPackError::Ok); // false @@ -82,15 +82,14 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { check("\x80", MsgPackError::Ok); } SECTION("{H:1}") { - check("\x81\xA1H\x01", - MsgPackError::NoMemory); + check("\x81\xA1H\x01", MsgPackError::NoMemory); check("\x81\xA1H\x01", MsgPackError::Ok); } SECTION("{H:1,W:2}") { check("\x82\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); - check("\x82\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + MsgPackError::NoMemory); + check("\x82\xA1H\x01\xA1W\x02", + MsgPackError::Ok); } } @@ -101,13 +100,14 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { SECTION("{H:1}") { check("\xDE\x00\x01\xA1H\x01", MsgPackError::NoMemory); - check("\xDE\x00\x01\xA1H\x01", MsgPackError::Ok); + check("\xDE\x00\x01\xA1H\x01", + MsgPackError::Ok); } SECTION("{H:1,W:2}") { check("\xDE\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); - check("\xDE\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + MsgPackError::NoMemory); + check("\xDE\x00\x02\xA1H\x01\xA1W\x02", + MsgPackError::Ok); } } @@ -119,13 +119,13 @@ TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") { check("\xDF\x00\x00\x00\x01\xA1H\x01", MsgPackError::NoMemory); check("\xDF\x00\x00\x00\x01\xA1H\x01", - MsgPackError::Ok); + MsgPackError::Ok); } SECTION("{H:1,W:2}") { - check("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); - check("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + check( + "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::NoMemory); + check( + "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::Ok); } } } diff --git a/test/MsgPack/deserializeVariant.cpp b/test/MsgPack/deserializeVariant.cpp index f25ed8979..25c32c321 100644 --- a/test/MsgPack/deserializeVariant.cpp +++ b/test/MsgPack/deserializeVariant.cpp @@ -7,7 +7,7 @@ template static void check(const char* input, U expected) { - DynamicJsonVariant variant; + DynamicJsonDocument variant; MsgPackError error = deserializeMsgPack(variant, input); @@ -127,151 +127,4 @@ TEST_CASE("deserializeMsgPack(JsonVariant&)") { SECTION("str 32") { check("\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); - } - } } diff --git a/test/StaticJsonBuffer/alloc.cpp b/test/StaticJsonBuffer/alloc.cpp index 9141def82..133871856 100644 --- a/test/StaticJsonBuffer/alloc.cpp +++ b/test/StaticJsonBuffer/alloc.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + static bool isAligned(void *ptr) { const size_t mask = sizeof(void *) - 1; size_t addr = reinterpret_cast(ptr); diff --git a/test/StaticJsonBuffer/size.cpp b/test/StaticJsonBuffer/size.cpp index 5ef76bf4f..88b3dc20f 100644 --- a/test/StaticJsonBuffer/size.cpp +++ b/test/StaticJsonBuffer/size.cpp @@ -2,9 +2,11 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include +using namespace ArduinoJson::Internals; + TEST_CASE("StaticJsonBuffer::size()") { StaticJsonBuffer<64> buffer; From 4c9c047ddf71399039342ed1ff184586252a3f49 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Wed, 18 Apr 2018 21:42:14 +0200 Subject: [PATCH 0027/1079] Made nestingLimit a member of the document --- src/ArduinoJson/DynamicJsonDocument.hpp | 7 +++++-- src/ArduinoJson/StaticJsonDocument.hpp | 4 ++++ src/ArduinoJson/deserializeJson.hpp | 17 ++++++--------- src/ArduinoJson/deserializeMsgPack.hpp | 20 ++++++++---------- test/JsonDeserializer/nestingLimit.cpp | 28 +++++++++++++------------ test/MsgPack/deserializationErrors.cpp | 5 +++-- 6 files changed, 42 insertions(+), 39 deletions(-) diff --git a/src/ArduinoJson/DynamicJsonDocument.hpp b/src/ArduinoJson/DynamicJsonDocument.hpp index 9cbda37f9..884c615df 100644 --- a/src/ArduinoJson/DynamicJsonDocument.hpp +++ b/src/ArduinoJson/DynamicJsonDocument.hpp @@ -16,8 +16,11 @@ class DynamicJsonDocument { JsonVariant _root; public: - DynamicJsonDocument() {} - DynamicJsonDocument(size_t capacity) : _buffer(capacity) {} + uint8_t nestingLimit; + + DynamicJsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {} + DynamicJsonDocument(size_t capacity) + : _buffer(capacity), nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {} template bool is() const { diff --git a/src/ArduinoJson/StaticJsonDocument.hpp b/src/ArduinoJson/StaticJsonDocument.hpp index a1821ca31..b111485cb 100644 --- a/src/ArduinoJson/StaticJsonDocument.hpp +++ b/src/ArduinoJson/StaticJsonDocument.hpp @@ -15,6 +15,10 @@ class StaticJsonDocument { JsonVariant _root; public: + uint8_t nestingLimit; + + StaticJsonDocument() : nestingLimit(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {} + Internals::StaticJsonBufferBase& buffer() { return _buffer; } diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index 46ffbfff3..c59c8517a 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -13,9 +13,8 @@ namespace ArduinoJson { template typename Internals::EnableIf::value, JsonError>::type -deserializeJson(TDocument &doc, const TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(&doc.buffer(), json, nestingLimit) +deserializeJson(TDocument &doc, const TString &json) { + return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit) .parse(doc.template to()); } // @@ -23,10 +22,8 @@ deserializeJson(TDocument &doc, const TString &json, // TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const char*, const char[N], const FlashStringHelper* template -JsonError deserializeJson( - TDocument &doc, TString *json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(&doc.buffer(), json, nestingLimit) +JsonError deserializeJson(TDocument &doc, TString *json) { + return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit) .parse(doc.template to()); } // @@ -34,10 +31,8 @@ JsonError deserializeJson( // TDocument = DynamicJsonDocument, StaticJsonDocument // TString = std::istream&, Stream& template -JsonError deserializeJson( - TDocument &doc, TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeParser(&doc.buffer(), json, nestingLimit) +JsonError deserializeJson(TDocument &doc, TString &json) { + return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit) .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeMsgPack.hpp b/src/ArduinoJson/deserializeMsgPack.hpp index 60493d35a..42cd83a69 100644 --- a/src/ArduinoJson/deserializeMsgPack.hpp +++ b/src/ArduinoJson/deserializeMsgPack.hpp @@ -13,9 +13,9 @@ namespace ArduinoJson { template typename Internals::EnableIf::value, MsgPackError>::type -deserializeMsgPack(TDocument &doc, const TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) +deserializeMsgPack(TDocument &doc, const TString &json) { + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, + doc.nestingLimit) .parse(doc.template to()); } // @@ -23,10 +23,9 @@ deserializeMsgPack(TDocument &doc, const TString &json, // TDocument = DynamicJsonArray | StaticJsonArray // TString = const char*, const char[N], const FlashStringHelper* template -MsgPackError deserializeMsgPack( - TDocument &doc, TString *json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) +MsgPackError deserializeMsgPack(TDocument &doc, TString *json) { + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, + doc.nestingLimit) .parse(doc.template to()); } // @@ -34,10 +33,9 @@ MsgPackError deserializeMsgPack( // TDocument = DynamicJsonArray | StaticJsonArray // TString = std::istream&, Stream& template -MsgPackError deserializeMsgPack( - TDocument &doc, TString &json, - uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) { - return Internals::makeMsgPackDeserializer(&doc.buffer(), json, nestingLimit) +MsgPackError deserializeMsgPack(TDocument &doc, TString &json) { + return Internals::makeMsgPackDeserializer(&doc.buffer(), json, + doc.nestingLimit) .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/test/JsonDeserializer/nestingLimit.cpp b/test/JsonDeserializer/nestingLimit.cpp index 0eecb4ff4..d2c41d5b4 100644 --- a/test/JsonDeserializer/nestingLimit.cpp +++ b/test/JsonDeserializer/nestingLimit.cpp @@ -12,21 +12,23 @@ 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)); + doc.nestingLimit = 0; + SHOULD_WORK(deserializeJson(doc, "\"toto\"")); + SHOULD_WORK(deserializeJson(doc, "123")); + SHOULD_WORK(deserializeJson(doc, "true")); + SHOULD_FAIL(deserializeJson(doc, "[]")); + SHOULD_FAIL(deserializeJson(doc, "{}")); + SHOULD_FAIL(deserializeJson(doc, "[\"toto\"]")); + SHOULD_FAIL(deserializeJson(doc, "{\"toto\":1}")); } 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)); + doc.nestingLimit = 1; + SHOULD_WORK(deserializeJson(doc, "[\"toto\"]")); + SHOULD_WORK(deserializeJson(doc, "{\"toto\":1}")); + SHOULD_FAIL(deserializeJson(doc, "{\"toto\":{}}")); + SHOULD_FAIL(deserializeJson(doc, "{\"toto\":[]}")); + SHOULD_FAIL(deserializeJson(doc, "[[\"toto\"]]")); + SHOULD_FAIL(deserializeJson(doc, "[{\"toto\":1}]")); } } diff --git a/test/MsgPack/deserializationErrors.cpp b/test/MsgPack/deserializationErrors.cpp index c9e0e94e6..1ece18bc0 100644 --- a/test/MsgPack/deserializationErrors.cpp +++ b/test/MsgPack/deserializationErrors.cpp @@ -7,9 +7,10 @@ static void check(const char* input, MsgPackError expected, uint8_t nestingLimit = 10) { - DynamicJsonDocument variant; + DynamicJsonDocument doc; + doc.nestingLimit = nestingLimit; - MsgPackError error = deserializeMsgPack(variant, input, nestingLimit); + MsgPackError error = deserializeMsgPack(doc, input); REQUIRE(error == expected); } From ccb54136a2d02849db25de7a2bd05402070ea1fa Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Mon, 14 May 2018 17:12:59 +0200 Subject: [PATCH 0028/1079] Added support for non zero-terminated strings (fixes #704) --- .travis.yml | 2 +- CHANGELOG.md | 1 + src/ArduinoJson.hpp | 2 - .../Json/Deserialization/Comments.hpp | 61 --- .../Json/Deserialization/JsonDeserializer.hpp | 207 ++++--- src/ArduinoJson/JsonError.hpp | 8 +- .../MsgPack/MsgPackDeserializer.hpp | 217 ++++---- src/ArduinoJson/MsgPack/MsgPackError.hpp | 8 +- .../Reading/ArduinoStreamReader.hpp | 41 ++ src/ArduinoJson/Reading/CharPointerReader.hpp | 64 +++ src/ArduinoJson/Reading/FlashStringReader.hpp | 56 ++ src/ArduinoJson/Reading/IteratorReader.hpp | 34 ++ src/ArduinoJson/Reading/Reader.hpp | 11 + src/ArduinoJson/Reading/StdStreamReader.hpp | 40 ++ src/ArduinoJson/Strings/ArduinoStream.hpp | 61 --- src/ArduinoJson/Strings/CharPointer.hpp | 20 - src/ArduinoJson/Strings/FlashString.hpp | 20 - src/ArduinoJson/Strings/StdStream.hpp | 60 --- src/ArduinoJson/Strings/StdString.hpp | 4 - src/ArduinoJson/Strings/StringTraits.hpp | 2 - src/ArduinoJson/Writing/JsonBufferWriter.hpp | 27 + .../{Strings => Writing}/StringWriter.hpp | 0 src/ArduinoJson/Writing/Writer.hpp | 44 ++ src/ArduinoJson/deserializeJson.hpp | 45 +- src/ArduinoJson/deserializeMsgPack.hpp | 60 ++- test/JsonArray/CMakeLists.txt | 1 + test/JsonArray/std_string.cpp | 39 ++ test/JsonDeserializer/CMakeLists.txt | 2 + test/JsonDeserializer/JsonError.cpp | 2 + .../JsonDeserializer/deserializeJsonArray.cpp | 62 ++- .../deserializeJsonArrayStatic.cpp | 20 +- .../deserializeJsonObject.cpp | 226 +++++++- .../deserializeJsonObjectStatic.cpp | 20 +- .../JsonDeserializer/deserializeJsonValue.cpp | 115 +++- test/JsonDeserializer/std_istream.cpp | 73 +++ test/JsonDeserializer/std_string.cpp | 35 ++ test/JsonObject/CMakeLists.txt | 1 + test/JsonObject/std_string.cpp | 173 ++++++ test/JsonSerializer/CMakeLists.txt | 2 + test/JsonSerializer/std_stream.cpp | 64 +++ test/JsonSerializer/std_string.cpp | 47 ++ test/Misc/CMakeLists.txt | 4 +- test/Misc/std_stream.cpp | 88 --- test/Misc/std_string.cpp | 259 --------- test/Misc/unsigned_char.cpp | 354 ++++++------ test/Misc/vla.cpp | 505 +++++++++--------- test/MsgPack/CMakeLists.txt | 10 +- test/MsgPack/MsgPackError.cpp | 2 + test/MsgPack/deserializationErrors.cpp | 59 -- test/MsgPack/incompleteInput.cpp | 106 ++++ test/MsgPack/nestingLimit.cpp | 31 ++ test/MsgPack/notSupported.cpp | 73 +++ test/MsgPack/std_istream.cpp | 29 + test/MsgPack/std_string.cpp | 44 ++ 54 files changed, 2187 insertions(+), 1354 deletions(-) delete mode 100644 src/ArduinoJson/Json/Deserialization/Comments.hpp create mode 100644 src/ArduinoJson/Reading/ArduinoStreamReader.hpp create mode 100644 src/ArduinoJson/Reading/CharPointerReader.hpp create mode 100644 src/ArduinoJson/Reading/FlashStringReader.hpp create mode 100644 src/ArduinoJson/Reading/IteratorReader.hpp create mode 100644 src/ArduinoJson/Reading/Reader.hpp create mode 100644 src/ArduinoJson/Reading/StdStreamReader.hpp delete mode 100644 src/ArduinoJson/Strings/ArduinoStream.hpp delete mode 100644 src/ArduinoJson/Strings/StdStream.hpp create mode 100644 src/ArduinoJson/Writing/JsonBufferWriter.hpp rename src/ArduinoJson/{Strings => Writing}/StringWriter.hpp (100%) create mode 100644 src/ArduinoJson/Writing/Writer.hpp create mode 100644 test/JsonArray/std_string.cpp create mode 100644 test/JsonDeserializer/std_istream.cpp create mode 100644 test/JsonDeserializer/std_string.cpp create mode 100644 test/JsonObject/std_string.cpp create mode 100644 test/JsonSerializer/std_stream.cpp create mode 100644 test/JsonSerializer/std_string.cpp delete mode 100644 test/Misc/std_stream.cpp delete mode 100644 test/Misc/std_string.cpp delete mode 100644 test/MsgPack/deserializationErrors.cpp create mode 100644 test/MsgPack/incompleteInput.cpp create mode 100644 test/MsgPack/nestingLimit.cpp create mode 100644 test/MsgPack/notSupported.cpp create mode 100644 test/MsgPack/std_istream.cpp create mode 100644 test/MsgPack/std_string.cpp diff --git a/.travis.yml b/.travis.yml index 9605e80cc..1f393a12f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,7 +31,7 @@ matrix: apt: sources: ['ubuntu-toolchain-r-test'] packages: ['g++-5'] - env: SCRIPT=cmake GCC=5 SANITIZE=undefined + env: SCRIPT=cmake GCC=5 # SANITIZE=undefined - compiler: gcc addons: apt: diff --git a/CHANGELOG.md b/CHANGELOG.md index e03c7e079..dce5d9a1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ HEAD * Added `measureJson()` and `measureJsonPretty()` * Added `deserializeMsgPack()` (issue #358) * Added example `MsgPackParser.ino` (issue #358) +* Added support for non zero-terminated strings (issue #704) * Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` * Removed `JsonBuffer::createArray()` and `createObject()` * Removed `printTo()` and `prettyPrintTo()` diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 71bc18e1a..a1a015083 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -5,12 +5,10 @@ #pragma once #include "ArduinoJson/DynamicJsonDocument.hpp" -#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" #include "ArduinoJson/StaticJsonDocument.hpp" #include "ArduinoJson/deserializeJson.hpp" #include "ArduinoJson/deserializeMsgPack.hpp" -#include "ArduinoJson/Json/Deserialization/JsonDeserializer.hpp" #include "ArduinoJson/Json/Serialization/JsonSerializer.hpp" #include "ArduinoJson/JsonArrayImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp" diff --git a/src/ArduinoJson/Json/Deserialization/Comments.hpp b/src/ArduinoJson/Json/Deserialization/Comments.hpp deleted file mode 100644 index c2c48ebcc..000000000 --- a/src/ArduinoJson/Json/Deserialization/Comments.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -namespace ArduinoJson { -namespace Internals { -template -void skipSpacesAndComments(TInput& input) { - for (;;) { - switch (input.current()) { - // spaces - case ' ': - case '\t': - case '\r': - case '\n': - input.move(); - continue; - - // comments - case '/': - switch (input.next()) { - // C-style block comment - case '*': - input.move(); // skip '/' - // no need to skip '*' - for (;;) { - input.move(); - if (input.current() == '\0') return; - if (input.current() == '*' && input.next() == '/') { - input.move(); // skip '*' - input.move(); // skip '/' - break; - } - } - break; - - // C++-style line comment - case '/': - // not need to skip "//" - for (;;) { - input.move(); - if (input.current() == '\0') return; - if (input.current() == '\n') break; - } - break; - - // not a comment, just a '/' - default: - return; - } - break; - - default: - return; - } - } -} -} -} diff --git a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp index c8db8ffd6..73026e377 100644 --- a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp +++ b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp @@ -7,10 +7,9 @@ #include "../../JsonError.hpp" #include "../../JsonVariant.hpp" #include "../../Memory/JsonBuffer.hpp" -#include "../../Strings/StringWriter.hpp" +#include "../../Reading/Reader.hpp" #include "../../TypeTraits/IsConst.hpp" #include "../Encoding.hpp" -#include "./Comments.hpp" namespace ArduinoJson { namespace Internals { @@ -23,11 +22,13 @@ class JsonDeserializer { : _buffer(buffer), _reader(reader), _writer(writer), - _nestingLimit(nestingLimit) {} + _nestingLimit(nestingLimit), + _loaded(false) {} JsonError parse(JsonVariant &variant) { - skipSpacesAndComments(_reader); + JsonError err = skipSpacesAndComments(); + if (err) return err; - switch (_reader.current()) { + switch (current()) { case '[': return parseArray(variant); @@ -42,15 +43,25 @@ class JsonDeserializer { 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; + char current() { + if (!_loaded) { + if (_reader.ended()) + _current = 0; + else + _current = _reader.read(); + _loaded = true; + } + return _current; + } + + void move() { + _loaded = false; } FORCE_INLINE bool eat(char charToSkip) { - return eat(_reader, charToSkip); + if (current() != charToSkip) return false; + move(); + return true; } JsonError parseArray(JsonVariant &variant) { @@ -62,6 +73,12 @@ class JsonDeserializer { // Check opening braket if (!eat('[')) return JsonError::InvalidInput; + + // Skip spaces + JsonError err = skipSpacesAndComments(); + if (err) return err; + + // Empty array? if (eat(']')) return JsonError::Ok; // Read each value @@ -69,12 +86,16 @@ class JsonDeserializer { // 1 - Parse value JsonVariant value; _nestingLimit--; - JsonError error = parse(value); + err = parse(value); _nestingLimit++; - if (error != JsonError::Ok) return error; + if (err) return err; if (!array->add(value)) return JsonError::NoMemory; - // 2 - More values? + // 2 - Skip spaces + err = skipSpacesAndComments(); + if (err) return err; + + // 3 - More values? if (eat(']')) return JsonError::Ok; if (!eat(',')) return JsonError::InvalidInput; } @@ -89,31 +110,52 @@ class JsonDeserializer { // Check opening brace if (!eat('{')) return JsonError::InvalidInput; + + // Skip spaces + JsonError err = skipSpacesAndComments(); + if (err) return err; + + // Empty object? if (eat('}')) return JsonError::Ok; // Read each key value pair for (;;) { - // 1 - Parse key + // Parse key const char *key; - JsonError error = parseString(&key); - if (error) return error; + err = parseString(&key); + if (err) return err; + + // Skip spaces + err = skipSpacesAndComments(); + if (err) return err; + + // Colon if (!eat(':')) return JsonError::InvalidInput; - // 2 - Parse value + // Parse value JsonVariant value; _nestingLimit--; - error = parse(value); + err = parse(value); _nestingLimit++; - if (error != JsonError::Ok) return error; + if (err) return err; if (!object->set(key, value)) return JsonError::NoMemory; - // 3 - More keys/values? + // Skip spaces + err = skipSpacesAndComments(); + if (err) return err; + + // More keys/values? if (eat('}')) return JsonError::Ok; if (!eat(',')) return JsonError::InvalidInput; + + // Skip spaces + err = skipSpacesAndComments(); + if (err) return err; } } + JsonError parseValue(JsonVariant &variant) { - bool hasQuotes = isQuote(_reader.current()); + bool hasQuotes = isQuote(current()); const char *value; JsonError error = parseString(&value); if (error) return error; @@ -128,33 +170,35 @@ class JsonDeserializer { JsonError parseString(const char **result) { typename RemoveReference::type::String str = _writer.startString(); - skipSpacesAndComments(_reader); - char c = _reader.current(); + char c = current(); + if (c == '\0') return JsonError::IncompleteInput; if (isQuote(c)) { // quotes - _reader.move(); + move(); char stopChar = c; for (;;) { - c = _reader.current(); - if (c == '\0') break; - _reader.move(); - + c = current(); + move(); if (c == stopChar) break; + if (c == '\0') return JsonError::IncompleteInput; + if (c == '\\') { + c = current(); + if (c == 0) return JsonError::IncompleteInput; // replace char - c = Encoding::unescapeChar(_reader.current()); + c = Encoding::unescapeChar(c); if (c == '\0') return JsonError::InvalidInput; - _reader.move(); + move(); } str.append(c); } } else if (canBeInNonQuotedString(c)) { // no quotes do { - _reader.move(); + move(); str.append(c); - c = _reader.current(); + c = current(); } while (canBeInNonQuotedString(c)); } else { return JsonError::InvalidInput; @@ -178,41 +222,80 @@ class JsonDeserializer { return c == '\'' || c == '\"'; } + JsonError skipSpacesAndComments() { + for (;;) { + switch (current()) { + // end of string + case '\0': + return JsonError::IncompleteInput; + + // spaces + case ' ': + case '\t': + case '\r': + case '\n': + move(); + continue; + + // comments + case '/': + move(); // skip '/' + switch (current()) { + // block comment + case '*': { + move(); // skip '*' + bool wasStar = false; + for (;;) { + char c = current(); + if (c == '\0') return JsonError::IncompleteInput; + if (c == '/' && wasStar) { + move(); + break; + } + wasStar = c == '*'; + move(); + } + break; + } + + // trailing comment + case '/': + // no need to skip "//" + for (;;) { + move(); + char c = current(); + if (c == '\0') return JsonError::IncompleteInput; + if (c == '\n') break; + } + break; + + // not a comment, just a '/' + default: + return JsonError::InvalidInput; + } + break; + + default: + return JsonError::Ok; + } + } + } + JsonBuffer *_buffer; TReader _reader; TWriter _writer; uint8_t _nestingLimit; + char _current; + bool _loaded; }; -template -struct JsonParserBuilder { - typedef typename StringTraits::Reader InputReader; - typedef JsonDeserializer TParser; - - static TParser makeParser(TJsonBuffer *buffer, TString &json, - uint8_t nestingLimit) { - return TParser(buffer, InputReader(json), *buffer, nestingLimit); - } -}; - -template -struct JsonParserBuilder::value>::type> { - typedef typename StringTraits::Reader TReader; - typedef StringWriter TWriter; - typedef JsonDeserializer TParser; - - static TParser makeParser(TJsonBuffer *buffer, TChar *json, - uint8_t nestingLimit) { - return TParser(buffer, TReader(json), TWriter(json), nestingLimit); - } -}; - -template -inline typename JsonParserBuilder::TParser makeParser( - TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) { - return JsonParserBuilder::makeParser(buffer, json, - nestingLimit); +template +JsonDeserializer makeJsonDeserializer(TJsonBuffer *buffer, + TReader reader, + TWriter writer, + uint8_t nestingLimit) { + return JsonDeserializer(buffer, reader, writer, + nestingLimit); } } // namespace Internals } // namespace ArduinoJson diff --git a/src/ArduinoJson/JsonError.hpp b/src/ArduinoJson/JsonError.hpp index 440604159..cc988bed7 100644 --- a/src/ArduinoJson/JsonError.hpp +++ b/src/ArduinoJson/JsonError.hpp @@ -4,11 +4,15 @@ #pragma once +#if ARDUINOJSON_ENABLE_STD_STREAM +#include +#endif + namespace ArduinoJson { class JsonError { public: - enum Code { Ok, TooDeep, NoMemory, InvalidInput }; + enum Code { Ok, TooDeep, NoMemory, InvalidInput, IncompleteInput }; JsonError(Code code) : _code(code) {} @@ -42,6 +46,8 @@ class JsonError { return "NoMemory"; case InvalidInput: return "InvalidInput"; + case IncompleteInput: + return "IncompleteInput"; default: return "???"; } diff --git a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index e1a923b79..d76547568 100644 --- a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -6,8 +6,9 @@ #include "../JsonVariant.hpp" #include "../Memory/JsonBuffer.hpp" -#include "../Strings/StringWriter.hpp" +#include "../Reading/Reader.hpp" #include "../TypeTraits/IsConst.hpp" +#include "../Writing/Writer.hpp" #include "./MsgPackError.hpp" #include "./endianess.hpp" #include "./ieee754.hpp" @@ -29,27 +30,28 @@ class MsgPackDeserializer { _nestingLimit(nestingLimit) {} MsgPackError parse(JsonVariant &variant) { - uint8_t c = readOne(); + uint8_t code; + if (!readByte(code)) return MsgPackError::IncompleteInput; - if ((c & 0x80) == 0) { - variant = c; + if ((code & 0x80) == 0) { + variant = code; return MsgPackError::Ok; } - if ((c & 0xe0) == 0xe0) { - variant = static_cast(c); + if ((code & 0xe0) == 0xe0) { + variant = static_cast(code); return MsgPackError::Ok; } - if ((c & 0xe0) == 0xa0) { - return readString(variant, c & 0x1f); + if ((code & 0xe0) == 0xa0) { + return readString(variant, code & 0x1f); } - if ((c & 0xf0) == 0x90) return readArray(variant, c & 0x0F); + if ((code & 0xf0) == 0x90) return readArray(variant, code & 0x0F); - if ((c & 0xf0) == 0x80) return readObject(variant, c & 0x0F); + if ((code & 0xf0) == 0x80) return readObject(variant, code & 0x0F); - switch (c) { + switch (code) { case 0xc0: variant = static_cast(0); return MsgPackError::Ok; @@ -63,81 +65,65 @@ class MsgPackDeserializer { return MsgPackError::Ok; case 0xcc: - variant = readInteger(); - return MsgPackError::Ok; + return readInteger(variant); case 0xcd: - variant = readInteger(); - return MsgPackError::Ok; + return readInteger(variant); case 0xce: - variant = readInteger(); - return MsgPackError::Ok; + return readInteger(variant); case 0xcf: #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 - variant = readInteger(); + return readInteger(variant); #else readInteger(); - variant = readInteger(); + return readInteger(variant); #endif - return MsgPackError::Ok; case 0xd0: - variant = readInteger(); - return MsgPackError::Ok; + return readInteger(variant); case 0xd1: - variant = readInteger(); - return MsgPackError::Ok; + return readInteger(variant); case 0xd2: - variant = readInteger(); - return MsgPackError::Ok; + return readInteger(variant); case 0xd3: #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 - variant = readInteger(); + return readInteger(variant); #else - readInteger(); - variant = readInteger(); + if (!skip(4)) return MsgPackError::IncompleteInput; + return readInteger(variant); #endif - return MsgPackError::Ok; case 0xca: - variant = readFloat(); - return MsgPackError::Ok; + return readFloat(variant); case 0xcb: - variant = readDouble(); - return MsgPackError::Ok; + return readDouble(variant); - case 0xd9: { - uint8_t n = readInteger(); - return readString(variant, n); - } + case 0xd9: + return readString(variant); - case 0xda: { - uint16_t n = readInteger(); - return readString(variant, n); - } + case 0xda: + return readString(variant); - case 0xdb: { - uint32_t n = readInteger(); - return readString(variant, n); - } + case 0xdb: + return readString(variant); case 0xdc: - return readArray(variant, readInteger()); + return readArray(variant); case 0xdd: - return readArray(variant, readInteger()); + return readArray(variant); case 0xde: - return readObject(variant, readInteger()); + return readObject(variant); case 0xdf: - return readObject(variant, readInteger()); + return readObject(variant); default: return MsgPackError::NotSupported; @@ -148,65 +134,115 @@ class MsgPackDeserializer { // Prevent VS warning "assignment operator could not be generated" MsgPackDeserializer &operator=(const MsgPackDeserializer &); - uint8_t readOne() { - char c = _reader.current(); - _reader.move(); - return static_cast(c); + bool skip(uint8_t n) { + while (n--) { + if (_reader.ended()) return false; + _reader.read(); + } + return true; } - void read(uint8_t *p, size_t n) { - for (size_t i = 0; i < n; i++) p[i] = readOne(); + bool readByte(uint8_t &value) { + if (_reader.ended()) return false; + value = static_cast(_reader.read()); + return true; + } + + bool readBytes(uint8_t *p, size_t n) { + for (size_t i = 0; i < n; i++) { + if (!readByte(p[i])) return false; + } + return true; } template - void read(T &value) { - read(reinterpret_cast(&value), sizeof(value)); + bool readBytes(T &value) { + return readBytes(reinterpret_cast(&value), sizeof(value)); } template T readInteger() { T value; - read(value); + readBytes(value); fixEndianess(value); return value; } template - typename EnableIf::type readFloat() { + bool readInteger(T &value) { + if (!readBytes(value)) return false; + fixEndianess(value); + return true; + } + + template + MsgPackError readInteger(JsonVariant &variant) { + T value; + if (!readInteger(value)) return MsgPackError::IncompleteInput; + variant = value; + return MsgPackError::Ok; + } + + template + typename EnableIf::type readFloat( + JsonVariant &variant) { T value; - read(value); + if (!readBytes(value)) return MsgPackError::IncompleteInput; fixEndianess(value); - return value; + variant = value; + return MsgPackError::Ok; } template - typename EnableIf::type readDouble() { + typename EnableIf::type readDouble( + JsonVariant &variant) { T value; - read(value); + if (!readBytes(value)) return MsgPackError::IncompleteInput; fixEndianess(value); - return value; + variant = value; + return MsgPackError::Ok; } template - typename EnableIf::type readDouble() { + typename EnableIf::type readDouble( + JsonVariant &variant) { uint8_t i[8]; // input is 8 bytes T value; // output is 4 bytes uint8_t *o = reinterpret_cast(&value); - read(i, 8); + if (!readBytes(i, 8)) return MsgPackError::IncompleteInput; doubleToFloat(i, o); fixEndianess(value); - return value; + variant = value; + return MsgPackError::Ok; + } + + template + MsgPackError readString(JsonVariant &variant) { + T size; + if (!readInteger(size)) return MsgPackError::IncompleteInput; + return readString(variant, size); } MsgPackError readString(JsonVariant &variant, size_t n) { typename RemoveReference::type::String str = _writer.startString(); - for (; n; --n) str.append(static_cast(readOne())); + for (; n; --n) { + uint8_t c; + if (!readBytes(c)) return MsgPackError::IncompleteInput; + str.append(static_cast(c)); + } const char *s = str.c_str(); if (s == NULL) return MsgPackError::NoMemory; variant = s; return MsgPackError::Ok; } + template + MsgPackError readArray(JsonVariant &variant) { + TSize size; + if (!readInteger(size)) return MsgPackError::IncompleteInput; + return readArray(variant, size); + } + MsgPackError readArray(JsonVariant &variant, size_t n) { JsonArray *array = new (_buffer) JsonArray(_buffer); if (!array) return MsgPackError::NoMemory; @@ -227,6 +263,13 @@ class MsgPackDeserializer { return MsgPackError::Ok; } + template + MsgPackError readObject(JsonVariant &variant) { + TSize size; + if (!readInteger(size)) return MsgPackError::IncompleteInput; + return readObject(variant, size); + } + MsgPackError readObject(JsonVariant &variant, size_t n) { JsonObject *object = new (_buffer) JsonObject(_buffer); if (!object) return MsgPackError::NoMemory; @@ -258,37 +301,11 @@ class MsgPackDeserializer { uint8_t _nestingLimit; }; -template -struct MsgPackDeserializerBuilder { - typedef typename StringTraits::Reader InputReader; - typedef MsgPackDeserializer TParser; - - static TParser makeMsgPackDeserializer(TJsonBuffer *buffer, TString &json, - uint8_t nestingLimit) { - return TParser(buffer, InputReader(json), *buffer, nestingLimit); - } -}; - -template -struct MsgPackDeserializerBuilder< - TJsonBuffer, TChar *, typename EnableIf::value>::type> { - typedef typename StringTraits::Reader TReader; - typedef StringWriter TWriter; - typedef MsgPackDeserializer TParser; - - static TParser makeMsgPackDeserializer(TJsonBuffer *buffer, TChar *json, - uint8_t nestingLimit) { - return TParser(buffer, TReader(json), TWriter(json), nestingLimit); - } -}; - -template -inline typename MsgPackDeserializerBuilder::TParser -makeMsgPackDeserializer(TJsonBuffer *buffer, TString &json, - uint8_t nestingLimit) { - return MsgPackDeserializerBuilder< - TJsonBuffer, TString>::makeMsgPackDeserializer(buffer, json, - nestingLimit); +template +MsgPackDeserializer makeMsgPackDeserializer( + TJsonBuffer *buffer, TReader reader, TWriter writer, uint8_t nestingLimit) { + return MsgPackDeserializer(buffer, reader, writer, + nestingLimit); } } // namespace Internals } // namespace ArduinoJson diff --git a/src/ArduinoJson/MsgPack/MsgPackError.hpp b/src/ArduinoJson/MsgPack/MsgPackError.hpp index 0134a723b..ed3a8a121 100644 --- a/src/ArduinoJson/MsgPack/MsgPackError.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackError.hpp @@ -4,11 +4,15 @@ #pragma once +#if ARDUINOJSON_ENABLE_STD_STREAM +#include +#endif + namespace ArduinoJson { class MsgPackError { public: - enum Code { Ok, NotSupported, NoMemory, TooDeep }; + enum Code { Ok, NotSupported, NoMemory, TooDeep, IncompleteInput }; MsgPackError() {} @@ -44,6 +48,8 @@ class MsgPackError { return "NoMemory"; case TooDeep: return "TooDeep"; + case IncompleteInput: + return "IncompleteInput"; default: return "???"; } diff --git a/src/ArduinoJson/Reading/ArduinoStreamReader.hpp b/src/ArduinoJson/Reading/ArduinoStreamReader.hpp new file mode 100644 index 000000000..53260657a --- /dev/null +++ b/src/ArduinoJson/Reading/ArduinoStreamReader.hpp @@ -0,0 +1,41 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#if ARDUINOJSON_ENABLE_ARDUINO_STREAM + +#include + +namespace ArduinoJson { +namespace Internals { + +struct ArduinoStreamReader { + Stream& _stream; + char _current; + bool _ended; + + public: + explicit ArduinoStreamReader(Stream& stream) + : _stream(stream), _current(0), _ended(false) {} + + char read() { + // don't use _stream.read() as it ignores the timeout + char c = 0; + _ended = _stream.readBytes(&c, 1) == 0; + return c; + } + + bool ended() const { + return _ended; + } +}; + +inline ArduinoStreamReader makeReader(Stream& input) { + return ArduinoStreamReader(input); +} +} // namespace Internals +} // namespace ArduinoJson + +#endif diff --git a/src/ArduinoJson/Reading/CharPointerReader.hpp b/src/ArduinoJson/Reading/CharPointerReader.hpp new file mode 100644 index 000000000..8414f84a4 --- /dev/null +++ b/src/ArduinoJson/Reading/CharPointerReader.hpp @@ -0,0 +1,64 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +template +class UnsafeCharPointerReader { + const TChar* _ptr; + + public: + explicit UnsafeCharPointerReader(const TChar* ptr) + : _ptr(ptr ? ptr : reinterpret_cast("")) {} + + char read() { + return static_cast(*_ptr++); + } + + bool ended() const { + // we cannot know + return false; + } +}; + +template +class SafeCharPointerReader { + const TChar* _ptr; + const TChar* _end; + + public: + explicit SafeCharPointerReader(const TChar* ptr, size_t len) + : _ptr(ptr ? ptr : reinterpret_cast("")), + _end(_ptr + len) {} + + char read() { + return static_cast(*_ptr++); + } + + bool ended() const { + return _ptr == _end; + } +}; + +template +inline UnsafeCharPointerReader makeReader(TChar* input) { + return UnsafeCharPointerReader(input); +} + +template +inline SafeCharPointerReader makeReader(TChar* input, size_t n) { + return SafeCharPointerReader(input, n); +} + +#if ARDUINOJSON_ENABLE_ARDUINO_STRING +inline SafeCharPointerReader makeReader(const String& input) { + return SafeCharPointerReader(input.c_str(), input.length()); +} +#endif + +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Reading/FlashStringReader.hpp b/src/ArduinoJson/Reading/FlashStringReader.hpp new file mode 100644 index 000000000..2eabf7982 --- /dev/null +++ b/src/ArduinoJson/Reading/FlashStringReader.hpp @@ -0,0 +1,56 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#if ARDUINOJSON_ENABLE_PROGMEM + +namespace ArduinoJson { +namespace Internals { +class UnsafeFlashStringReader { + const char* _ptr; + + public: + explicit UnsafeFlashStringReader(const __FlashStringHelper* ptr) + : _ptr(reinterpret_cast(ptr)) {} + + char read() { + return pgm_read_byte_near(_ptr++); + } + + bool ended() const { + // this reader cannot detect the end + return false; + } +}; + +class SafeFlashStringReader { + const char* _ptr; + const char* _end; + + public: + explicit SafeFlashStringReader(const __FlashStringHelper* ptr, size_t size) + : _ptr(reinterpret_cast(ptr)), _end(_ptr + size) {} + + char read() { + return pgm_read_byte_near(_ptr++); + } + + bool ended() const { + return _ptr == _end; + } +}; + +inline UnsafeFlashStringReader makeReader(const __FlashStringHelper* input) { + return UnsafeFlashStringReader(input); +} + +inline SafeFlashStringReader makeReader(const __FlashStringHelper* input, + size_t size) { + return SafeFlashStringReader(input, size); +} +} // namespace Internals +} // namespace ArduinoJson + +#endif diff --git a/src/ArduinoJson/Reading/IteratorReader.hpp b/src/ArduinoJson/Reading/IteratorReader.hpp new file mode 100644 index 000000000..7e01c214d --- /dev/null +++ b/src/ArduinoJson/Reading/IteratorReader.hpp @@ -0,0 +1,34 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +template +class IteratorReader { + TIterator _ptr, _end; + + public: + explicit IteratorReader(TIterator begin, TIterator end) + : _ptr(begin), _end(end) {} + + bool ended() const { + return _ptr == _end; + } + + char read() { + return char(*_ptr++); + } +}; + +template +inline IteratorReader makeReader( + const TInput& input) { + return IteratorReader(input.begin(), + input.end()); +} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Reading/Reader.hpp b/src/ArduinoJson/Reading/Reader.hpp new file mode 100644 index 000000000..ba7e0146b --- /dev/null +++ b/src/ArduinoJson/Reading/Reader.hpp @@ -0,0 +1,11 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "./ArduinoStreamReader.hpp" +#include "./CharPointerReader.hpp" +#include "./FlashStringReader.hpp" +#include "./IteratorReader.hpp" +#include "./StdStreamReader.hpp" diff --git a/src/ArduinoJson/Reading/StdStreamReader.hpp b/src/ArduinoJson/Reading/StdStreamReader.hpp new file mode 100644 index 000000000..8ad841a73 --- /dev/null +++ b/src/ArduinoJson/Reading/StdStreamReader.hpp @@ -0,0 +1,40 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#if ARDUINOJSON_ENABLE_STD_STREAM + +#include + +namespace ArduinoJson { +namespace Internals { + +class StdStreamReader { + std::istream& _stream; + char _current; + + public: + explicit StdStreamReader(std::istream& stream) + : _stream(stream), _current(0) {} + + bool ended() const { + return _stream.eof(); + } + + char read() { + return static_cast(_stream.get()); + } + + private: + StdStreamReader& operator=(const StdStreamReader&); // Visual Studio C4512 +}; + +inline StdStreamReader makeReader(std::istream& input) { + return StdStreamReader(input); +} +} // namespace Internals +} // namespace ArduinoJson + +#endif diff --git a/src/ArduinoJson/Strings/ArduinoStream.hpp b/src/ArduinoJson/Strings/ArduinoStream.hpp deleted file mode 100644 index 5db0852b8..000000000 --- a/src/ArduinoJson/Strings/ArduinoStream.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#if ARDUINOJSON_ENABLE_ARDUINO_STREAM - -#include - -namespace ArduinoJson { -namespace Internals { - -struct ArduinoStreamTraits { - class Reader { - Stream& _stream; - char _current, _next; - - public: - Reader(Stream& stream) : _stream(stream), _current(0), _next(0) {} - - void move() { - _current = _next; - _next = 0; - } - - char current() { - if (!_current) _current = read(); - return _current; - } - - char next() { - // assumes that current() has been called - if (!_next) _next = read(); - return _next; - } - - private: - char read() { - // don't use _stream.read() as it ignores the timeout - char c = 0; - _stream.readBytes(&c, 1); - return c; - } - }; - - static const bool has_append = false; - static const bool has_equals = false; -}; - -template -struct StringTraits< - TStream, - // match any type that is derived from Stream: - typename EnableIf< - IsBaseOf::type>::value>::type> - : ArduinoStreamTraits {}; -} -} - -#endif diff --git a/src/ArduinoJson/Strings/CharPointer.hpp b/src/ArduinoJson/Strings/CharPointer.hpp index a9f30f786..2b804ab3b 100644 --- a/src/ArduinoJson/Strings/CharPointer.hpp +++ b/src/ArduinoJson/Strings/CharPointer.hpp @@ -9,26 +9,6 @@ namespace Internals { template struct CharPointerTraits { - class Reader { - const TChar* _ptr; - - public: - Reader(const TChar* ptr) - : _ptr(ptr ? ptr : reinterpret_cast("")) {} - - void move() { - ++_ptr; - } - - char current() const { - return char(_ptr[0]); - } - - char next() const { - return char(_ptr[1]); - } - }; - static bool equals(const TChar* str, const char* expected) { return strcmp(reinterpret_cast(str), expected) == 0; } diff --git a/src/ArduinoJson/Strings/FlashString.hpp b/src/ArduinoJson/Strings/FlashString.hpp index 95f555d20..f5edbdc61 100644 --- a/src/ArduinoJson/Strings/FlashString.hpp +++ b/src/ArduinoJson/Strings/FlashString.hpp @@ -10,26 +10,6 @@ namespace ArduinoJson { namespace Internals { template <> struct StringTraits { - class Reader { - const char* _ptr; - - public: - Reader(const __FlashStringHelper* ptr) - : _ptr(reinterpret_cast(ptr)) {} - - void move() { - _ptr++; - } - - char current() const { - return pgm_read_byte_near(_ptr); - } - - char next() const { - return pgm_read_byte_near(_ptr + 1); - } - }; - static bool equals(const __FlashStringHelper* str, const char* expected) { return strcmp_P(expected, (const char*)str) == 0; } diff --git a/src/ArduinoJson/Strings/StdStream.hpp b/src/ArduinoJson/Strings/StdStream.hpp deleted file mode 100644 index 227c74406..000000000 --- a/src/ArduinoJson/Strings/StdStream.hpp +++ /dev/null @@ -1,60 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#if ARDUINOJSON_ENABLE_STD_STREAM - -#include - -namespace ArduinoJson { -namespace Internals { - -struct StdStreamTraits { - class Reader { - std::istream& _stream; - char _current, _next; - - public: - Reader(std::istream& stream) : _stream(stream), _current(0), _next(0) {} - - void move() { - _current = _next; - _next = 0; - } - - char current() { - if (!_current) _current = read(); - return _current; - } - - char next() { - // assumes that current() has been called - if (!_next) _next = read(); - return _next; - } - - private: - Reader& operator=(const Reader&); // Visual Studio C4512 - - char read() { - return _stream.eof() ? '\0' : static_cast(_stream.get()); - } - }; - - static const bool has_append = false; - static const bool has_equals = false; -}; - -template -struct StringTraits< - TStream, - // match any type that is derived from std::istream: - typename EnableIf::type>::value>::type> - : StdStreamTraits {}; -} -} - -#endif diff --git a/src/ArduinoJson/Strings/StdString.hpp b/src/ArduinoJson/Strings/StdString.hpp index 39124dac8..aa521e58c 100644 --- a/src/ArduinoJson/Strings/StdString.hpp +++ b/src/ArduinoJson/Strings/StdString.hpp @@ -35,10 +35,6 @@ struct StdStringTraits { return !str.c_str(); } - struct Reader : CharPointerTraits::Reader { - Reader(const TString& str) : CharPointerTraits::Reader(str.c_str()) {} - }; - static bool equals(const TString& str, const char* expected) { return 0 == strcmp(str.c_str(), expected); } diff --git a/src/ArduinoJson/Strings/StringTraits.hpp b/src/ArduinoJson/Strings/StringTraits.hpp index dd5694b2e..5201c1723 100644 --- a/src/ArduinoJson/Strings/StringTraits.hpp +++ b/src/ArduinoJson/Strings/StringTraits.hpp @@ -29,8 +29,6 @@ struct StringTraits : StringTraits {}; } } -#include "ArduinoStream.hpp" #include "CharPointer.hpp" #include "FlashString.hpp" -#include "StdStream.hpp" #include "StdString.hpp" diff --git a/src/ArduinoJson/Writing/JsonBufferWriter.hpp b/src/ArduinoJson/Writing/JsonBufferWriter.hpp new file mode 100644 index 000000000..5631ac2ed --- /dev/null +++ b/src/ArduinoJson/Writing/JsonBufferWriter.hpp @@ -0,0 +1,27 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "./StringWriter.hpp" + +namespace ArduinoJson { +namespace Internals { + +template +class JsonBufferWriter { + public: + JsonBufferWriter(TJsonBuffer& jb) : _jb(&jb) {} + + typedef typename TJsonBuffer::String String; + + String startString() { + return _jb->startString(); + } + + private: + TJsonBuffer* _jb; +}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Strings/StringWriter.hpp b/src/ArduinoJson/Writing/StringWriter.hpp similarity index 100% rename from src/ArduinoJson/Strings/StringWriter.hpp rename to src/ArduinoJson/Writing/StringWriter.hpp diff --git a/src/ArduinoJson/Writing/Writer.hpp b/src/ArduinoJson/Writing/Writer.hpp new file mode 100644 index 000000000..7a5292793 --- /dev/null +++ b/src/ArduinoJson/Writing/Writer.hpp @@ -0,0 +1,44 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "./JsonBufferWriter.hpp" +#include "./StringWriter.hpp" + +namespace ArduinoJson { +namespace Internals { + +template +struct Writer { + typedef JsonBufferWriter type; + + static type create(TJsonBuffer& jb, TInput&) { + return type(jb); + } +}; + +template +struct Writer::value>::type> { + typedef StringWriter type; + + static type create(TJsonBuffer&, TChar* input) { + return type(input); + } +}; + +template +typename Writer::type makeWriter(TJsonBuffer& jb, + TInput& input) { + return Writer::create(jb, input); +} + +template +typename Writer::type makeWriter(TJsonBuffer& jb, + TChar* input) { + return Writer::create(jb, input); +} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index c59c8517a..bda81ac68 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -5,34 +5,53 @@ #pragma once #include "Json/Deserialization/JsonDeserializer.hpp" +#include "Reading/Reader.hpp" +#include "Writing/Writer.hpp" namespace ArduinoJson { -// JsonError deserializeJson(TDocument& doc, TString json); +// JsonError deserializeJson(TDocument& doc, TString input); // TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& template typename Internals::EnableIf::value, JsonError>::type -deserializeJson(TDocument &doc, const TString &json) { - return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit) +deserializeJson(TDocument &doc, const TString &input) { + using namespace Internals; + return makeJsonDeserializer(&doc.buffer(), makeReader(input), + makeWriter(doc.buffer(), input), doc.nestingLimit) .parse(doc.template to()); } // -// JsonError deserializeJson(TDocument& doc, TString json); +// JsonError deserializeJson(TDocument& doc, TChar* input); // TDocument = DynamicJsonDocument, StaticJsonDocument -// TString = const char*, const char[N], const FlashStringHelper* -template -JsonError deserializeJson(TDocument &doc, TString *json) { - return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit) +// TChar* = char*, const char*, const FlashStringHelper* +template +JsonError deserializeJson(TDocument &doc, TChar *input) { + using namespace Internals; + return makeJsonDeserializer(&doc.buffer(), makeReader(input), + makeWriter(doc.buffer(), input), doc.nestingLimit) .parse(doc.template to()); } // -// JsonError deserializeJson(TDocument& doc, TString json); +// JsonError deserializeJson(TDocument& doc, TChar* input, size_t inputSize); // TDocument = DynamicJsonDocument, StaticJsonDocument -// TString = std::istream&, Stream& -template -JsonError deserializeJson(TDocument &doc, TString &json) { - return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit) +// TChar* = char*, const char*, const FlashStringHelper* +template +JsonError deserializeJson(TDocument &doc, TChar *input, size_t inputSize) { + using namespace Internals; + return makeJsonDeserializer(&doc.buffer(), makeReader(input, inputSize), + makeWriter(doc.buffer(), input), doc.nestingLimit) + .parse(doc.template to()); +} +// +// JsonError deserializeJson(TDocument& doc, TStream input); +// TDocument = DynamicJsonDocument, StaticJsonDocument +// TStream = std::istream&, Stream& +template +JsonError deserializeJson(TDocument &doc, TStream &input) { + using namespace Internals; + return makeJsonDeserializer(&doc.buffer(), makeReader(input), + makeWriter(doc.buffer(), input), doc.nestingLimit) .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeMsgPack.hpp b/src/ArduinoJson/deserializeMsgPack.hpp index 42cd83a69..92ac993ca 100644 --- a/src/ArduinoJson/deserializeMsgPack.hpp +++ b/src/ArduinoJson/deserializeMsgPack.hpp @@ -5,37 +5,59 @@ #pragma once #include "MsgPack/MsgPackDeserializer.hpp" +#include "Reading/Reader.hpp" +#include "Writing/Writer.hpp" namespace ArduinoJson { -// MsgPackError deserializeMsgPack(TDocument& doc, TString json); -// TDocument = DynamicJsonArray | StaticJsonArray +// MsgPackError deserializeMsgPack(TDocument& doc, TString input); +// TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& template typename Internals::EnableIf::value, MsgPackError>::type -deserializeMsgPack(TDocument &doc, const TString &json) { - return Internals::makeMsgPackDeserializer(&doc.buffer(), json, - doc.nestingLimit) +deserializeMsgPack(TDocument &doc, const TString &input) { + using namespace Internals; + return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), + makeWriter(doc.buffer(), input), + doc.nestingLimit) .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDocument& doc, TString json); -// TDocument = DynamicJsonArray | StaticJsonArray -// TString = const char*, const char[N], const FlashStringHelper* -template -MsgPackError deserializeMsgPack(TDocument &doc, TString *json) { - return Internals::makeMsgPackDeserializer(&doc.buffer(), json, - doc.nestingLimit) +// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input); +// TDocument = DynamicJsonDocument, StaticJsonDocument +// TChar* = char*, const char*, const FlashStringHelper* +template +MsgPackError deserializeMsgPack(TDocument &doc, TChar *input) { + using namespace Internals; + return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), + makeWriter(doc.buffer(), input), + doc.nestingLimit) .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDocument& doc, TString json); -// TDocument = DynamicJsonArray | StaticJsonArray -// TString = std::istream&, Stream& -template -MsgPackError deserializeMsgPack(TDocument &doc, TString &json) { - return Internals::makeMsgPackDeserializer(&doc.buffer(), json, - doc.nestingLimit) +// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input, size_t +// inputSize); +// TDocument = DynamicJsonDocument, StaticJsonDocument +// TChar* = char*, const char*, const FlashStringHelper* +template +MsgPackError deserializeMsgPack(TDocument &doc, TChar *input, + size_t inputSize) { + using namespace Internals; + return makeMsgPackDeserializer(&doc.buffer(), makeReader(input, inputSize), + makeWriter(doc.buffer(), input), + doc.nestingLimit) + .parse(doc.template to()); +} +// +// MsgPackError deserializeMsgPack(TDocument& doc, TStream input); +// TDocument = DynamicJsonDocument, StaticJsonDocument +// TStream = std::istream&, Stream& +template +MsgPackError deserializeMsgPack(TDocument &doc, TStream &input) { + using namespace Internals; + return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), + makeWriter(doc.buffer(), input), + doc.nestingLimit) .parse(doc.template to()); } } // namespace ArduinoJson diff --git a/test/JsonArray/CMakeLists.txt b/test/JsonArray/CMakeLists.txt index c0b13b60f..d7a5dc09b 100644 --- a/test/JsonArray/CMakeLists.txt +++ b/test/JsonArray/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(JsonArrayTests remove.cpp set.cpp size.cpp + std_string.cpp subscript.cpp ) diff --git a/test/JsonArray/std_string.cpp b/test/JsonArray/std_string.cpp new file mode 100644 index 000000000..d6be2973f --- /dev/null +++ b/test/JsonArray/std_string.cpp @@ -0,0 +1,39 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +static void eraseString(std::string &str) { + char *p = const_cast(str.c_str()); + while (*p) *p++ = '*'; +} + +TEST_CASE("std::string") { + DynamicJsonDocument doc; + JsonArray &array = doc.to(); + + SECTION("add()") { + std::string value("hello"); + array.add(value); + eraseString(value); + REQUIRE(std::string("hello") == array[0]); + } + + SECTION("set()") { + std::string value("world"); + array.add("hello"); + array.set(0, value); + eraseString(value); + REQUIRE(std::string("world") == array[0]); + } + + SECTION("operator[]") { + std::string value("world"); + array.add("hello"); + array[0] = value; + eraseString(value); + REQUIRE(std::string("world") == array[0]); + } +} diff --git a/test/JsonDeserializer/CMakeLists.txt b/test/JsonDeserializer/CMakeLists.txt index 6201ea701..16cb2460f 100644 --- a/test/JsonDeserializer/CMakeLists.txt +++ b/test/JsonDeserializer/CMakeLists.txt @@ -10,6 +10,8 @@ add_executable(JsonDeserializerTests deserializeJsonValue.cpp JsonError.cpp nestingLimit.cpp + std_istream.cpp + std_string.cpp ) target_link_libraries(JsonDeserializerTests catch) diff --git a/test/JsonDeserializer/JsonError.cpp b/test/JsonDeserializer/JsonError.cpp index edcad063f..b80bd66ac 100644 --- a/test/JsonDeserializer/JsonError.cpp +++ b/test/JsonDeserializer/JsonError.cpp @@ -25,6 +25,7 @@ TEST_CASE("JsonError") { TEST_STRINGIFICATION(TooDeep); TEST_STRINGIFICATION(NoMemory); TEST_STRINGIFICATION(InvalidInput); + TEST_STRINGIFICATION(IncompleteInput); } SECTION("as boolean") { @@ -32,6 +33,7 @@ TEST_CASE("JsonError") { TEST_BOOLIFICATION(TooDeep, true); TEST_BOOLIFICATION(NoMemory, true); TEST_BOOLIFICATION(InvalidInput, true); + TEST_BOOLIFICATION(IncompleteInput, true); } SECTION("ostream") { diff --git a/test/JsonDeserializer/deserializeJsonArray.cpp b/test/JsonDeserializer/deserializeJsonArray.cpp index 54dcc2d51..57bf5759a 100644 --- a/test/JsonDeserializer/deserializeJsonArray.cpp +++ b/test/JsonDeserializer/deserializeJsonArray.cpp @@ -164,13 +164,13 @@ TEST_CASE("deserialize JSON array") { SECTION("Closing single quotes missing") { JsonError err = deserializeJson(doc, "[\"]"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } SECTION("Closing double quotes missing") { JsonError err = deserializeJson(doc, "[\']"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } } @@ -233,21 +233,21 @@ TEST_CASE("deserialize JSON array") { SECTION("/*/") { JsonError err = deserializeJson(doc, "[/*/\n]"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } SECTION("Unfinished comment") { JsonError err = deserializeJson(doc, "[/*COMMENT]"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } SECTION("Final slash missing") { JsonError err = deserializeJson(doc, "[/*COMMENT*]"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } } - SECTION("Line comments") { + SECTION("Trailing comments") { SECTION("Before opening bracket") { JsonError err = deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); JsonArray& arr = doc.as(); @@ -311,39 +311,53 @@ TEST_CASE("deserialize JSON array") { SECTION("End document with comment") { JsonError err = deserializeJson(doc, "[//COMMENT"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } } - SECTION("Misc") { - SECTION("Garbage") { - JsonError err = deserializeJson(doc, "%*$£¤"); + SECTION("Premature null-terminator") { + SECTION("After opening bracket") { + JsonError err = deserializeJson(doc, "["); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } - SECTION("The opening bracket is missing") { - JsonError err = deserializeJson(doc, "]"); + SECTION("After value") { + JsonError err = deserializeJson(doc, "[1"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } - SECTION("The closing bracket is missing") { - JsonError err = deserializeJson(doc, "["); + SECTION("After comma") { + JsonError err = deserializeJson(doc, "[1,"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } + } - SECTION("Escape sequences") { - JsonError err = - deserializeJson(doc, "[\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"]"); - JsonArray& arr = doc.as(); + SECTION("Premature end of input") { + const char* input = "[1,2]"; - REQUIRE(err == JsonError::Ok); - REQUIRE(1 == arr.size()); - REQUIRE(arr[0] == "1\"2\\3/4\b5\f6\n7\r8\t9"); + SECTION("After opening bracket") { + JsonError err = deserializeJson(doc, input, 1); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("After value") { + JsonError err = deserializeJson(doc, input, 2); + + REQUIRE(err == JsonError::IncompleteInput); } + SECTION("After comma") { + JsonError err = deserializeJson(doc, input, 3); + + REQUIRE(err == JsonError::IncompleteInput); + } + } + + SECTION("Misc") { SECTION("Nested objects") { char jsonString[] = " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; diff --git a/test/JsonDeserializer/deserializeJsonArrayStatic.cpp b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp index 45da9c03f..8315c7ebf 100644 --- a/test/JsonDeserializer/deserializeJsonArrayStatic.cpp +++ b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp @@ -21,7 +21,7 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") { JsonError err = deserializeJson(doc, input); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::NoMemory); } SECTION("BufferOfTheRightSizeForArrayWithOneValue") { @@ -39,7 +39,7 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") { JsonError err = deserializeJson(doc, input); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::NoMemory); } SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { @@ -51,22 +51,6 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") { REQUIRE(err == JsonError::Ok); } - SECTION("CharPtrNull") { - StaticJsonDocument<100> doc; - - JsonError err = deserializeJson(doc, static_cast(0)); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("ConstCharPtrNull") { - StaticJsonDocument<100> doc; - - JsonError err = deserializeJson(doc, static_cast(0)); - - REQUIRE(err != JsonError::Ok); - } - SECTION("CopyStringNotSpaces") { StaticJsonDocument<100> doc; diff --git a/test/JsonDeserializer/deserializeJsonObject.cpp b/test/JsonDeserializer/deserializeJsonObject.cpp index f44a8e053..ca848a827 100644 --- a/test/JsonDeserializer/deserializeJsonObject.cpp +++ b/test/JsonDeserializer/deserializeJsonObject.cpp @@ -212,19 +212,39 @@ TEST_CASE("deserialize JSON object") { } } - SECTION("Misc") { - SECTION("The opening brace is missing") { - JsonError err = deserializeJson(doc, "}"); + SECTION("Premature null terminator") { + SECTION("After opening brace") { + JsonError err = deserializeJson(doc, "{"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("After key") { + JsonError err = deserializeJson(doc, "{\"hello\""); + + REQUIRE(err == JsonError::IncompleteInput); } - SECTION("The closing brace is missing") { + SECTION("After colon") { + JsonError err = deserializeJson(doc, "{\"hello\":"); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("After value") { JsonError err = deserializeJson(doc, "{\"hello\":\"world\""); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == JsonError::IncompleteInput); } + SECTION("After comma") { + JsonError err = deserializeJson(doc, "{\"hello\":\"world\","); + + REQUIRE(err == JsonError::IncompleteInput); + } + } + + SECTION("Misc") { SECTION("A quoted key without value") { JsonError err = deserializeJson(doc, "{\"key\"}"); @@ -250,6 +270,200 @@ TEST_CASE("deserialize JSON object") { } } + SECTION("Block comments") { + SECTION("Before opening brace") { + JsonError err = deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("After opening brace") { + JsonError err = deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("Before colon") { + JsonError err = deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("After colon") { + JsonError err = deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("Before closing brace") { + JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("After closing brace") { + JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("Before comma") { + JsonError err = deserializeJson( + doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + REQUIRE(obj["answer"] == 42); + } + + SECTION("After comma") { + JsonError err = deserializeJson( + doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + REQUIRE(obj["answer"] == 42); + } + } + + SECTION("Trailing comments") { + SECTION("Before opening brace") { + JsonError err = deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("After opening brace") { + JsonError err = deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("Before colon") { + JsonError err = deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("After colon") { + JsonError err = deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("Before closing brace") { + JsonError err = deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("After closing brace") { + JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("Before comma") { + JsonError err = deserializeJson( + doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + REQUIRE(obj["answer"] == 42); + } + + SECTION("After comma") { + JsonError err = deserializeJson( + doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + REQUIRE(obj["answer"] == 42); + } + } + + SECTION("Dangling slash") { + SECTION("Before opening brace") { + JsonError err = deserializeJson(doc, "/{\"hello\":\"world\"}"); + + REQUIRE(err == JsonError::InvalidInput); + } + + SECTION("After opening brace") { + JsonError err = deserializeJson(doc, "{/\"hello\":\"world\"}"); + + REQUIRE(err == JsonError::InvalidInput); + } + + SECTION("Before colon") { + JsonError err = deserializeJson(doc, "{\"hello\"/:\"world\"}"); + + REQUIRE(err == JsonError::InvalidInput); + } + + SECTION("After colon") { + JsonError err = deserializeJson(doc, "{\"hello\":/\"world\"}"); + + REQUIRE(err == JsonError::InvalidInput); + } + + SECTION("Before closing brace") { + JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/}"); + + REQUIRE(err == JsonError::InvalidInput); + } + + SECTION("After closing brace") { + JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/"); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(obj["hello"] == "world"); + } + + SECTION("Before comma") { + JsonError err = + deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}"); + + REQUIRE(err == JsonError::InvalidInput); + } + + SECTION("After comma") { + JsonError err = + deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}"); + + REQUIRE(err == JsonError::InvalidInput); + } + } + SECTION("Should clear the JsonObject") { deserializeJson(doc, "{\"hello\":\"world\"}"); deserializeJson(doc, "{}"); diff --git a/test/JsonDeserializer/deserializeJsonObjectStatic.cpp b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp index ab44b2a18..85b2dfef4 100644 --- a/test/JsonDeserializer/deserializeJsonObjectStatic.cpp +++ b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp @@ -21,7 +21,7 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") { JsonError err = deserializeJson(doc, input); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::NoMemory); } SECTION("BufferOfTheRightSizeForObjectWithOneValue") { @@ -39,7 +39,7 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") { JsonError err = deserializeJson(doc, input); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::NoMemory); } SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { @@ -51,22 +51,6 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") { REQUIRE(err == JsonError::Ok); } - SECTION("CharPtrNull") { - StaticJsonDocument<100> doc; - - JsonError err = deserializeJson(doc, static_cast(0)); - - REQUIRE(err != JsonError::Ok); - } - - SECTION("ConstCharPtrNull") { - StaticJsonDocument<100> doc; - - JsonError err = deserializeJson(doc, static_cast(0)); - - REQUIRE(err != JsonError::Ok); - } - SECTION("Should clear the JsonObject") { StaticJsonDocument doc; char input[] = "{\"hello\":\"world\"}"; diff --git a/test/JsonDeserializer/deserializeJsonValue.cpp b/test/JsonDeserializer/deserializeJsonValue.cpp index 4d374d5cf..fb9f8105a 100644 --- a/test/JsonDeserializer/deserializeJsonValue.cpp +++ b/test/JsonDeserializer/deserializeJsonValue.cpp @@ -10,18 +10,16 @@ using namespace Catch::Matchers; TEST_CASE("deserializeJson(DynamicJsonDocument&)") { DynamicJsonDocument doc; - SECTION("EmptyObject") { - JsonError err = deserializeJson(doc, "{}"); + SECTION("null char*") { + JsonError err = deserializeJson(doc, static_cast(0)); - REQUIRE(err == JsonError::Ok); - REQUIRE(doc.is()); + REQUIRE(err != JsonError::Ok); } - SECTION("EmptyArray") { - JsonError err = deserializeJson(doc, "[]"); + SECTION("null const char*") { + JsonError err = deserializeJson(doc, static_cast(0)); - REQUIRE(err == JsonError::Ok); - REQUIRE(doc.is()); + REQUIRE(err != JsonError::Ok); } SECTION("Integer") { @@ -58,6 +56,14 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") { REQUIRE_THAT(doc.as(), Equals("hello world")); } + SECTION("Escape sequences") { + JsonError err = + deserializeJson(doc, "\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\""); + + REQUIRE(err == JsonError::Ok); + REQUIRE(doc.as() == "1\"2\\3/4\b5\f6\n7\r8\t9"); + } + SECTION("True") { JsonError err = deserializeJson(doc, "true"); @@ -74,30 +80,93 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") { REQUIRE(doc.as() == false); } - SECTION("OpenBrace") { - JsonError err = deserializeJson(doc, "{"); + SECTION("Should clear the JsonVariant") { + deserializeJson(doc, "[1,2,3]"); + deserializeJson(doc, "{}"); + + REQUIRE(doc.is()); + REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + } + + SECTION("Empty input") { + JsonError err = deserializeJson(doc, ""); - REQUIRE(err != JsonError::Ok); + REQUIRE(err == JsonError::IncompleteInput); } - SECTION("Incomplete string") { - JsonError err = deserializeJson(doc, "\"hello"); + SECTION("Just a trailing comment") { + JsonError err = deserializeJson(doc, "// comment"); - REQUIRE(err == JsonError::Ok); - REQUIRE(doc.is()); - REQUIRE_THAT(doc.as(), Equals("hello")); + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("Just a block comment") { + JsonError err = deserializeJson(doc, "/*comment*/"); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("Just a slash") { + JsonError err = deserializeJson(doc, "/"); + + REQUIRE(err == JsonError::InvalidInput); } - SECTION("Unterminated escape sequence") { - JsonError err = deserializeJson(doc, "\"\\\0\""); + SECTION("Garbage") { + JsonError err = deserializeJson(doc, "%*$£¤"); + REQUIRE(err == JsonError::InvalidInput); } - SECTION("Should clear the JsonVariant") { - deserializeJson(doc, "[1,2,3]"); - deserializeJson(doc, "{}"); + SECTION("Premature null-terminator") { + SECTION("In escape sequence") { + JsonError err = deserializeJson(doc, "\"\\"); - REQUIRE(doc.is()); - REQUIRE(doc.memoryUsage() == JSON_OBJECT_SIZE(0)); + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("In block comment") { + JsonError err = deserializeJson(doc, "/* comment"); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("In double quoted string") { + JsonError err = deserializeJson(doc, "\"hello"); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("In single quoted string") { + JsonError err = deserializeJson(doc, "'hello"); + + REQUIRE(err == JsonError::IncompleteInput); + } + } + + SECTION("Premature end of input") { + SECTION("In escape sequence") { + JsonError err = deserializeJson(doc, "\"\\n\"", 2); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("In block comment") { + JsonError err = deserializeJson(doc, "/* comment */", 10); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("In double quoted string") { + JsonError err = deserializeJson(doc, "\"hello\"", 6); + + REQUIRE(err == JsonError::IncompleteInput); + } + + SECTION("In single quoted string") { + JsonError err = deserializeJson(doc, "'hello'", 6); + + REQUIRE(err == JsonError::IncompleteInput); + } } } diff --git a/test/JsonDeserializer/std_istream.cpp b/test/JsonDeserializer/std_istream.cpp new file mode 100644 index 000000000..b1f242185 --- /dev/null +++ b/test/JsonDeserializer/std_istream.cpp @@ -0,0 +1,73 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include +#include + +TEST_CASE("deserializeJson(std::istream&)") { + DynamicJsonDocument doc; + + SECTION("array") { + std::istringstream json(" [ 42 /* comment */ ] "); + + JsonError err = deserializeJson(doc, json); + JsonArray& arr = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == arr.size()); + REQUIRE(42 == arr[0]); + } + + SECTION("object") { + std::istringstream json(" { hello : world // comment\n }"); + + JsonError err = deserializeJson(doc, json); + JsonObject& obj = doc.as(); + + REQUIRE(err == JsonError::Ok); + REQUIRE(1 == obj.size()); + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("Should not read after the closing brace of an empty object") { + std::istringstream json("{}123"); + + deserializeJson(doc, json); + + REQUIRE('1' == char(json.get())); + } + + SECTION("Should not read after the closing brace") { + std::istringstream json("{\"hello\":\"world\"}123"); + + deserializeJson(doc, json); + + REQUIRE('1' == char(json.get())); + } + + SECTION("Should not read after the closing bracket of an empty array") { + std::istringstream json("[]123"); + + deserializeJson(doc, json); + + REQUIRE('1' == char(json.get())); + } + + SECTION("Should not read after the closing bracket") { + std::istringstream json("[\"hello\",\"world\"]123"); + + deserializeJson(doc, json); + + REQUIRE('1' == char(json.get())); + } + + SECTION("Should not read after the closing quote") { + std::istringstream json("\"hello\"123"); + + deserializeJson(doc, json); + + REQUIRE('1' == char(json.get())); + } +} diff --git a/test/JsonDeserializer/std_string.cpp b/test/JsonDeserializer/std_string.cpp new file mode 100644 index 000000000..baa5ee531 --- /dev/null +++ b/test/JsonDeserializer/std_string.cpp @@ -0,0 +1,35 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeJson(const std::string&)") { + DynamicJsonDocument doc; + + SECTION("should accept const string") { + const std::string input("[42]"); + + JsonError err = deserializeJson(doc, input); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("should accept temporary string") { + JsonError err = deserializeJson(doc, std::string("[42]")); + + REQUIRE(err == JsonError::Ok); + } + + SECTION("should duplicate content") { + std::string input("[\"hello\"]"); + + JsonError err = deserializeJson(doc, input); + input[2] = 'X'; // alter the string tomake sure we made a copy + + JsonArray &array = doc.as(); + REQUIRE(err == JsonError::Ok); + REQUIRE(std::string("hello") == array[0]); + } +} diff --git a/test/JsonObject/CMakeLists.txt b/test/JsonObject/CMakeLists.txt index b6de6d30b..5cb25efa6 100644 --- a/test/JsonObject/CMakeLists.txt +++ b/test/JsonObject/CMakeLists.txt @@ -11,6 +11,7 @@ add_executable(JsonObjectTests remove.cpp set.cpp size.cpp + std_string.cpp subscript.cpp ) diff --git a/test/JsonObject/std_string.cpp b/test/JsonObject/std_string.cpp new file mode 100644 index 000000000..accd7ae1b --- /dev/null +++ b/test/JsonObject/std_string.cpp @@ -0,0 +1,173 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +static void eraseString(std::string &str) { + char *p = const_cast(str.c_str()); + while (*p) *p++ = '*'; +} + +TEST_CASE("std::string") { + DynamicJsonDocument doc; + + SECTION("operator[]") { + char json[] = "{\"key\":\"value\"}"; + + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + + REQUIRE(std::string("value") == obj[std::string("key")]); + } + + SECTION("operator[] const") { + char json[] = "{\"key\":\"value\"}"; + + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + + REQUIRE(std::string("value") == obj[std::string("key")]); + } + + SECTION("set(key)") { + JsonObject &obj = doc.to(); + std::string key("hello"); + obj.set(key, "world"); + eraseString(key); + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("set(value)") { + JsonObject &obj = doc.to(); + std::string value("world"); + obj.set("hello", value); + eraseString(value); + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("set(key,value)") { + JsonObject &obj = doc.to(); + std::string key("hello"); + std::string value("world"); + obj.set(key, value); + eraseString(key); + eraseString(value); + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("set(JsonArraySubscript)") { + JsonObject &obj = doc.to(); + DynamicJsonDocument doc2; + JsonArray &arr = doc2.to(); + arr.add("world"); + + obj.set(std::string("hello"), arr[0]); + + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("set(JsonObjectSubscript)") { + JsonObject &obj = doc.to(); + DynamicJsonDocument doc2; + JsonObject &obj2 = doc2.to(); + obj2.set("x", "world"); + + obj.set(std::string("hello"), obj2["x"]); + + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("get()") { + char json[] = "{\"key\":\"value\"}"; + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + + REQUIRE(std::string("value") == obj.get(std::string("key"))); + } + + SECTION("is()") { + char json[] = "{\"key\":\"value\"}"; + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + + REQUIRE(true == obj.is(std::string("key"))); + } + + SECTION("createNestedObject()") { + JsonObject &obj = doc.to(); + std::string key = "key"; + char json[64]; + obj.createNestedObject(key); + eraseString(key); + serializeJson(doc, json, sizeof(json)); + REQUIRE(std::string("{\"key\":{}}") == json); + } + + SECTION("createNestedArray()") { + JsonObject &obj = doc.to(); + std::string key = "key"; + char json[64]; + obj.createNestedArray(key); + eraseString(key); + serializeJson(doc, json, sizeof(json)); + REQUIRE(std::string("{\"key\":[]}") == json); + } + + SECTION("containsKey()") { + char json[] = "{\"key\":\"value\"}"; + deserializeJson(doc, json); + JsonObject &obj = doc.as(); + REQUIRE(true == obj.containsKey(std::string("key"))); + } + + SECTION("remove()") { + JsonObject &obj = doc.to(); + obj["key"] = "value"; + + obj.remove(std::string("key")); + + REQUIRE(0 == obj.size()); + } + + SECTION("operator[], set key") { + std::string key("hello"); + JsonObject &obj = doc.to(); + obj[key] = "world"; + eraseString(key); + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("operator[], set value") { + std::string value("world"); + JsonObject &obj = doc.to(); + obj["hello"] = value; + eraseString(value); + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("memoryUsage() increases when adding a new key") { + std::string key1("hello"), key2("world"); + JsonObject &obj = doc.to(); + + obj[key1] = 1; + size_t sizeBefore = doc.memoryUsage(); + obj[key2] = 2; + size_t sizeAfter = doc.memoryUsage(); + + REQUIRE(sizeAfter - sizeBefore >= key2.size()); + } + + SECTION("memoryUsage() remains when adding the same key") { + std::string key("hello"); + JsonObject &obj = doc.to(); + + obj[key] = 1; + size_t sizeBefore = doc.memoryUsage(); + obj[key] = 2; + size_t sizeAfter = doc.memoryUsage(); + + REQUIRE(sizeBefore == sizeAfter); + } +} diff --git a/test/JsonSerializer/CMakeLists.txt b/test/JsonSerializer/CMakeLists.txt index f513ca1d2..1dc605dc4 100644 --- a/test/JsonSerializer/CMakeLists.txt +++ b/test/JsonSerializer/CMakeLists.txt @@ -8,6 +8,8 @@ add_executable(JsonSerializerTests JsonObject.cpp JsonObjectPretty.cpp JsonVariant.cpp + std_stream.cpp + std_string.cpp ) target_link_libraries(JsonSerializerTests catch) diff --git a/test/JsonSerializer/std_stream.cpp b/test/JsonSerializer/std_stream.cpp new file mode 100644 index 000000000..0d52846ad --- /dev/null +++ b/test/JsonSerializer/std_stream.cpp @@ -0,0 +1,64 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include +#include + +TEST_CASE("operator<<(std::ostream)") { + DynamicJsonDocument doc; + std::ostringstream os; + + SECTION("JsonVariant containing false") { + JsonVariant variant = false; + + os << variant; + + REQUIRE("false" == os.str()); + } + + SECTION("JsonVariant containing string") { + JsonVariant variant = "coucou"; + + os << variant; + + REQUIRE("\"coucou\"" == os.str()); + } + + SECTION("JsonObject") { + JsonObject& object = doc.to(); + object["key"] = "value"; + + os << object; + + REQUIRE("{\"key\":\"value\"}" == os.str()); + } + + SECTION("JsonObjectSubscript") { + JsonObject& object = doc.to(); + object["key"] = "value"; + + os << object["key"]; + + REQUIRE("\"value\"" == os.str()); + } + + SECTION("JsonArray") { + JsonArray& array = doc.to(); + array.add("value"); + + os << array; + + REQUIRE("[\"value\"]" == os.str()); + } + + SECTION("JsonArraySubscript") { + JsonArray& array = doc.to(); + array.add("value"); + + os << array[0]; + + REQUIRE("\"value\"" == os.str()); + } +} diff --git a/test/JsonSerializer/std_string.cpp b/test/JsonSerializer/std_string.cpp new file mode 100644 index 000000000..2d9608a41 --- /dev/null +++ b/test/JsonSerializer/std_string.cpp @@ -0,0 +1,47 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("serialize JsonArray to std::string") { + DynamicJsonDocument doc; + JsonArray &array = doc.to(); + array.add(4); + array.add(2); + + SECTION("serializeJson()") { + std::string json; + serializeJson(array, json); + + REQUIRE(std::string("[4,2]") == json); + } + + SECTION("serializeJsonPretty") { + std::string json; + serializeJsonPretty(array, json); + + REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json); + } +} + +TEST_CASE("serialize JsonObject to std::string") { + DynamicJsonDocument doc; + JsonObject &obj = doc.to(); + obj["key"] = "value"; + + SECTION("object") { + std::string json; + serializeJson(doc, json); + + REQUIRE(std::string("{\"key\":\"value\"}") == json); + } + + SECTION("serializeJsonPretty") { + std::string json; + serializeJsonPretty(doc, json); + + REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); + } +} diff --git a/test/Misc/CMakeLists.txt b/test/Misc/CMakeLists.txt index 28e273d02..69db9af76 100644 --- a/test/Misc/CMakeLists.txt +++ b/test/Misc/CMakeLists.txt @@ -2,10 +2,8 @@ # Copyright Benoit Blanchon 2014-2018 # MIT License -add_executable(MiscTests +add_executable(MiscTests FloatParts.cpp - std_stream.cpp - std_string.cpp StringBuilder.cpp StringTraits.cpp TypeTraits.cpp diff --git a/test/Misc/std_stream.cpp b/test/Misc/std_stream.cpp deleted file mode 100644 index 5ac6701f9..000000000 --- a/test/Misc/std_stream.cpp +++ /dev/null @@ -1,88 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include -#include - -TEST_CASE("std::stream") { - SECTION("JsonVariantFalse") { - std::ostringstream os; - JsonVariant variant = false; - os << variant; - REQUIRE("false" == os.str()); - } - - SECTION("JsonVariantString") { - std::ostringstream os; - JsonVariant variant = "coucou"; - os << variant; - REQUIRE("\"coucou\"" == os.str()); - } - - SECTION("JsonObject") { - std::ostringstream os; - DynamicJsonDocument doc; - JsonObject& object = doc.to(); - object["key"] = "value"; - os << object; - REQUIRE("{\"key\":\"value\"}" == os.str()); - } - - SECTION("JsonObjectSubscript") { - std::ostringstream os; - DynamicJsonDocument doc; - JsonObject& object = doc.to(); - object["key"] = "value"; - os << object["key"]; - REQUIRE("\"value\"" == os.str()); - } - - SECTION("JsonArray") { - std::ostringstream os; - DynamicJsonDocument doc; - JsonArray& array = doc.to(); - array.add("value"); - os << array; - REQUIRE("[\"value\"]" == os.str()); - } - - SECTION("JsonArraySubscript") { - std::ostringstream os; - DynamicJsonDocument doc; - JsonArray& array = doc.to(); - array.add("value"); - os << array[0]; - REQUIRE("\"value\"" == os.str()); - } - - SECTION("ParseArray") { - std::istringstream json(" [ 42 /* comment */ ] "); - DynamicJsonDocument doc; - JsonError err = deserializeJson(doc, json); - JsonArray& arr = doc.as(); - - REQUIRE(err == JsonError::Ok); - REQUIRE(1 == arr.size()); - REQUIRE(42 == arr[0]); - } - - SECTION("ParseObject") { - std::istringstream json(" { hello : world // comment\n }"); - DynamicJsonDocument doc; - JsonError err = deserializeJson(doc, json); - JsonObject& obj = doc.as(); - - REQUIRE(err == JsonError::Ok); - REQUIRE(1 == obj.size()); - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("ShouldNotReadPastTheEnd") { - std::istringstream json("{}123"); - DynamicJsonDocument doc; - deserializeJson(doc, json); - REQUIRE('1' == json.get()); - } -} diff --git a/test/Misc/std_string.cpp b/test/Misc/std_string.cpp deleted file mode 100644 index 4765f7078..000000000 --- a/test/Misc/std_string.cpp +++ /dev/null @@ -1,259 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -static void eraseString(std::string &str) { - char *p = const_cast(str.c_str()); - while (*p) *p++ = '*'; -} - -TEST_CASE("std::string") { - SECTION("deserializeJson duplicates content") { - std::string json("[\"hello\"]"); - - DynamicJsonDocument doc; - JsonError err = deserializeJson(doc, json); - eraseString(json); - - JsonArray &array = doc.as(); - REQUIRE(err == JsonError::Ok); - REQUIRE(std::string("hello") == array[0]); - } - - SECTION("JsonArray") { - DynamicJsonDocument doc; - JsonArray &array = doc.to(); - - SECTION("add()") { - std::string value("hello"); - array.add(value); - eraseString(value); - REQUIRE(std::string("hello") == array[0]); - } - - SECTION("set()") { - std::string value("world"); - array.add("hello"); - array.set(0, value); - eraseString(value); - REQUIRE(std::string("world") == array[0]); - } - - SECTION("operator[]") { - std::string value("world"); - array.add("hello"); - array[0] = value; - eraseString(value); - REQUIRE(std::string("world") == array[0]); - } - - SECTION("serializeJson()") { - array.add(4); - array.add(2); - std::string json; - serializeJson(array, json); - REQUIRE(std::string("[4,2]") == json); - } - - SECTION("serializeJsonPretty()") { - array.add(4); - array.add(2); - std::string json; - serializeJsonPretty(array, json); - REQUIRE(std::string("[\r\n 4,\r\n 2\r\n]") == json); - } - } - - SECTION("JsonObject") { - DynamicJsonDocument doc; - - SECTION("deserializeJson()") { - std::string json("{\"hello\":\"world\"}"); - - JsonError err = deserializeJson(doc, json); - JsonObject &obj = doc.as(); - eraseString(json); - - REQUIRE(err == JsonError::Ok); - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("operator[]") { - char json[] = "{\"key\":\"value\"}"; - - deserializeJson(doc, json); - JsonObject &obj = doc.as(); - - REQUIRE(std::string("value") == obj[std::string("key")]); - } - - SECTION("operator[] const") { - char json[] = "{\"key\":\"value\"}"; - - deserializeJson(doc, json); - JsonObject &obj = doc.as(); - - REQUIRE(std::string("value") == obj[std::string("key")]); - } - - SECTION("set(key)") { - JsonObject &obj = doc.to(); - std::string key("hello"); - obj.set(key, "world"); - eraseString(key); - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("set(value)") { - JsonObject &obj = doc.to(); - std::string value("world"); - obj.set("hello", value); - eraseString(value); - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("set(key,value)") { - JsonObject &obj = doc.to(); - std::string key("hello"); - std::string value("world"); - obj.set(key, value); - eraseString(key); - eraseString(value); - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("set(JsonArraySubscript)") { - JsonObject &obj = doc.to(); - DynamicJsonDocument doc2; - JsonArray &arr = doc2.to(); - arr.add("world"); - - obj.set(std::string("hello"), arr[0]); - - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("set(JsonObjectSubscript)") { - JsonObject &obj = doc.to(); - DynamicJsonDocument doc2; - JsonObject &obj2 = doc2.to(); - obj2.set("x", "world"); - - obj.set(std::string("hello"), obj2["x"]); - - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("get()") { - char json[] = "{\"key\":\"value\"}"; - deserializeJson(doc, json); - JsonObject &obj = doc.as(); - - REQUIRE(std::string("value") == - obj.get(std::string("key"))); - } - - SECTION("is()") { - char json[] = "{\"key\":\"value\"}"; - deserializeJson(doc, json); - JsonObject &obj = doc.as(); - - REQUIRE(true == obj.is(std::string("key"))); - } - - SECTION("createNestedObject()") { - JsonObject &obj = doc.to(); - std::string key = "key"; - char json[64]; - obj.createNestedObject(key); - eraseString(key); - serializeJson(doc, json, sizeof(json)); - REQUIRE(std::string("{\"key\":{}}") == json); - } - - SECTION("createNestedArray()") { - JsonObject &obj = doc.to(); - std::string key = "key"; - char json[64]; - obj.createNestedArray(key); - eraseString(key); - serializeJson(doc, json, sizeof(json)); - REQUIRE(std::string("{\"key\":[]}") == json); - } - - SECTION("containsKey()") { - char json[] = "{\"key\":\"value\"}"; - deserializeJson(doc, json); - JsonObject &obj = doc.as(); - REQUIRE(true == obj.containsKey(std::string("key"))); - } - - SECTION("remove()") { - JsonObject &obj = doc.to(); - obj["key"] = "value"; - - obj.remove(std::string("key")); - - REQUIRE(0 == obj.size()); - } - - SECTION("operator[], set key") { - std::string key("hello"); - JsonObject &obj = doc.to(); - obj[key] = "world"; - eraseString(key); - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("operator[], set value") { - std::string value("world"); - JsonObject &obj = doc.to(); - obj["hello"] = value; - eraseString(value); - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("serializeJson()") { - JsonObject &obj = doc.to(); - obj["key"] = "value"; - std::string json; - serializeJson(doc, json); - REQUIRE(std::string("{\"key\":\"value\"}") == json); - } - - SECTION("serializeJsonPretty()") { - JsonObject &obj = doc.to(); - obj["key"] = "value"; - std::string json; - serializeJsonPretty(doc, json); - REQUIRE(std::string("{\r\n \"key\": \"value\"\r\n}") == json); - } - - SECTION("memoryUsage() increases when adding a new key") { - std::string key1("hello"), key2("world"); - JsonObject &obj = doc.to(); - - obj[key1] = 1; - size_t sizeBefore = doc.memoryUsage(); - obj[key2] = 2; - size_t sizeAfter = doc.memoryUsage(); - - REQUIRE(sizeAfter - sizeBefore >= key2.size()); - } - - SECTION("memoryUsage() remains when adding the same key") { - std::string key("hello"); - JsonObject &obj = doc.to(); - - obj[key] = 1; - size_t sizeBefore = doc.memoryUsage(); - obj[key] = 2; - size_t sizeAfter = doc.memoryUsage(); - - REQUIRE(sizeBefore == sizeAfter); - } - } -} diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 87f3cab63..4471e6767 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -9,259 +9,267 @@ #define CONFLICTS_WITH_BUILTIN_OPERATOR #endif -TEST_CASE("unsigned char string") { - SECTION("JsonBuffer::parseArray") { - unsigned char json[] = "[42]"; +TEST_CASE("unsigned char[]") { + SECTION("deserializeJson()") { + unsigned char input[] = "{\"a\":42}"; - StaticJsonDocument doc; - JsonError err = deserializeJson(doc, json); + StaticJsonDocument doc; + JsonError err = deserializeJson(doc, input); REQUIRE(err == JsonError::Ok); } - SECTION("JsonBuffer::parseObject") { - unsigned char json[] = "{\"a\":42}"; + SECTION("deserializeMsgPack()") { + unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world"; - StaticJsonDocument doc; - JsonError err = deserializeJson(doc, json); + StaticJsonDocument doc; + MsgPackError err = deserializeMsgPack(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == MsgPackError::Ok); } - SECTION("JsonVariant constructor") { - unsigned char value[] = "42"; + SECTION("JsonVariant") { + SECTION("constructor") { + unsigned char value[] = "42"; - JsonVariant variant(value); + JsonVariant variant(value); - REQUIRE(42 == variant.as()); - } + REQUIRE(42 == variant.as()); + } - SECTION("JsonVariant assignment operator") { - unsigned char value[] = "42"; + SECTION("operator=") { + unsigned char value[] = "42"; - JsonVariant variant(666); - variant = value; + JsonVariant variant(666); + variant = value; - REQUIRE(42 == variant.as()); - } + REQUIRE(42 == variant.as()); + } #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonVariant::operator[]") { - unsigned char key[] = "hello"; + SECTION("operator[]") { + unsigned char key[] = "hello"; - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - JsonVariant variant = doc.as(); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonVariant variant = doc.as(); - REQUIRE(std::string("world") == variant[key]); - } + REQUIRE(std::string("world") == variant[key]); + } #endif #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonVariant::operator[] const") { - unsigned char key[] = "hello"; + SECTION("operator[] const") { + unsigned char key[] = "hello"; - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - const JsonVariant variant = doc.as(); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + const JsonVariant variant = doc.as(); - REQUIRE(std::string("world") == variant[key]); - } + REQUIRE(std::string("world") == variant[key]); + } #endif - SECTION("JsonVariant::operator==") { - unsigned char comparand[] = "hello"; + SECTION("operator==") { + unsigned char comparand[] = "hello"; - JsonVariant variant; - variant = "hello"; + JsonVariant variant; + variant = "hello"; - REQUIRE(comparand == variant); - REQUIRE(variant == comparand); - REQUIRE_FALSE(comparand != variant); - REQUIRE_FALSE(variant != comparand); - } + REQUIRE(comparand == variant); + REQUIRE(variant == comparand); + REQUIRE_FALSE(comparand != variant); + REQUIRE_FALSE(variant != comparand); + } - SECTION("JsonVariant::operator!=") { - unsigned char comparand[] = "hello"; + SECTION("operator!=") { + unsigned char comparand[] = "hello"; - JsonVariant variant; - variant = "world"; + JsonVariant variant; + variant = "world"; - REQUIRE(comparand != variant); - REQUIRE(variant != comparand); - REQUIRE_FALSE(comparand == variant); - REQUIRE_FALSE(variant == comparand); + REQUIRE(comparand != variant); + REQUIRE(variant != comparand); + REQUIRE_FALSE(comparand == variant); + REQUIRE_FALSE(variant == comparand); + } } + SECTION("JsonObject") { #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonObject::operator[]") { - unsigned char key[] = "hello"; + SECTION("operator[]") { + unsigned char key[] = "hello"; - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj[key] = "world"; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj[key] = "world"; - REQUIRE(std::string("world") == obj["hello"]); - } -#endif + REQUIRE(std::string("world") == obj["hello"]); + } - SECTION("JsonObjectSubscript::operator=") { // issue #416 - unsigned char value[] = "world"; + SECTION("JsonObject::operator[] const") { + unsigned char key[] = "hello"; - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj["hello"] = value; + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); - REQUIRE(std::string("world") == obj["hello"]); - } + JsonObject& obj = doc.as(); + REQUIRE(std::string("world") == obj[key]); + } +#endif - SECTION("JsonObjectSubscript::set()") { - unsigned char value[] = "world"; + SECTION("get()") { + unsigned char key[] = "hello"; - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj["hello"].set(value); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + REQUIRE(std::string("world") == obj.get(key)); + } - REQUIRE(std::string("world") == obj["hello"]); - } + SECTION("set() key") { + unsigned char key[] = "hello"; -#ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonObject::operator[] const") { - unsigned char key[] = "hello"; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.set(key, "world"); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); + REQUIRE(std::string("world") == obj["hello"]); + } - JsonObject& obj = doc.as(); - REQUIRE(std::string("world") == obj[key]); - } -#endif + SECTION("set() value") { + unsigned char value[] = "world"; - SECTION("JsonObject::get()") { - unsigned char key[] = "hello"; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.set("hello", value); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - JsonObject& obj = doc.as(); - REQUIRE(std::string("world") == obj.get(key)); - } + REQUIRE(std::string("world") == obj["hello"]); + } - SECTION("JsonObject::set() key") { - unsigned char key[] = "hello"; + SECTION("set() key&value") { + unsigned char key[] = "world"; - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.set(key, "world"); + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.set(key, key); - REQUIRE(std::string("world") == obj["hello"]); - } + REQUIRE(std::string("world") == obj["world"]); + } - SECTION("JsonObject::set() value") { - unsigned char value[] = "world"; + SECTION("containsKey()") { + unsigned char key[] = "hello"; - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.set("hello", value); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + REQUIRE(true == obj.containsKey(key)); + } - REQUIRE(std::string("world") == obj["hello"]); - } + SECTION("remove()") { + unsigned char key[] = "hello"; - SECTION("JsonObject::set key&value") { - unsigned char key[] = "world"; + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + obj.remove(key); - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.set(key, key); + REQUIRE(0 == obj.size()); + } - REQUIRE(std::string("world") == obj["world"]); - } + SECTION("is()") { + unsigned char key[] = "hello"; - SECTION("JsonObject::containsKey()") { - unsigned char key[] = "hello"; + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":42}"); + JsonObject& obj = doc.as(); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - JsonObject& obj = doc.as(); - REQUIRE(true == obj.containsKey(key)); - } + REQUIRE(true == obj.is(key)); + } - SECTION("JsonObject::remove()") { - unsigned char key[] = "hello"; + SECTION("createNestedArray()") { + unsigned char key[] = "hello"; - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - JsonObject& obj = doc.as(); - obj.remove(key); + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.createNestedArray(key); + } - REQUIRE(0 == obj.size()); - } + SECTION("createNestedObject()") { + unsigned char key[] = "hello"; - SECTION("JsonObject::is()") { - unsigned char key[] = "hello"; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.createNestedObject(key); + } + } - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":42}"); - JsonObject& obj = doc.as(); + SECTION("JsonObjectSubscript") { + SECTION("operator=") { // issue #416 + unsigned char value[] = "world"; - REQUIRE(true == obj.is(key)); - } + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj["hello"] = value; - SECTION("JsonObject::createNestedArray()") { - unsigned char key[] = "hello"; + REQUIRE(std::string("world") == obj["hello"]); + } - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.createNestedArray(key); - } + SECTION("set()") { + unsigned char value[] = "world"; - SECTION("JsonObject::createNestedObject()") { - unsigned char key[] = "hello"; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj["hello"].set(value); - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.createNestedObject(key); + REQUIRE(std::string("world") == obj["hello"]); + } } - SECTION("JsonArray::add()") { - unsigned char value[] = "world"; + SECTION("JsonArray") { + SECTION("add()") { + unsigned char value[] = "world"; - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add(value); + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add(value); - REQUIRE(std::string("world") == arr[0]); - } + REQUIRE(std::string("world") == arr[0]); + } - SECTION("JsonArray::set()") { - unsigned char value[] = "world"; + SECTION("set()") { + unsigned char value[] = "world"; - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add("hello"); - arr.set(0, value); + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + arr.set(0, value); - REQUIRE(std::string("world") == arr[0]); + REQUIRE(std::string("world") == arr[0]); + } } - SECTION("JsonArraySubscript::set()") { - unsigned char value[] = "world"; + SECTION("JsonArraySubscript") { + SECTION("set()") { + unsigned char value[] = "world"; - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add("hello"); - arr[0].set(value); + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + arr[0].set(value); - REQUIRE(std::string("world") == arr[0]); - } + REQUIRE(std::string("world") == arr[0]); + } - SECTION("JsonArraySubscript::operator=") { - unsigned char value[] = "world"; + SECTION("operator=") { + unsigned char value[] = "world"; - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add("hello"); - arr[0] = value; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + arr[0] = value; - REQUIRE(std::string("world") == arr[0]); + REQUIRE(std::string("world") == arr[0]); + } } } diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 2fd84453b..89207c89b 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -17,322 +17,321 @@ #ifndef VLA_NOT_SUPPORTED TEST_CASE("Variable Length Array") { - SECTION("ParseArray") { - int i = 8; + SECTION("deserializeJson()") { + int i = 9; char vla[i]; - strcpy(vla, "[42]"); + strcpy(vla, "{\"a\":42}"); - StaticJsonDocument doc; + StaticJsonDocument doc; JsonError err = deserializeJson(doc, vla); REQUIRE(err == JsonError::Ok); } - SECTION("ParseObject") { + SECTION("deserializeMsgPack()") { int i = 16; char vla[i]; - strcpy(vla, "{\"a\":42}"); + memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); StaticJsonDocument doc; - JsonError error = deserializeJson(doc, vla); + MsgPackError err = deserializeMsgPack(doc, vla); - REQUIRE(error == JsonError::Ok); + REQUIRE(err == MsgPackError::Ok); } - SECTION("Parse") { - int i = 16; - char vla[i]; - strcpy(vla, "42"); + SECTION("JsonVariant") { + SECTION("constructor") { + int i = 16; + char vla[i]; + strcpy(vla, "42"); - StaticJsonDocument<> variant; - deserializeJson(variant, vla); + JsonVariant variant(vla); - REQUIRE(42 == variant.as()); - } + REQUIRE(42 == variant.as()); + } - SECTION("JsonVariant_Constructor") { - int i = 16; - char vla[i]; - strcpy(vla, "42"); - - JsonVariant variant(vla); - - REQUIRE(42 == variant.as()); - } + SECTION("operator=") { + int i = 16; + char vla[i]; + strcpy(vla, "42"); - SECTION("JsonVariant_Assign") { - int i = 16; - char vla[i]; - strcpy(vla, "42"); + JsonVariant variant(666); + variant = vla; - JsonVariant variant(666); - variant = vla; - - REQUIRE(42 == variant.as()); - } + REQUIRE(42 == variant.as()); + } #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonVariant_Subscript") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + SECTION("operator[]") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - JsonVariant variant = doc.as(); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonVariant variant = doc.as(); - REQUIRE(std::string("world") == variant[vla]); - } + REQUIRE(std::string("world") == variant[vla]); + } #endif #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonVariant_Subscript_Const") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + SECTION("operator[] const") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - const JsonVariant variant = doc.as(); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + const JsonVariant variant = doc.as(); - REQUIRE(std::string("world") == variant[vla]); - } + REQUIRE(std::string("world") == variant[vla]); + } #endif - SECTION("JsonVariant_Equals") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); - - JsonVariant variant; - variant = "hello"; - - REQUIRE((vla == variant)); - REQUIRE((variant == vla)); - REQUIRE_FALSE((vla != variant)); - REQUIRE_FALSE((variant != vla)); - } - - SECTION("JsonVariant_Differs") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); - - JsonVariant variant; - variant = "world"; - - REQUIRE((vla != variant)); - REQUIRE((variant != vla)); - REQUIRE_FALSE((vla == variant)); - REQUIRE_FALSE((variant == vla)); + SECTION("operator==") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + JsonVariant variant; + variant = "hello"; + + REQUIRE((vla == variant)); + REQUIRE((variant == vla)); + REQUIRE_FALSE((vla != variant)); + REQUIRE_FALSE((variant != vla)); + } + + SECTION("operator!=") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + JsonVariant variant; + variant = "world"; + + REQUIRE((vla != variant)); + REQUIRE((variant != vla)); + REQUIRE_FALSE((vla == variant)); + REQUIRE_FALSE((variant == vla)); + } } + SECTION("JsonObject") { #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonObject_Subscript") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + SECTION("operator[]") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj[vla] = "world"; + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj[vla] = "world"; - REQUIRE(std::string("world") == obj["hello"]); - } + REQUIRE(std::string("world") == obj["hello"]); + } #endif - SECTION("JsonObject_Subscript_Assign") { // issue #416 - int i = 32; - char vla[i]; - strcpy(vla, "world"); - - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj["hello"] = vla; - - REQUIRE(std::string("world") == obj["hello"].as()); - } - - SECTION("JsonObject_Subscript_Set") { - int i = 32; - char vla[i]; - strcpy(vla, "world"); - - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj["hello"].set(vla); - - REQUIRE(std::string("world") == obj["hello"].as()); - } - #ifndef CONFLICTS_WITH_BUILTIN_OPERATOR - SECTION("JsonObject_Subscript_Const") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + SECTION("operator[] const") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); - JsonObject& obj = doc.as(); - REQUIRE(std::string("world") == obj[vla]); - } + JsonObject& obj = doc.as(); + REQUIRE(std::string("world") == obj[vla]); + } #endif - SECTION("JsonObject_Get") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); - - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - - JsonObject& obj = doc.as(); - REQUIRE(std::string("world") == obj.get(vla)); - } - - SECTION("JsonObject_Set_Key") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); - - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.set(vla, "world"); - - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("JsonObject_Set_Value") { - int i = 16; - char vla[i]; - strcpy(vla, "world"); - - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.set("hello", vla); - - REQUIRE(std::string("world") == obj["hello"]); - } - - SECTION("JsonObject_Set_KeyAndValue") { - int i = 16; - char vla[i]; - strcpy(vla, "world"); - - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.set(vla, vla); - - REQUIRE(std::string("world") == obj["world"]); - } - - SECTION("JsonObject_ContainsKey") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); - - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - - JsonObject& obj = doc.as(); - REQUIRE(true == obj.containsKey(vla)); + SECTION("get()") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + + JsonObject& obj = doc.as(); + REQUIRE(std::string("world") == obj.get(vla)); + } + + SECTION("set() key") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.set(vla, "world"); + + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("set() value") { + int i = 16; + char vla[i]; + strcpy(vla, "world"); + + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.set("hello", vla); + + REQUIRE(std::string("world") == obj["hello"]); + } + + SECTION("set() key&value") { + int i = 16; + char vla[i]; + strcpy(vla, "world"); + + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.set(vla, vla); + + REQUIRE(std::string("world") == obj["world"]); + } + + SECTION("containsKey()") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + + JsonObject& obj = doc.as(); + REQUIRE(true == obj.containsKey(vla)); + } + + SECTION("remove()") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":\"world\"}"); + JsonObject& obj = doc.as(); + obj.remove(vla); + + REQUIRE(0 == obj.size()); + } + + SECTION("is()") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + DynamicJsonDocument doc; + deserializeJson(doc, "{\"hello\":42}"); + JsonObject& obj = doc.as(); + + REQUIRE(true == obj.is(vla)); + } + + SECTION("createNestedArray()") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.createNestedArray(vla); + } + + SECTION("createNestedObject()") { + int i = 16; + char vla[i]; + strcpy(vla, "hello"); + + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj.createNestedObject(vla); + } } - SECTION("JsonObject_Remove") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + SECTION("JsonObjectSubscript") { + SECTION("operator=") { // issue #416 + int i = 32; + char vla[i]; + strcpy(vla, "world"); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":\"world\"}"); - JsonObject& obj = doc.as(); - obj.remove(vla); + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj["hello"] = vla; - REQUIRE(0 == obj.size()); - } + REQUIRE(std::string("world") == obj["hello"].as()); + } - SECTION("JsonObject_Is") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + SECTION("set()") { + int i = 32; + char vla[i]; + strcpy(vla, "world"); - DynamicJsonDocument doc; - deserializeJson(doc, "{\"hello\":42}"); - JsonObject& obj = doc.as(); + DynamicJsonDocument doc; + JsonObject& obj = doc.to(); + obj["hello"].set(vla); - REQUIRE(true == obj.is(vla)); + REQUIRE(std::string("world") == obj["hello"].as()); + } } - SECTION("JsonObject_CreateNestedArray") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + SECTION("JsonArray") { + SECTION("add()") { + int i = 16; + char vla[i]; + strcpy(vla, "world"); - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.createNestedArray(vla); - } + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add(vla); - SECTION("JsonObject_CreateNestedObject") { - int i = 16; - char vla[i]; - strcpy(vla, "hello"); + REQUIRE(std::string("world") == arr[0]); + } - DynamicJsonDocument doc; - JsonObject& obj = doc.to(); - obj.createNestedObject(vla); - } + SECTION("set()") { + int i = 16; + char vla[i]; + strcpy(vla, "world"); - SECTION("JsonArray_Add") { - int i = 16; - char vla[i]; - strcpy(vla, "world"); + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + arr.set(0, vla); - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add(vla); - - REQUIRE(std::string("world") == arr[0]); - } - - SECTION("JsonArray_Set") { - int i = 16; - char vla[i]; - strcpy(vla, "world"); - - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add("hello"); - arr.set(0, vla); - - REQUIRE(std::string("world") == arr[0]); + REQUIRE(std::string("world") == arr[0]); + } } - SECTION("JsonArraySubscript_Set") { - int i = 16; - char vla[i]; - strcpy(vla, "world"); + SECTION("JsonArraySubscript") { + SECTION("set()") { + int i = 16; + char vla[i]; + strcpy(vla, "world"); - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add("hello"); - arr[0].set(vla); + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + arr[0].set(vla); - REQUIRE(std::string("world") == arr[0]); - } + REQUIRE(std::string("world") == arr[0]); + } - SECTION("JsonArraySubscript_Assign") { - int i = 16; - char vla[i]; - strcpy(vla, "world"); + SECTION("operator=") { + int i = 16; + char vla[i]; + strcpy(vla, "world"); - DynamicJsonDocument doc; - JsonArray& arr = doc.to(); - arr.add("hello"); - arr[0] = vla; + DynamicJsonDocument doc; + JsonArray& arr = doc.to(); + arr.add("hello"); + arr[0] = vla; - REQUIRE(std::string("world") == arr[0]); + REQUIRE(std::string("world") == arr[0]); + } } } #endif diff --git a/test/MsgPack/CMakeLists.txt b/test/MsgPack/CMakeLists.txt index b816549e8..4565892b0 100644 --- a/test/MsgPack/CMakeLists.txt +++ b/test/MsgPack/CMakeLists.txt @@ -3,13 +3,17 @@ # MIT License add_executable(MsgPackTests - deserializationErrors.cpp + MsgPackError.cpp deserializeArray.cpp deserializeObject.cpp - deserializeVariant.cpp deserializeStaticVariant.cpp + deserializeVariant.cpp doubleToFloat.cpp - MsgPackError.cpp + incompleteInput.cpp + nestingLimit.cpp + notSupported.cpp + std_string.cpp + std_istream.cpp ) target_link_libraries(MsgPackTests catch) diff --git a/test/MsgPack/MsgPackError.cpp b/test/MsgPack/MsgPackError.cpp index 3f070260b..eba414344 100644 --- a/test/MsgPack/MsgPackError.cpp +++ b/test/MsgPack/MsgPackError.cpp @@ -25,6 +25,7 @@ TEST_CASE("MsgPackError") { TEST_STRINGIFICATION(NotSupported); TEST_STRINGIFICATION(NoMemory); TEST_STRINGIFICATION(TooDeep); + TEST_STRINGIFICATION(IncompleteInput); } SECTION("as boolean") { @@ -32,6 +33,7 @@ TEST_CASE("MsgPackError") { TEST_BOOLIFICATION(NotSupported, true); TEST_BOOLIFICATION(NoMemory, true); TEST_BOOLIFICATION(TooDeep, true); + TEST_BOOLIFICATION(IncompleteInput, true); } SECTION("ostream") { diff --git a/test/MsgPack/deserializationErrors.cpp b/test/MsgPack/deserializationErrors.cpp deleted file mode 100644 index 1ece18bc0..000000000 --- a/test/MsgPack/deserializationErrors.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -static void check(const char* input, MsgPackError expected, - uint8_t nestingLimit = 10) { - DynamicJsonDocument doc; - doc.nestingLimit = nestingLimit; - - MsgPackError error = deserializeMsgPack(doc, input); - - REQUIRE(error == expected); -} - -TEST_CASE("Errors returned by deserializeMsgPack()") { - SECTION("unsupported") { - check("\xc4", MsgPackError::NotSupported); // bin 8 - check("\xc5", MsgPackError::NotSupported); // bin 16 - check("\xc6", MsgPackError::NotSupported); // bin 32 - check("\xc7", MsgPackError::NotSupported); // ext 8 - check("\xc8", MsgPackError::NotSupported); // ext 16 - check("\xc9", MsgPackError::NotSupported); // ext 32 - check("\xd4", MsgPackError::NotSupported); // fixext 1 - check("\xd5", MsgPackError::NotSupported); // fixext 2 - check("\xd6", MsgPackError::NotSupported); // fixext 4 - check("\xd7", MsgPackError::NotSupported); // fixext 8 - check("\xd8", MsgPackError::NotSupported); // fixext 16 - } - - SECTION("unsupported in array") { - check("\x91\xc4", MsgPackError::NotSupported); - } - - SECTION("unsupported in map") { - check("\x81\xc4\x00\xA1H", MsgPackError::NotSupported); - check("\x81\xA1H\xc4\x00", MsgPackError::NotSupported); - } - - SECTION("integer as key") { - check("\x81\x01\xA1H", MsgPackError::NotSupported); - } - - SECTION("object too deep") { - check("\x80", MsgPackError::TooDeep, 0); // {} - check("\x80", MsgPackError::Ok, 1); // {} - check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}} - check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}} - } - - SECTION("array too deep") { - check("\x90", MsgPackError::TooDeep, 0); // [] - check("\x90", MsgPackError::Ok, 1); // [] - check("\x91\x90", MsgPackError::TooDeep, 1); // [[]] - check("\x91\x90", MsgPackError::Ok, 2); // [[]] - } -} diff --git a/test/MsgPack/incompleteInput.cpp b/test/MsgPack/incompleteInput.cpp new file mode 100644 index 000000000..8d1715c83 --- /dev/null +++ b/test/MsgPack/incompleteInput.cpp @@ -0,0 +1,106 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +MsgPackError deserialize(const char* input, size_t len) { + DynamicJsonDocument doc; + + return deserializeMsgPack(doc, input, len); +} + +void checkAllSizes(const char* input, size_t len) { + REQUIRE(deserialize(input, len) == MsgPackError::Ok); + + while (--len) { + REQUIRE(deserialize(input, len) == MsgPackError::IncompleteInput); + } +} + +TEST_CASE("deserializeMsgPack() returns IncompleteInput") { + SECTION("empty input") { + checkAllSizes("\x00", 1); + } + + SECTION("fixarray") { + checkAllSizes("\x91\x01", 2); + } + + SECTION("array 16") { + checkAllSizes("\xDC\x00\x01\x01", 4); + } + + SECTION("array 32") { + checkAllSizes("\xDD\x00\x00\x00\x01\x01", 6); + } + + SECTION("fixmap") { + checkAllSizes("\x81\xA3one\x01", 6); + } + + SECTION("map 16") { + checkAllSizes("\xDE\x00\x01\xA3one\x01", 8); + } + + SECTION("map 32") { + checkAllSizes("\xDF\x00\x00\x00\x01\xA3one\x01", 10); + } + + SECTION("uint 8") { + checkAllSizes("\xcc\x01", 2); + } + + SECTION("uint 16") { + checkAllSizes("\xcd\x00\x01", 3); + } + + SECTION("uint 32") { + checkAllSizes("\xCE\x00\x00\x00\x01", 5); + } + + SECTION("uint 64") { + checkAllSizes("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 9); + } + + SECTION("int 8") { + checkAllSizes("\xD0\x01", 2); + } + + SECTION("int 16") { + checkAllSizes("\xD1\x00\x01", 3); + } + + SECTION("int 32") { + checkAllSizes("\xD2\x00\x00\x00\x01", 5); + } + + SECTION("int 64") { + checkAllSizes("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", 9); + } + + SECTION("float 32") { + checkAllSizes("\xCA\x40\x48\xF5\xC3", 5); + } + + SECTION("float 64") { + checkAllSizes("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 9); + } + + SECTION("fixstr") { + checkAllSizes("\xABhello world", 12); + } + + SECTION("str 8") { + checkAllSizes("\xd9\x05hello", 7); + } + + SECTION("str 16") { + checkAllSizes("\xda\x00\x05hello", 8); + } + + SECTION("str 32") { + checkAllSizes("\xdb\x00\x00\x00\x05hello", 10); + } +} diff --git a/test/MsgPack/nestingLimit.cpp b/test/MsgPack/nestingLimit.cpp new file mode 100644 index 000000000..a56acc2fe --- /dev/null +++ b/test/MsgPack/nestingLimit.cpp @@ -0,0 +1,31 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +static void check(const char* input, MsgPackError expected, uint8_t limit) { + DynamicJsonDocument doc; + doc.nestingLimit = limit; + + MsgPackError error = deserializeMsgPack(doc, input); + + REQUIRE(error == expected); +} + +TEST_CASE("Errors returned by deserializeMsgPack()") { + SECTION("object too deep") { + check("\x80", MsgPackError::TooDeep, 0); // {} + check("\x80", MsgPackError::Ok, 1); // {} + check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}} + check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}} + } + + SECTION("array too deep") { + check("\x90", MsgPackError::TooDeep, 0); // [] + check("\x90", MsgPackError::Ok, 1); // [] + check("\x91\x90", MsgPackError::TooDeep, 1); // [[]] + check("\x91\x90", MsgPackError::Ok, 2); // [[]] + } +} diff --git a/test/MsgPack/notSupported.cpp b/test/MsgPack/notSupported.cpp new file mode 100644 index 000000000..e6ab63008 --- /dev/null +++ b/test/MsgPack/notSupported.cpp @@ -0,0 +1,73 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +static void checkNotSupported(const char* input) { + DynamicJsonDocument doc; + + MsgPackError error = deserializeMsgPack(doc, input); + + REQUIRE(error == MsgPackError::NotSupported); +} + +TEST_CASE("deserializeMsgPack() return NotSupported") { + SECTION("bin 8") { + checkNotSupported("\xc4"); + } + + SECTION("bin 16") { + checkNotSupported("\xc5"); + } + + SECTION("bin 32") { + checkNotSupported("\xc6"); + } + + SECTION("ext 8") { + checkNotSupported("\xc7"); + } + + SECTION("ext 16") { + checkNotSupported("\xc8"); + } + + SECTION("ext 32") { + checkNotSupported("\xc9"); + } + + SECTION("fixext 1") { + checkNotSupported("\xd4"); + } + + SECTION("fixext 2") { + checkNotSupported("\xd5"); + } + + SECTION("fixext 4") { + checkNotSupported("\xd6"); + } + + SECTION("fixext 8") { + checkNotSupported("\xd7"); + } + + SECTION("fixext 16") { + checkNotSupported("\xd8"); + } + + SECTION("unsupported in array") { + checkNotSupported("\x91\xc4"); + } + + SECTION("unsupported in map") { + checkNotSupported("\x81\xc4\x00\xA1H"); + checkNotSupported("\x81\xA1H\xc4\x00"); + } + + SECTION("integer as key") { + checkNotSupported("\x81\x01\xA1H"); + } +} diff --git a/test/MsgPack/std_istream.cpp b/test/MsgPack/std_istream.cpp new file mode 100644 index 000000000..d04dc935d --- /dev/null +++ b/test/MsgPack/std_istream.cpp @@ -0,0 +1,29 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeMsgPack(std::istream&)") { + DynamicJsonDocument doc; + + SECTION("should accept a zero in input") { + std::istringstream input(std::string("\x92\x00\x02", 3)); + + MsgPackError err = deserializeMsgPack(doc, input); + + REQUIRE(err == MsgPackError::Ok); + JsonArray& arr = doc.as(); + REQUIRE(arr[0] == 0); + REQUIRE(arr[1] == 2); + } + + SECTION("should detect incomplete input") { + std::istringstream input("\x92\x00\x02"); + + MsgPackError err = deserializeMsgPack(doc, input); + + REQUIRE(err == MsgPackError::IncompleteInput); + } +} diff --git a/test/MsgPack/std_string.cpp b/test/MsgPack/std_string.cpp new file mode 100644 index 000000000..bc3747193 --- /dev/null +++ b/test/MsgPack/std_string.cpp @@ -0,0 +1,44 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#include +#include + +TEST_CASE("deserializeMsgPack(const std::string&)") { + DynamicJsonDocument doc; + + SECTION("should accept const string") { + const std::string input("\x92\x01\x02"); + + MsgPackError err = deserializeMsgPack(doc, input); + + REQUIRE(err == MsgPackError::Ok); + } + + SECTION("should accept temporary string") { + MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x01\x02")); + + REQUIRE(err == MsgPackError::Ok); + } + + SECTION("should duplicate content") { + std::string input("\x91\xA5hello"); + + MsgPackError err = deserializeMsgPack(doc, input); + input[2] = 'X'; // alter the string tomake sure we made a copy + + JsonArray& array = doc.as(); + REQUIRE(err == MsgPackError::Ok); + REQUIRE(std::string("hello") == array[0]); + } + + SECTION("should accept a zero in input") { + MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x00\x02", 3)); + + REQUIRE(err == MsgPackError::Ok); + JsonArray& arr = doc.as(); + REQUIRE(arr[0] == 0); + REQUIRE(arr[1] == 2); + } +} From 4592f23260d5a4a75c6cce0065141de609bc2e46 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Tue, 15 May 2018 18:23:09 +0200 Subject: [PATCH 0029/1079] Merged MsgPackError and JsonError into DeserializationError. Return NotSupported if the JSON input contains "\u". --- CHANGELOG.md | 2 +- examples/JsonConfigFile/JsonConfigFile.ino | 2 +- examples/JsonHttpClient/JsonHttpClient.ino | 2 +- .../JsonParserExample/JsonParserExample.ino | 2 +- examples/MsgPackParser/MsgPackParser.ino | 2 +- fuzzing/fuzzer.cpp | 4 +- ...JsonError.hpp => DeserializationError.hpp} | 31 ++- .../Json/Deserialization/JsonDeserializer.hpp | 79 +++---- .../MsgPack/MsgPackDeserializer.hpp | 97 ++++---- src/ArduinoJson/MsgPack/MsgPackError.hpp | 74 ------ src/ArduinoJson/deserializeJson.hpp | 21 +- src/ArduinoJson/deserializeMsgPack.hpp | 18 +- test/DynamicJsonBuffer/no_memory.cpp | 4 +- test/IntegrationTests/gbathree.cpp | 4 +- test/JsonArray/copyTo.cpp | 12 +- test/JsonDeserializer/CMakeLists.txt | 2 +- ...JsonError.cpp => DeserializationError.cpp} | 14 +- .../JsonDeserializer/deserializeJsonArray.cpp | 177 +++++++------- .../deserializeJsonArrayStatic.cpp | 24 +- .../deserializeJsonObject.cpp | 216 ++++++++++-------- .../deserializeJsonObjectStatic.cpp | 20 +- .../JsonDeserializer/deserializeJsonValue.cpp | 95 ++++---- test/JsonDeserializer/nestingLimit.cpp | 5 +- test/JsonDeserializer/std_istream.cpp | 8 +- test/JsonDeserializer/std_string.cpp | 12 +- test/Misc/unsigned_char.cpp | 8 +- test/Misc/vla.cpp | 8 +- test/MsgPack/CMakeLists.txt | 1 - test/MsgPack/MsgPackError.cpp | 44 ---- test/MsgPack/deserializeArray.cpp | 24 +- test/MsgPack/deserializeObject.cpp | 24 +- test/MsgPack/deserializeStaticVariant.cpp | 111 ++++----- test/MsgPack/deserializeVariant.cpp | 4 +- test/MsgPack/incompleteInput.cpp | 6 +- test/MsgPack/nestingLimit.cpp | 21 +- test/MsgPack/notSupported.cpp | 4 +- test/MsgPack/std_istream.cpp | 8 +- test/MsgPack/std_string.cpp | 18 +- 38 files changed, 573 insertions(+), 635 deletions(-) rename src/ArduinoJson/{JsonError.hpp => DeserializationError.hpp} (52%) delete mode 100644 src/ArduinoJson/MsgPack/MsgPackError.hpp rename test/JsonDeserializer/{JsonError.cpp => DeserializationError.cpp} (66%) delete mode 100644 test/MsgPack/MsgPackError.cpp diff --git a/CHANGELOG.md b/CHANGELOG.md index dce5d9a1d..78b53dee9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,7 @@ HEAD > > ```c++ > DynamicJsonDocument doc; -> JsonError error = deserializeJson(doc, json); +> DeserializationError error = deserializeJson(doc, json); > if (error) { > > } diff --git a/examples/JsonConfigFile/JsonConfigFile.ino b/examples/JsonConfigFile/JsonConfigFile.ino index 6134f5873..2d5956cea 100644 --- a/examples/JsonConfigFile/JsonConfigFile.ino +++ b/examples/JsonConfigFile/JsonConfigFile.ino @@ -35,7 +35,7 @@ void loadConfiguration(const char *filename, Config &config) { StaticJsonDocument<512> doc; // Deserialize the JSON document - JsonError error = deserializeJson(doc, file); + DeserializationError error = deserializeJson(doc, file); if (error) Serial.println(F("Failed to read file, using default configuration")); diff --git a/examples/JsonHttpClient/JsonHttpClient.ino b/examples/JsonHttpClient/JsonHttpClient.ino index 41b130ef8..73f6b15e0 100644 --- a/examples/JsonHttpClient/JsonHttpClient.ino +++ b/examples/JsonHttpClient/JsonHttpClient.ino @@ -76,7 +76,7 @@ void setup() { DynamicJsonDocument doc(capacity); // Parse JSON object - JsonError error = deserializeJson(doc, client); + DeserializationError error = deserializeJson(doc, client); if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.c_str()); diff --git a/examples/JsonParserExample/JsonParserExample.ino b/examples/JsonParserExample/JsonParserExample.ino index d7926cf9f..1001350c0 100644 --- a/examples/JsonParserExample/JsonParserExample.ino +++ b/examples/JsonParserExample/JsonParserExample.ino @@ -32,7 +32,7 @@ void setup() { "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; // Deserialize the JSON document - JsonError error = deserializeJson(doc, json); + DeserializationError error = deserializeJson(doc, json); // Test if parsing succeeds. if (error) { diff --git a/examples/MsgPackParser/MsgPackParser.ino b/examples/MsgPackParser/MsgPackParser.ino index 381fffd15..5798aff4a 100644 --- a/examples/MsgPackParser/MsgPackParser.ino +++ b/examples/MsgPackParser/MsgPackParser.ino @@ -45,7 +45,7 @@ void setup() { // It's a reference to the JsonObject, the actual bytes are inside the // JsonBuffer with all the other nodes of the object tree. // Memory is freed when jsonBuffer goes out of scope. - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); // Test if parsing succeeds. if (error) { diff --git a/fuzzing/fuzzer.cpp b/fuzzing/fuzzer.cpp index 0c5a19af1..8ceacaf4f 100644 --- a/fuzzing/fuzzer.cpp +++ b/fuzzing/fuzzer.cpp @@ -18,8 +18,8 @@ class memstream : public std::istream { extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { DynamicJsonDocument doc; memstream json(data, size); - JsonError error = deserializeJson(doc, json); - if (error == JsonError::Ok) { + DeserializationError error = deserializeJson(doc, json); + if (error == DeserializationError::Ok) { JsonVariant variant = doc.as(); variant.as(); // <- serialize to JSON } diff --git a/src/ArduinoJson/JsonError.hpp b/src/ArduinoJson/DeserializationError.hpp similarity index 52% rename from src/ArduinoJson/JsonError.hpp rename to src/ArduinoJson/DeserializationError.hpp index cc988bed7..724f2ab94 100644 --- a/src/ArduinoJson/JsonError.hpp +++ b/src/ArduinoJson/DeserializationError.hpp @@ -10,25 +10,33 @@ namespace ArduinoJson { -class JsonError { +class DeserializationError { public: - enum Code { Ok, TooDeep, NoMemory, InvalidInput, IncompleteInput }; + enum Code { + Ok, + IncompleteInput, + InvalidInput, + NoMemory, + NotSupported, + TooDeep + }; - JsonError(Code code) : _code(code) {} + DeserializationError() {} + DeserializationError(Code code) : _code(code) {} - friend bool operator==(const JsonError& err, Code code) { + friend bool operator==(const DeserializationError& err, Code code) { return err._code == code; } - friend bool operator==(Code code, const JsonError& err) { + friend bool operator==(Code code, const DeserializationError& err) { return err._code == code; } - friend bool operator!=(const JsonError& err, Code code) { + friend bool operator!=(const DeserializationError& err, Code code) { return err._code != code; } - friend bool operator!=(Code code, const JsonError& err) { + friend bool operator!=(Code code, const DeserializationError& err) { return err._code != code; } @@ -48,6 +56,8 @@ class JsonError { return "InvalidInput"; case IncompleteInput: return "IncompleteInput"; + case NotSupported: + return "NotSupported"; default: return "???"; } @@ -58,13 +68,14 @@ class JsonError { }; #if ARDUINOJSON_ENABLE_STD_STREAM -inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { +inline std::ostream& operator<<(std::ostream& s, + const DeserializationError& e) { s << e.c_str(); return s; } -inline std::ostream& operator<<(std::ostream& s, JsonError::Code c) { - s << JsonError(c).c_str(); +inline std::ostream& operator<<(std::ostream& s, DeserializationError::Code c) { + s << DeserializationError(c).c_str(); return s; } #endif diff --git a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp index 73026e377..3b5d33012 100644 --- a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp +++ b/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp @@ -4,7 +4,7 @@ #pragma once -#include "../../JsonError.hpp" +#include "../../DeserializationError.hpp" #include "../../JsonVariant.hpp" #include "../../Memory/JsonBuffer.hpp" #include "../../Reading/Reader.hpp" @@ -24,8 +24,8 @@ class JsonDeserializer { _writer(writer), _nestingLimit(nestingLimit), _loaded(false) {} - JsonError parse(JsonVariant &variant) { - JsonError err = skipSpacesAndComments(); + DeserializationError parse(JsonVariant &variant) { + DeserializationError err = skipSpacesAndComments(); if (err) return err; switch (current()) { @@ -64,22 +64,22 @@ class JsonDeserializer { return true; } - JsonError parseArray(JsonVariant &variant) { - if (_nestingLimit == 0) return JsonError::TooDeep; + DeserializationError parseArray(JsonVariant &variant) { + if (_nestingLimit == 0) return DeserializationError::TooDeep; JsonArray *array = new (_buffer) JsonArray(_buffer); - if (!array) return JsonError::NoMemory; + if (!array) return DeserializationError::NoMemory; variant = array; // Check opening braket - if (!eat('[')) return JsonError::InvalidInput; + if (!eat('[')) return DeserializationError::InvalidInput; // Skip spaces - JsonError err = skipSpacesAndComments(); + DeserializationError err = skipSpacesAndComments(); if (err) return err; // Empty array? - if (eat(']')) return JsonError::Ok; + if (eat(']')) return DeserializationError::Ok; // Read each value for (;;) { @@ -89,34 +89,34 @@ class JsonDeserializer { err = parse(value); _nestingLimit++; if (err) return err; - if (!array->add(value)) return JsonError::NoMemory; + if (!array->add(value)) return DeserializationError::NoMemory; // 2 - Skip spaces err = skipSpacesAndComments(); if (err) return err; // 3 - More values? - if (eat(']')) return JsonError::Ok; - if (!eat(',')) return JsonError::InvalidInput; + if (eat(']')) return DeserializationError::Ok; + if (!eat(',')) return DeserializationError::InvalidInput; } } - JsonError parseObject(JsonVariant &variant) { - if (_nestingLimit == 0) return JsonError::TooDeep; + DeserializationError parseObject(JsonVariant &variant) { + if (_nestingLimit == 0) return DeserializationError::TooDeep; JsonObject *object = new (_buffer) JsonObject(_buffer); - if (!object) return JsonError::NoMemory; + if (!object) return DeserializationError::NoMemory; variant = object; // Check opening brace - if (!eat('{')) return JsonError::InvalidInput; + if (!eat('{')) return DeserializationError::InvalidInput; // Skip spaces - JsonError err = skipSpacesAndComments(); + DeserializationError err = skipSpacesAndComments(); if (err) return err; // Empty object? - if (eat('}')) return JsonError::Ok; + if (eat('}')) return DeserializationError::Ok; // Read each key value pair for (;;) { @@ -130,7 +130,7 @@ class JsonDeserializer { if (err) return err; // Colon - if (!eat(':')) return JsonError::InvalidInput; + if (!eat(':')) return DeserializationError::InvalidInput; // Parse value JsonVariant value; @@ -138,15 +138,15 @@ class JsonDeserializer { err = parse(value); _nestingLimit++; if (err) return err; - if (!object->set(key, value)) return JsonError::NoMemory; + if (!object->set(key, value)) return DeserializationError::NoMemory; // Skip spaces err = skipSpacesAndComments(); if (err) return err; // More keys/values? - if (eat('}')) return JsonError::Ok; - if (!eat(',')) return JsonError::InvalidInput; + if (eat('}')) return DeserializationError::Ok; + if (!eat(',')) return DeserializationError::InvalidInput; // Skip spaces err = skipSpacesAndComments(); @@ -154,24 +154,24 @@ class JsonDeserializer { } } - JsonError parseValue(JsonVariant &variant) { + DeserializationError parseValue(JsonVariant &variant) { bool hasQuotes = isQuote(current()); const char *value; - JsonError error = parseString(&value); + DeserializationError error = parseString(&value); if (error) return error; if (hasQuotes) { variant = value; } else { variant = RawJson(value); } - return JsonError::Ok; + return DeserializationError::Ok; } - JsonError parseString(const char **result) { + DeserializationError parseString(const char **result) { typename RemoveReference::type::String str = _writer.startString(); char c = current(); - if (c == '\0') return JsonError::IncompleteInput; + if (c == '\0') return DeserializationError::IncompleteInput; if (isQuote(c)) { // quotes move(); @@ -181,14 +181,15 @@ class JsonDeserializer { move(); if (c == stopChar) break; - if (c == '\0') return JsonError::IncompleteInput; + if (c == '\0') return DeserializationError::IncompleteInput; if (c == '\\') { c = current(); - if (c == 0) return JsonError::IncompleteInput; + if (c == '\0') return DeserializationError::IncompleteInput; + if (c == 'u') return DeserializationError::NotSupported; // replace char c = Encoding::unescapeChar(c); - if (c == '\0') return JsonError::InvalidInput; + if (c == '\0') return DeserializationError::InvalidInput; move(); } @@ -201,12 +202,12 @@ class JsonDeserializer { c = current(); } while (canBeInNonQuotedString(c)); } else { - return JsonError::InvalidInput; + return DeserializationError::InvalidInput; } *result = str.c_str(); - if (*result == NULL) return JsonError::NoMemory; - return JsonError::Ok; + if (*result == NULL) return DeserializationError::NoMemory; + return DeserializationError::Ok; } static inline bool isBetween(char c, char min, char max) { @@ -222,12 +223,12 @@ class JsonDeserializer { return c == '\'' || c == '\"'; } - JsonError skipSpacesAndComments() { + DeserializationError skipSpacesAndComments() { for (;;) { switch (current()) { // end of string case '\0': - return JsonError::IncompleteInput; + return DeserializationError::IncompleteInput; // spaces case ' ': @@ -247,7 +248,7 @@ class JsonDeserializer { bool wasStar = false; for (;;) { char c = current(); - if (c == '\0') return JsonError::IncompleteInput; + if (c == '\0') return DeserializationError::IncompleteInput; if (c == '/' && wasStar) { move(); break; @@ -264,19 +265,19 @@ class JsonDeserializer { for (;;) { move(); char c = current(); - if (c == '\0') return JsonError::IncompleteInput; + if (c == '\0') return DeserializationError::IncompleteInput; if (c == '\n') break; } break; // not a comment, just a '/' default: - return JsonError::InvalidInput; + return DeserializationError::InvalidInput; } break; default: - return JsonError::Ok; + return DeserializationError::Ok; } } } diff --git a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index d76547568..34dc11de4 100644 --- a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -4,21 +4,18 @@ #pragma once +#include "../DeserializationError.hpp" #include "../JsonVariant.hpp" #include "../Memory/JsonBuffer.hpp" #include "../Reading/Reader.hpp" #include "../TypeTraits/IsConst.hpp" #include "../Writing/Writer.hpp" -#include "./MsgPackError.hpp" #include "./endianess.hpp" #include "./ieee754.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 class MsgPackDeserializer { public: @@ -29,18 +26,18 @@ class MsgPackDeserializer { _writer(writer), _nestingLimit(nestingLimit) {} - MsgPackError parse(JsonVariant &variant) { + DeserializationError parse(JsonVariant &variant) { uint8_t code; - if (!readByte(code)) return MsgPackError::IncompleteInput; + if (!readByte(code)) return DeserializationError::IncompleteInput; if ((code & 0x80) == 0) { variant = code; - return MsgPackError::Ok; + return DeserializationError::Ok; } if ((code & 0xe0) == 0xe0) { variant = static_cast(code); - return MsgPackError::Ok; + return DeserializationError::Ok; } if ((code & 0xe0) == 0xa0) { @@ -54,15 +51,15 @@ class MsgPackDeserializer { switch (code) { case 0xc0: variant = static_cast(0); - return MsgPackError::Ok; + return DeserializationError::Ok; case 0xc2: variant = false; - return MsgPackError::Ok; + return DeserializationError::Ok; case 0xc3: variant = true; - return MsgPackError::Ok; + return DeserializationError::Ok; case 0xcc: return readInteger(variant); @@ -94,7 +91,7 @@ class MsgPackDeserializer { #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 return readInteger(variant); #else - if (!skip(4)) return MsgPackError::IncompleteInput; + if (!skip(4)) return DeserializationError::IncompleteInput; return readInteger(variant); #endif @@ -126,7 +123,7 @@ class MsgPackDeserializer { return readObject(variant); default: - return MsgPackError::NotSupported; + return DeserializationError::NotSupported; } } @@ -176,123 +173,123 @@ class MsgPackDeserializer { } template - MsgPackError readInteger(JsonVariant &variant) { + DeserializationError readInteger(JsonVariant &variant) { T value; - if (!readInteger(value)) return MsgPackError::IncompleteInput; + if (!readInteger(value)) return DeserializationError::IncompleteInput; variant = value; - return MsgPackError::Ok; + return DeserializationError::Ok; } template - typename EnableIf::type readFloat( + typename EnableIf::type readFloat( JsonVariant &variant) { T value; - if (!readBytes(value)) return MsgPackError::IncompleteInput; + if (!readBytes(value)) return DeserializationError::IncompleteInput; fixEndianess(value); variant = value; - return MsgPackError::Ok; + return DeserializationError::Ok; } template - typename EnableIf::type readDouble( + typename EnableIf::type readDouble( JsonVariant &variant) { T value; - if (!readBytes(value)) return MsgPackError::IncompleteInput; + if (!readBytes(value)) return DeserializationError::IncompleteInput; fixEndianess(value); variant = value; - return MsgPackError::Ok; + return DeserializationError::Ok; } template - typename EnableIf::type readDouble( + typename EnableIf::type readDouble( JsonVariant &variant) { uint8_t i[8]; // input is 8 bytes T value; // output is 4 bytes uint8_t *o = reinterpret_cast(&value); - if (!readBytes(i, 8)) return MsgPackError::IncompleteInput; + if (!readBytes(i, 8)) return DeserializationError::IncompleteInput; doubleToFloat(i, o); fixEndianess(value); variant = value; - return MsgPackError::Ok; + return DeserializationError::Ok; } template - MsgPackError readString(JsonVariant &variant) { + DeserializationError readString(JsonVariant &variant) { T size; - if (!readInteger(size)) return MsgPackError::IncompleteInput; + if (!readInteger(size)) return DeserializationError::IncompleteInput; return readString(variant, size); } - MsgPackError readString(JsonVariant &variant, size_t n) { + DeserializationError readString(JsonVariant &variant, size_t n) { typename RemoveReference::type::String str = _writer.startString(); for (; n; --n) { uint8_t c; - if (!readBytes(c)) return MsgPackError::IncompleteInput; + if (!readBytes(c)) return DeserializationError::IncompleteInput; str.append(static_cast(c)); } const char *s = str.c_str(); - if (s == NULL) return MsgPackError::NoMemory; + if (s == NULL) return DeserializationError::NoMemory; variant = s; - return MsgPackError::Ok; + return DeserializationError::Ok; } template - MsgPackError readArray(JsonVariant &variant) { + DeserializationError readArray(JsonVariant &variant) { TSize size; - if (!readInteger(size)) return MsgPackError::IncompleteInput; + if (!readInteger(size)) return DeserializationError::IncompleteInput; return readArray(variant, size); } - MsgPackError readArray(JsonVariant &variant, size_t n) { + DeserializationError readArray(JsonVariant &variant, size_t n) { JsonArray *array = new (_buffer) JsonArray(_buffer); - if (!array) return MsgPackError::NoMemory; + if (!array) return DeserializationError::NoMemory; variant = array; return readArray(*array, n); } - MsgPackError readArray(JsonArray &array, size_t n) { - if (_nestingLimit == 0) return MsgPackError::TooDeep; + DeserializationError readArray(JsonArray &array, size_t n) { + if (_nestingLimit == 0) return DeserializationError::TooDeep; --_nestingLimit; for (; n; --n) { JsonVariant variant; - MsgPackError err = parse(variant); + DeserializationError err = parse(variant); if (err) return err; - if (!array.add(variant)) return MsgPackError::NoMemory; + if (!array.add(variant)) return DeserializationError::NoMemory; } ++_nestingLimit; - return MsgPackError::Ok; + return DeserializationError::Ok; } template - MsgPackError readObject(JsonVariant &variant) { + DeserializationError readObject(JsonVariant &variant) { TSize size; - if (!readInteger(size)) return MsgPackError::IncompleteInput; + if (!readInteger(size)) return DeserializationError::IncompleteInput; return readObject(variant, size); } - MsgPackError readObject(JsonVariant &variant, size_t n) { + DeserializationError readObject(JsonVariant &variant, size_t n) { JsonObject *object = new (_buffer) JsonObject(_buffer); - if (!object) return MsgPackError::NoMemory; + if (!object) return DeserializationError::NoMemory; variant = object; return readObject(*object, n); } - MsgPackError readObject(JsonObject &object, size_t n) { - if (_nestingLimit == 0) return MsgPackError::TooDeep; + DeserializationError readObject(JsonObject &object, size_t n) { + if (_nestingLimit == 0) return DeserializationError::TooDeep; --_nestingLimit; for (; n; --n) { - MsgPackError err; + DeserializationError err; JsonVariant variant; err = parse(variant); if (err) return err; const char *key = variant.as(); - if (!key) return MsgPackError::NotSupported; + if (!key) return DeserializationError::NotSupported; err = parse(variant); if (err) return err; - if (!object.set(key, variant)) return MsgPackError::NoMemory; + if (!object.set(key, variant)) return DeserializationError::NoMemory; } ++_nestingLimit; - return MsgPackError::Ok; + return DeserializationError::Ok; } JsonBuffer *_buffer; diff --git a/src/ArduinoJson/MsgPack/MsgPackError.hpp b/src/ArduinoJson/MsgPack/MsgPackError.hpp deleted file mode 100644 index ed3a8a121..000000000 --- a/src/ArduinoJson/MsgPack/MsgPackError.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#if ARDUINOJSON_ENABLE_STD_STREAM -#include -#endif - -namespace ArduinoJson { - -class MsgPackError { - public: - enum Code { Ok, NotSupported, NoMemory, TooDeep, IncompleteInput }; - - MsgPackError() {} - - MsgPackError(Code code) : _code(code) {} - - operator bool() const { - return _code != Ok; - } - - friend bool operator==(const MsgPackError& err, Code code) { - return err._code == code; - } - - friend bool operator==(Code code, const MsgPackError& err) { - return err._code == code; - } - - friend bool operator!=(const MsgPackError& err, Code code) { - return err._code != code; - } - - friend bool operator!=(Code code, const MsgPackError& err) { - return err._code != code; - } - - const char* c_str() const { - switch (_code) { - case Ok: - return "Ok"; - case NotSupported: - return "NotSupported"; - case NoMemory: - return "NoMemory"; - case TooDeep: - return "TooDeep"; - case IncompleteInput: - return "IncompleteInput"; - default: - return "???"; - } - } - - private: - Code _code; -}; - -#if ARDUINOJSON_ENABLE_STD_STREAM -inline std::ostream& operator<<(std::ostream& os, const MsgPackError& err) { - os << err.c_str(); - return os; -} - -inline std::ostream& operator<<(std::ostream& os, MsgPackError::Code code) { - os << MsgPackError(code).c_str(); - return os; -} -#endif - -} // namespace ArduinoJson diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index bda81ac68..b0eafc8bf 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -9,12 +9,12 @@ #include "Writing/Writer.hpp" namespace ArduinoJson { -// JsonError deserializeJson(TDocument& doc, TString input); +// DeserializationError deserializeJson(TDocument& doc, TString input); // TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& template typename Internals::EnableIf::value, - JsonError>::type + DeserializationError>::type deserializeJson(TDocument &doc, const TString &input) { using namespace Internals; return makeJsonDeserializer(&doc.buffer(), makeReader(input), @@ -22,33 +22,34 @@ deserializeJson(TDocument &doc, const TString &input) { .parse(doc.template to()); } // -// JsonError deserializeJson(TDocument& doc, TChar* input); +// DeserializationError deserializeJson(TDocument& doc, TChar* input); // TDocument = DynamicJsonDocument, StaticJsonDocument // TChar* = char*, const char*, const FlashStringHelper* template -JsonError deserializeJson(TDocument &doc, TChar *input) { +DeserializationError deserializeJson(TDocument &doc, TChar *input) { using namespace Internals; return makeJsonDeserializer(&doc.buffer(), makeReader(input), makeWriter(doc.buffer(), input), doc.nestingLimit) .parse(doc.template to()); } // -// JsonError deserializeJson(TDocument& doc, TChar* input, size_t inputSize); -// TDocument = DynamicJsonDocument, StaticJsonDocument -// TChar* = char*, const char*, const FlashStringHelper* +// DeserializationError deserializeJson(TDocument& doc, TChar* input, size_t +// inputSize); TDocument = DynamicJsonDocument, StaticJsonDocument TChar* = +// char*, const char*, const FlashStringHelper* template -JsonError deserializeJson(TDocument &doc, TChar *input, size_t inputSize) { +DeserializationError deserializeJson(TDocument &doc, TChar *input, + size_t inputSize) { using namespace Internals; return makeJsonDeserializer(&doc.buffer(), makeReader(input, inputSize), makeWriter(doc.buffer(), input), doc.nestingLimit) .parse(doc.template to()); } // -// JsonError deserializeJson(TDocument& doc, TStream input); +// DeserializationError deserializeJson(TDocument& doc, TStream input); // TDocument = DynamicJsonDocument, StaticJsonDocument // TStream = std::istream&, Stream& template -JsonError deserializeJson(TDocument &doc, TStream &input) { +DeserializationError deserializeJson(TDocument &doc, TStream &input) { using namespace Internals; return makeJsonDeserializer(&doc.buffer(), makeReader(input), makeWriter(doc.buffer(), input), doc.nestingLimit) diff --git a/src/ArduinoJson/deserializeMsgPack.hpp b/src/ArduinoJson/deserializeMsgPack.hpp index 92ac993ca..9256a4112 100644 --- a/src/ArduinoJson/deserializeMsgPack.hpp +++ b/src/ArduinoJson/deserializeMsgPack.hpp @@ -9,12 +9,12 @@ #include "Writing/Writer.hpp" namespace ArduinoJson { -// MsgPackError deserializeMsgPack(TDocument& doc, TString input); +// DeserializationError deserializeMsgPack(TDocument& doc, TString input); // TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& template typename Internals::EnableIf::value, - MsgPackError>::type + DeserializationError>::type deserializeMsgPack(TDocument &doc, const TString &input) { using namespace Internals; return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), @@ -23,11 +23,11 @@ deserializeMsgPack(TDocument &doc, const TString &input) { .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input); +// DeserializationError deserializeMsgPack(TDocument& doc, TChar* input); // TDocument = DynamicJsonDocument, StaticJsonDocument // TChar* = char*, const char*, const FlashStringHelper* template -MsgPackError deserializeMsgPack(TDocument &doc, TChar *input) { +DeserializationError deserializeMsgPack(TDocument &doc, TChar *input) { using namespace Internals; return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), makeWriter(doc.buffer(), input), @@ -35,13 +35,13 @@ MsgPackError deserializeMsgPack(TDocument &doc, TChar *input) { .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input, size_t +// DeserializationError deserializeMsgPack(TDocument& doc, TChar* input, size_t // inputSize); // TDocument = DynamicJsonDocument, StaticJsonDocument // TChar* = char*, const char*, const FlashStringHelper* template -MsgPackError deserializeMsgPack(TDocument &doc, TChar *input, - size_t inputSize) { +DeserializationError deserializeMsgPack(TDocument &doc, TChar *input, + size_t inputSize) { using namespace Internals; return makeMsgPackDeserializer(&doc.buffer(), makeReader(input, inputSize), makeWriter(doc.buffer(), input), @@ -49,11 +49,11 @@ MsgPackError deserializeMsgPack(TDocument &doc, TChar *input, .parse(doc.template to()); } // -// MsgPackError deserializeMsgPack(TDocument& doc, TStream input); +// DeserializationError deserializeMsgPack(TDocument& doc, TStream input); // TDocument = DynamicJsonDocument, StaticJsonDocument // TStream = std::istream&, Stream& template -MsgPackError deserializeMsgPack(TDocument &doc, TStream &input) { +DeserializationError deserializeMsgPack(TDocument &doc, TStream &input) { using namespace Internals; return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), makeWriter(doc.buffer(), input), diff --git a/test/DynamicJsonBuffer/no_memory.cpp b/test/DynamicJsonBuffer/no_memory.cpp index ecb82b8c0..06eec36b9 100644 --- a/test/DynamicJsonBuffer/no_memory.cpp +++ b/test/DynamicJsonBuffer/no_memory.cpp @@ -27,9 +27,9 @@ TEST_CASE("DynamicJsonBuffer no memory") { // char json[] = "{[]}"; // DynamicJsonDocument obj; - // JsonError err = deserializeJson(obj, json); + // DeserializationError err = deserializeJson(obj, json); - // REQUIRE(err != JsonError::Ok); + // REQUIRE(err != DeserializationError::Ok); // } SECTION("startString()") { diff --git a/test/IntegrationTests/gbathree.cpp b/test/IntegrationTests/gbathree.cpp index 965022ae8..9372fc1d2 100644 --- a/test/IntegrationTests/gbathree.cpp +++ b/test/IntegrationTests/gbathree.cpp @@ -8,7 +8,7 @@ TEST_CASE("Gbathree") { DynamicJsonDocument doc; - JsonError error = deserializeJson( + DeserializationError error = deserializeJson( doc, "{\"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0," "\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_" @@ -23,7 +23,7 @@ TEST_CASE("Gbathree") { JsonObject& root = doc.as(); SECTION("Success") { - REQUIRE(error == JsonError::Ok); + REQUIRE(error == DeserializationError::Ok); } SECTION("ProtocolName") { diff --git a/test/JsonArray/copyTo.cpp b/test/JsonArray/copyTo.cpp index 87c9801ee..d90927082 100644 --- a/test/JsonArray/copyTo.cpp +++ b/test/JsonArray/copyTo.cpp @@ -10,8 +10,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("BiggerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonError err = deserializeJson(doc, json); - REQUIRE(err == JsonError::Ok); + DeserializationError err = deserializeJson(doc, json); + REQUIRE(err == DeserializationError::Ok); JsonArray& array = doc.as(); int destination[4] = {0}; @@ -26,8 +26,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("SmallerOneDimensionIntegerArray") { char json[] = "[1,2,3]"; - JsonError err = deserializeJson(doc, json); - REQUIRE(err == JsonError::Ok); + DeserializationError err = deserializeJson(doc, json); + REQUIRE(err == DeserializationError::Ok); JsonArray& array = doc.as(); int destination[2] = {0}; @@ -41,8 +41,8 @@ TEST_CASE("JsonArray::copyTo()") { SECTION("TwoOneDimensionIntegerArray") { char json[] = "[[1,2],[3],[4]]"; - JsonError err = deserializeJson(doc, json); - REQUIRE(err == JsonError::Ok); + DeserializationError err = deserializeJson(doc, json); + REQUIRE(err == DeserializationError::Ok); JsonArray& array = doc.as(); int destination[3][2] = {{0}}; diff --git a/test/JsonDeserializer/CMakeLists.txt b/test/JsonDeserializer/CMakeLists.txt index 16cb2460f..5624ffdd3 100644 --- a/test/JsonDeserializer/CMakeLists.txt +++ b/test/JsonDeserializer/CMakeLists.txt @@ -8,7 +8,7 @@ add_executable(JsonDeserializerTests deserializeJsonObject.cpp deserializeJsonObjectStatic.cpp deserializeJsonValue.cpp - JsonError.cpp + DeserializationError.cpp nestingLimit.cpp std_istream.cpp std_string.cpp diff --git a/test/JsonDeserializer/JsonError.cpp b/test/JsonDeserializer/DeserializationError.cpp similarity index 66% rename from test/JsonDeserializer/JsonError.cpp rename to test/JsonDeserializer/DeserializationError.cpp index b80bd66ac..c524f082a 100644 --- a/test/JsonDeserializer/JsonError.cpp +++ b/test/JsonDeserializer/DeserializationError.cpp @@ -5,27 +5,28 @@ #include #include -void testStringification(JsonError error, std::string expected) { +void testStringification(DeserializationError error, std::string expected) { REQUIRE(error.c_str() == expected); } -void testBoolification(JsonError error, bool expected) { +void testBoolification(DeserializationError error, bool expected) { CHECK(error == expected); } #define TEST_STRINGIFICATION(symbol) \ - testStringification(JsonError::symbol, #symbol) + testStringification(DeserializationError::symbol, #symbol) #define TEST_BOOLIFICATION(symbol, expected) \ - testBoolification(JsonError::symbol, expected) + testBoolification(DeserializationError::symbol, expected) -TEST_CASE("JsonError") { +TEST_CASE("DeserializationError") { SECTION("c_str()") { TEST_STRINGIFICATION(Ok); TEST_STRINGIFICATION(TooDeep); TEST_STRINGIFICATION(NoMemory); TEST_STRINGIFICATION(InvalidInput); TEST_STRINGIFICATION(IncompleteInput); + TEST_STRINGIFICATION(NotSupported); } SECTION("as boolean") { @@ -34,11 +35,12 @@ TEST_CASE("JsonError") { TEST_BOOLIFICATION(NoMemory, true); TEST_BOOLIFICATION(InvalidInput, true); TEST_BOOLIFICATION(IncompleteInput, true); + TEST_BOOLIFICATION(NotSupported, true); } SECTION("ostream") { std::stringstream s; - s << JsonError::InvalidInput; + s << DeserializationError::InvalidInput; REQUIRE(s.str() == "InvalidInput"); } } diff --git a/test/JsonDeserializer/deserializeJsonArray.cpp b/test/JsonDeserializer/deserializeJsonArray.cpp index 57bf5759a..f1f7ff284 100644 --- a/test/JsonDeserializer/deserializeJsonArray.cpp +++ b/test/JsonDeserializer/deserializeJsonArray.cpp @@ -9,36 +9,36 @@ TEST_CASE("deserialize JSON array") { DynamicJsonDocument doc; SECTION("An empty array") { - JsonError err = deserializeJson(doc, "[]"); + DeserializationError err = deserializeJson(doc, "[]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(0 == arr.size()); } SECTION("Spaces") { SECTION("Before the opening bracket") { - JsonError err = deserializeJson(doc, " []"); + DeserializationError err = deserializeJson(doc, " []"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(0 == arr.size()); } SECTION("Before first value") { - JsonError err = deserializeJson(doc, "[ \t\r\n42]"); + DeserializationError err = deserializeJson(doc, "[ \t\r\n42]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == 42); } SECTION("After first value") { - JsonError err = deserializeJson(doc, "[42 \t\r\n]"); + DeserializationError err = deserializeJson(doc, "[42 \t\r\n]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == 42); } @@ -46,58 +46,58 @@ TEST_CASE("deserialize JSON array") { SECTION("Values types") { SECTION("On integer") { - JsonError err = deserializeJson(doc, "[42]"); + DeserializationError err = deserializeJson(doc, "[42]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == 42); } SECTION("Two integers") { - JsonError err = deserializeJson(doc, "[42,84]"); + DeserializationError err = deserializeJson(doc, "[42,84]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == 42); REQUIRE(arr[1] == 84); } SECTION("Double") { - JsonError err = deserializeJson(doc, "[4.2,1e2]"); + DeserializationError err = deserializeJson(doc, "[4.2,1e2]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == 4.2); REQUIRE(arr[1] == 1e2); } SECTION("Unsigned long") { - JsonError err = deserializeJson(doc, "[4294967295]"); + DeserializationError err = deserializeJson(doc, "[4294967295]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == 4294967295UL); } SECTION("Boolean") { - JsonError err = deserializeJson(doc, "[true,false]"); + DeserializationError err = deserializeJson(doc, "[true,false]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == true); REQUIRE(arr[1] == false); } SECTION("Null") { - JsonError err = deserializeJson(doc, "[null,null]"); + DeserializationError err = deserializeJson(doc, "[null,null]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0].as() == 0); REQUIRE(arr[1].as() == 0); @@ -106,232 +106,241 @@ TEST_CASE("deserialize JSON array") { SECTION("Quotes") { SECTION("Double quotes") { - JsonError err = deserializeJson(doc, "[ \"hello\" , \"world\" ]"); + DeserializationError err = + deserializeJson(doc, "[ \"hello\" , \"world\" ]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == "hello"); REQUIRE(arr[1] == "world"); } SECTION("Single quotes") { - JsonError err = deserializeJson(doc, "[ 'hello' , 'world' ]"); + DeserializationError err = deserializeJson(doc, "[ 'hello' , 'world' ]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == "hello"); REQUIRE(arr[1] == "world"); } SECTION("No quotes") { - JsonError err = deserializeJson(doc, "[ hello , world ]"); + DeserializationError err = deserializeJson(doc, "[ hello , world ]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == "hello"); REQUIRE(arr[1] == "world"); } SECTION("Double quotes (empty strings)") { - JsonError err = deserializeJson(doc, "[\"\",\"\"]"); + DeserializationError err = deserializeJson(doc, "[\"\",\"\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == ""); REQUIRE(arr[1] == ""); } SECTION("Single quotes (empty strings)") { - JsonError err = deserializeJson(doc, "[\'\',\'\']"); + DeserializationError err = deserializeJson(doc, "[\'\',\'\']"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == ""); REQUIRE(arr[1] == ""); } SECTION("No quotes (empty strings)") { - JsonError err = deserializeJson(doc, "[,]"); + DeserializationError err = deserializeJson(doc, "[,]"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("Closing single quotes missing") { - JsonError err = deserializeJson(doc, "[\"]"); + DeserializationError err = deserializeJson(doc, "[\"]"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("Closing double quotes missing") { - JsonError err = deserializeJson(doc, "[\']"); + DeserializationError err = deserializeJson(doc, "[\']"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } } SECTION("Block comments") { SECTION("Before opening bracket") { - JsonError err = deserializeJson(doc, "/*COMMENT*/ [\"hello\"]"); + DeserializationError err = + deserializeJson(doc, "/*COMMENT*/ [\"hello\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("After opening bracket") { - JsonError err = deserializeJson(doc, "[/*COMMENT*/ \"hello\"]"); + DeserializationError err = + deserializeJson(doc, "[/*COMMENT*/ \"hello\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("Before closing bracket") { - JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]"); + DeserializationError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("After closing bracket") { - JsonError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/"); + DeserializationError err = deserializeJson(doc, "[\"hello\"]/*COMMENT*/"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("Before comma") { - JsonError err = deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]"); + DeserializationError err = + deserializeJson(doc, "[\"hello\"/*COMMENT*/,\"world\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == "hello"); REQUIRE(arr[1] == "world"); } SECTION("After comma") { - JsonError err = deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]"); + DeserializationError err = + deserializeJson(doc, "[\"hello\",/*COMMENT*/ \"world\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == "hello"); REQUIRE(arr[1] == "world"); } SECTION("/*/") { - JsonError err = deserializeJson(doc, "[/*/\n]"); - REQUIRE(err == JsonError::IncompleteInput); + DeserializationError err = deserializeJson(doc, "[/*/\n]"); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("Unfinished comment") { - JsonError err = deserializeJson(doc, "[/*COMMENT]"); - REQUIRE(err == JsonError::IncompleteInput); + DeserializationError err = deserializeJson(doc, "[/*COMMENT]"); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("Final slash missing") { - JsonError err = deserializeJson(doc, "[/*COMMENT*]"); - REQUIRE(err == JsonError::IncompleteInput); + DeserializationError err = deserializeJson(doc, "[/*COMMENT*]"); + REQUIRE(err == DeserializationError::IncompleteInput); } } SECTION("Trailing comments") { SECTION("Before opening bracket") { - JsonError err = deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); + DeserializationError err = + deserializeJson(doc, "//COMMENT\n\t[\"hello\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("After opening bracket") { - JsonError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]"); + DeserializationError err = deserializeJson(doc, "[//COMMENT\n\"hello\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("Before closing bracket") { - JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\r\n]"); + DeserializationError err = + deserializeJson(doc, "[\"hello\"//COMMENT\r\n]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("After closing bracket") { - JsonError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n"); + DeserializationError err = deserializeJson(doc, "[\"hello\"]//COMMENT\n"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(arr[0] == "hello"); } SECTION("Before comma") { - JsonError err = deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]"); + DeserializationError err = + deserializeJson(doc, "[\"hello\"//COMMENT\n,\"world\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == "hello"); REQUIRE(arr[1] == "world"); } SECTION("After comma") { - JsonError err = deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]"); + DeserializationError err = + deserializeJson(doc, "[\"hello\",//COMMENT\n\"world\"]"); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(2 == arr.size()); REQUIRE(arr[0] == "hello"); REQUIRE(arr[1] == "world"); } SECTION("Invalid comment") { - JsonError err = deserializeJson(doc, "[/COMMENT\n]"); - REQUIRE(err == JsonError::InvalidInput); + DeserializationError err = deserializeJson(doc, "[/COMMENT\n]"); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("End document with comment") { - JsonError err = deserializeJson(doc, "[//COMMENT"); - REQUIRE(err == JsonError::IncompleteInput); + DeserializationError err = deserializeJson(doc, "[//COMMENT"); + REQUIRE(err == DeserializationError::IncompleteInput); } } SECTION("Premature null-terminator") { SECTION("After opening bracket") { - JsonError err = deserializeJson(doc, "["); + DeserializationError err = deserializeJson(doc, "["); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After value") { - JsonError err = deserializeJson(doc, "[1"); + DeserializationError err = deserializeJson(doc, "[1"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After comma") { - JsonError err = deserializeJson(doc, "[1,"); + DeserializationError err = deserializeJson(doc, "[1,"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } } @@ -339,21 +348,21 @@ TEST_CASE("deserialize JSON array") { const char* input = "[1,2]"; SECTION("After opening bracket") { - JsonError err = deserializeJson(doc, input, 1); + DeserializationError err = deserializeJson(doc, input, 1); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After value") { - JsonError err = deserializeJson(doc, input, 2); + DeserializationError err = deserializeJson(doc, input, 2); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After comma") { - JsonError err = deserializeJson(doc, input, 3); + DeserializationError err = deserializeJson(doc, input, 3); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } } @@ -362,14 +371,14 @@ TEST_CASE("deserialize JSON array") { char jsonString[] = " [ { \"a\" : 1 , \"b\" : 2 } , { \"c\" : 3 , \"d\" : 4 } ] "; - JsonError err = deserializeJson(doc, jsonString); + DeserializationError err = deserializeJson(doc, jsonString); JsonArray& arr = doc.as(); JsonObject& object1 = arr[0]; const JsonObject& object2 = arr[1]; JsonObject& object3 = arr[2]; - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(true == object1.success()); REQUIRE(true == object2.success()); diff --git a/test/JsonDeserializer/deserializeJsonArrayStatic.cpp b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp index 8315c7ebf..471ad72a3 100644 --- a/test/JsonDeserializer/deserializeJsonArrayStatic.cpp +++ b/test/JsonDeserializer/deserializeJsonArrayStatic.cpp @@ -10,45 +10,45 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") { StaticJsonDocument doc; char input[] = "[]"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("TooSmallBufferForArrayWithOneValue") { StaticJsonDocument doc; char input[] = "[1]"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::NoMemory); + REQUIRE(err == DeserializationError::NoMemory); } SECTION("BufferOfTheRightSizeForArrayWithOneValue") { StaticJsonDocument doc; char input[] = "[1]"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("TooSmallBufferForArrayWithNestedObject") { StaticJsonDocument doc; char input[] = "[{}]"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::NoMemory); + REQUIRE(err == DeserializationError::NoMemory); } SECTION("BufferOfTheRightSizeForArrayWithNestedObject") { StaticJsonDocument doc; char input[] = "[{}]"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("CopyStringNotSpaces") { @@ -77,10 +77,10 @@ TEST_CASE("deserialize JSON array with a StaticJsonDocument") { StaticJsonDocument doc; char input[] = "[1,2]"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2)); REQUIRE(arr[0] == 1); diff --git a/test/JsonDeserializer/deserializeJsonObject.cpp b/test/JsonDeserializer/deserializeJsonObject.cpp index ca848a827..d62ce9b07 100644 --- a/test/JsonDeserializer/deserializeJsonObject.cpp +++ b/test/JsonDeserializer/deserializeJsonObject.cpp @@ -9,50 +9,50 @@ TEST_CASE("deserialize JSON object") { DynamicJsonDocument doc; SECTION("An empty object") { - JsonError err = deserializeJson(doc, "{}"); + DeserializationError err = deserializeJson(doc, "{}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 0); } SECTION("Quotes") { SECTION("Double quotes") { - JsonError err = deserializeJson(doc, "{\"key\":\"value\"}"); + DeserializationError err = deserializeJson(doc, "{\"key\":\"value\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Single quotes") { - JsonError err = deserializeJson(doc, "{'key':'value'}"); + DeserializationError err = deserializeJson(doc, "{'key':'value'}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes") { - JsonError err = deserializeJson(doc, "{key:value}"); + DeserializationError err = deserializeJson(doc, "{key:value}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("No quotes, allow underscore in key") { - JsonError err = deserializeJson(doc, "{_k_e_y_:42}"); + DeserializationError err = deserializeJson(doc, "{_k_e_y_:42}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["_k_e_y_"] == 42); @@ -61,51 +61,51 @@ TEST_CASE("deserialize JSON object") { SECTION("Spaces") { SECTION("Before the key") { - JsonError err = deserializeJson(doc, "{ \"key\":\"value\"}"); + DeserializationError err = deserializeJson(doc, "{ \"key\":\"value\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the key") { - JsonError err = deserializeJson(doc, "{\"key\" :\"value\"}"); + DeserializationError err = deserializeJson(doc, "{\"key\" :\"value\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the value") { - JsonError err = deserializeJson(doc, "{\"key\": \"value\"}"); + DeserializationError err = deserializeJson(doc, "{\"key\": \"value\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("After the value") { - JsonError err = deserializeJson(doc, "{\"key\":\"value\" }"); + DeserializationError err = deserializeJson(doc, "{\"key\":\"value\" }"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 1); REQUIRE(obj["key"] == "value"); } SECTION("Before the colon") { - JsonError err = + DeserializationError err = deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); @@ -113,11 +113,11 @@ TEST_CASE("deserialize JSON object") { } SECTION("After the colon") { - JsonError err = + DeserializationError err = deserializeJson(doc, "{\"key1\":\"value1\" ,\"key2\":\"value2\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); @@ -127,11 +127,11 @@ TEST_CASE("deserialize JSON object") { SECTION("Values types") { SECTION("String") { - JsonError err = + DeserializationError err = deserializeJson(doc, "{\"key1\":\"value1\",\"key2\":\"value2\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == "value1"); @@ -139,10 +139,11 @@ TEST_CASE("deserialize JSON object") { } SECTION("Integer") { - JsonError err = deserializeJson(doc, "{\"key1\":42,\"key2\":-42}"); + DeserializationError err = + deserializeJson(doc, "{\"key1\":42,\"key2\":-42}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 42); @@ -150,10 +151,11 @@ TEST_CASE("deserialize JSON object") { } SECTION("Double") { - JsonError err = deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}"); + DeserializationError err = + deserializeJson(doc, "{\"key1\":12.345,\"key2\":-7E89}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == 12.345); @@ -161,10 +163,11 @@ TEST_CASE("deserialize JSON object") { } SECTION("Booleans") { - JsonError err = deserializeJson(doc, "{\"key1\":true,\"key2\":false}"); + DeserializationError err = + deserializeJson(doc, "{\"key1\":true,\"key2\":false}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"] == true); @@ -172,10 +175,11 @@ TEST_CASE("deserialize JSON object") { } SECTION("Null") { - JsonError err = deserializeJson(doc, "{\"key1\":null,\"key2\":null}"); + DeserializationError err = + deserializeJson(doc, "{\"key1\":null,\"key2\":null}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["key1"].as() == 0); @@ -185,14 +189,14 @@ TEST_CASE("deserialize JSON object") { SECTION("Array") { char jsonString[] = " { \"ab\" : [ 1 , 2 ] , \"cd\" : [ 3 , 4 ] } "; - JsonError err = deserializeJson(doc, jsonString); + DeserializationError err = deserializeJson(doc, jsonString); JsonObject& obj = doc.as(); JsonArray& array1 = obj["ab"]; const JsonArray& array2 = obj["cd"]; JsonArray& array3 = obj["ef"]; - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(true == array1.success()); REQUIRE(true == array2.success()); @@ -214,127 +218,133 @@ TEST_CASE("deserialize JSON object") { SECTION("Premature null terminator") { SECTION("After opening brace") { - JsonError err = deserializeJson(doc, "{"); + DeserializationError err = deserializeJson(doc, "{"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After key") { - JsonError err = deserializeJson(doc, "{\"hello\""); + DeserializationError err = deserializeJson(doc, "{\"hello\""); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After colon") { - JsonError err = deserializeJson(doc, "{\"hello\":"); + DeserializationError err = deserializeJson(doc, "{\"hello\":"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After value") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\""); + DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\""); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("After comma") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\","); + DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\","); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } } SECTION("Misc") { SECTION("A quoted key without value") { - JsonError err = deserializeJson(doc, "{\"key\"}"); + DeserializationError err = deserializeJson(doc, "{\"key\"}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("A non-quoted key without value") { - JsonError err = deserializeJson(doc, "{key}"); + DeserializationError err = deserializeJson(doc, "{key}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("A dangling comma") { - JsonError err = deserializeJson(doc, "{\"key1\":\"value1\",}"); + DeserializationError err = deserializeJson(doc, "{\"key1\":\"value1\",}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("null as a key") { - JsonError err = deserializeJson(doc, "{null:\"value\"}"); + DeserializationError err = deserializeJson(doc, "{null:\"value\"}"); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } } SECTION("Block comments") { SECTION("Before opening brace") { - JsonError err = deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}"); + DeserializationError err = + deserializeJson(doc, "/*COMMENT*/ {\"hello\":\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("After opening brace") { - JsonError err = deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}"); + DeserializationError err = + deserializeJson(doc, "{/*COMMENT*/\"hello\":\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("Before colon") { - JsonError err = deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}"); + DeserializationError err = + deserializeJson(doc, "{\"hello\"/*COMMENT*/:\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("After colon") { - JsonError err = deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}"); + DeserializationError err = + deserializeJson(doc, "{\"hello\":/*COMMENT*/\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("Before closing brace") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}"); + DeserializationError err = + deserializeJson(doc, "{\"hello\":\"world\"/*COMMENT*/}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("After closing brace") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/"); + DeserializationError err = + deserializeJson(doc, "{\"hello\":\"world\"}/*COMMENT*/"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("Before comma") { - JsonError err = deserializeJson( + DeserializationError err = deserializeJson( doc, "{\"hello\":\"world\"/*COMMENT*/,\"answer\":42}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); REQUIRE(obj["answer"] == 42); } SECTION("After comma") { - JsonError err = deserializeJson( + DeserializationError err = deserializeJson( doc, "{\"hello\":\"world\",/*COMMENT*/\"answer\":42}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); REQUIRE(obj["answer"] == 42); } @@ -342,69 +352,75 @@ TEST_CASE("deserialize JSON object") { SECTION("Trailing comments") { SECTION("Before opening brace") { - JsonError err = deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}"); + DeserializationError err = + deserializeJson(doc, "//COMMENT\n {\"hello\":\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("After opening brace") { - JsonError err = deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}"); + DeserializationError err = + deserializeJson(doc, "{//COMMENT\n\"hello\":\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("Before colon") { - JsonError err = deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}"); + DeserializationError err = + deserializeJson(doc, "{\"hello\"//COMMENT\n:\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("After colon") { - JsonError err = deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}"); + DeserializationError err = + deserializeJson(doc, "{\"hello\"://COMMENT\n\"world\"}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("Before closing brace") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}"); + DeserializationError err = + deserializeJson(doc, "{\"hello\":\"world\"//COMMENT\n}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("After closing brace") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n"); + DeserializationError err = + deserializeJson(doc, "{\"hello\":\"world\"}//COMMENT\n"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("Before comma") { - JsonError err = deserializeJson( + DeserializationError err = deserializeJson( doc, "{\"hello\":\"world\"//COMMENT\n,\"answer\":42}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); REQUIRE(obj["answer"] == 42); } SECTION("After comma") { - JsonError err = deserializeJson( + DeserializationError err = deserializeJson( doc, "{\"hello\":\"world\",//COMMENT\n\"answer\":42}"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); REQUIRE(obj["answer"] == 42); } @@ -412,55 +428,55 @@ TEST_CASE("deserialize JSON object") { SECTION("Dangling slash") { SECTION("Before opening brace") { - JsonError err = deserializeJson(doc, "/{\"hello\":\"world\"}"); + DeserializationError err = deserializeJson(doc, "/{\"hello\":\"world\"}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("After opening brace") { - JsonError err = deserializeJson(doc, "{/\"hello\":\"world\"}"); + DeserializationError err = deserializeJson(doc, "{/\"hello\":\"world\"}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("Before colon") { - JsonError err = deserializeJson(doc, "{\"hello\"/:\"world\"}"); + DeserializationError err = deserializeJson(doc, "{\"hello\"/:\"world\"}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("After colon") { - JsonError err = deserializeJson(doc, "{\"hello\":/\"world\"}"); + DeserializationError err = deserializeJson(doc, "{\"hello\":/\"world\"}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("Before closing brace") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\"/}"); + DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"/}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("After closing brace") { - JsonError err = deserializeJson(doc, "{\"hello\":\"world\"}/"); + DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"}/"); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(obj["hello"] == "world"); } SECTION("Before comma") { - JsonError err = + DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\"/,\"answer\":42}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("After comma") { - JsonError err = + DeserializationError err = deserializeJson(doc, "{\"hello\":\"world\",/\"answer\":42}"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } } diff --git a/test/JsonDeserializer/deserializeJsonObjectStatic.cpp b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp index 85b2dfef4..6a1d307a8 100644 --- a/test/JsonDeserializer/deserializeJsonObjectStatic.cpp +++ b/test/JsonDeserializer/deserializeJsonObjectStatic.cpp @@ -10,45 +10,45 @@ TEST_CASE("deserialize JSON object with StaticJsonDocument") { StaticJsonDocument doc; char input[] = "{}"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("TooSmallBufferForObjectWithOneValue") { StaticJsonDocument doc; char input[] = "{\"a\":1}"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::NoMemory); + REQUIRE(err == DeserializationError::NoMemory); } SECTION("BufferOfTheRightSizeForObjectWithOneValue") { StaticJsonDocument doc; char input[] = "{\"a\":1}"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("TooSmallBufferForObjectWithNestedObject") { StaticJsonDocument doc; char input[] = "{\"a\":[]}"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::NoMemory); + REQUIRE(err == DeserializationError::NoMemory); } SECTION("BufferOfTheRightSizeForObjectWithNestedObject") { StaticJsonDocument doc; char input[] = "{\"a\":[]}"; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("Should clear the JsonObject") { diff --git a/test/JsonDeserializer/deserializeJsonValue.cpp b/test/JsonDeserializer/deserializeJsonValue.cpp index fb9f8105a..45ce150b4 100644 --- a/test/JsonDeserializer/deserializeJsonValue.cpp +++ b/test/JsonDeserializer/deserializeJsonValue.cpp @@ -11,71 +11,78 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") { DynamicJsonDocument doc; SECTION("null char*") { - JsonError err = deserializeJson(doc, static_cast(0)); + DeserializationError err = deserializeJson(doc, static_cast(0)); - REQUIRE(err != JsonError::Ok); + REQUIRE(err != DeserializationError::Ok); } SECTION("null const char*") { - JsonError err = deserializeJson(doc, static_cast(0)); + DeserializationError err = + deserializeJson(doc, static_cast(0)); - REQUIRE(err != JsonError::Ok); + REQUIRE(err != DeserializationError::Ok); } SECTION("Integer") { - JsonError err = deserializeJson(doc, "-42"); + DeserializationError err = deserializeJson(doc, "-42"); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE_FALSE(doc.is()); REQUIRE(doc.as() == -42); } SECTION("Double") { - JsonError err = deserializeJson(doc, "-1.23e+4"); + DeserializationError err = deserializeJson(doc, "-1.23e+4"); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE_FALSE(doc.is()); REQUIRE(doc.is()); REQUIRE(doc.as() == Approx(-1.23e+4)); } SECTION("Double quoted string") { - JsonError err = deserializeJson(doc, "\"hello world\""); + DeserializationError err = deserializeJson(doc, "\"hello world\""); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE_THAT(doc.as(), Equals("hello world")); } SECTION("Single quoted string") { - JsonError err = deserializeJson(doc, "\'hello world\'"); + DeserializationError err = deserializeJson(doc, "\'hello world\'"); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE_THAT(doc.as(), Equals("hello world")); } SECTION("Escape sequences") { - JsonError err = + DeserializationError err = deserializeJson(doc, "\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\""); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.as() == "1\"2\\3/4\b5\f6\n7\r8\t9"); } + SECTION("UTF-16 surrogate") { + DeserializationError err = deserializeJson(doc, "\"\\uD834\\uDD1E\""); + + REQUIRE(err == DeserializationError::NotSupported); + } + SECTION("True") { - JsonError err = deserializeJson(doc, "true"); + DeserializationError err = deserializeJson(doc, "true"); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(doc.as() == true); } SECTION("False") { - JsonError err = deserializeJson(doc, "false"); + DeserializationError err = deserializeJson(doc, "false"); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(doc.as() == false); } @@ -89,84 +96,84 @@ TEST_CASE("deserializeJson(DynamicJsonDocument&)") { } SECTION("Empty input") { - JsonError err = deserializeJson(doc, ""); + DeserializationError err = deserializeJson(doc, ""); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("Just a trailing comment") { - JsonError err = deserializeJson(doc, "// comment"); + DeserializationError err = deserializeJson(doc, "// comment"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("Just a block comment") { - JsonError err = deserializeJson(doc, "/*comment*/"); + DeserializationError err = deserializeJson(doc, "/*comment*/"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("Just a slash") { - JsonError err = deserializeJson(doc, "/"); + DeserializationError err = deserializeJson(doc, "/"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("Garbage") { - JsonError err = deserializeJson(doc, "%*$£¤"); + DeserializationError err = deserializeJson(doc, "%*$£¤"); - REQUIRE(err == JsonError::InvalidInput); + REQUIRE(err == DeserializationError::InvalidInput); } SECTION("Premature null-terminator") { SECTION("In escape sequence") { - JsonError err = deserializeJson(doc, "\"\\"); + DeserializationError err = deserializeJson(doc, "\"\\"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("In block comment") { - JsonError err = deserializeJson(doc, "/* comment"); + DeserializationError err = deserializeJson(doc, "/* comment"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("In double quoted string") { - JsonError err = deserializeJson(doc, "\"hello"); + DeserializationError err = deserializeJson(doc, "\"hello"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("In single quoted string") { - JsonError err = deserializeJson(doc, "'hello"); + DeserializationError err = deserializeJson(doc, "'hello"); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } } SECTION("Premature end of input") { SECTION("In escape sequence") { - JsonError err = deserializeJson(doc, "\"\\n\"", 2); + DeserializationError err = deserializeJson(doc, "\"\\n\"", 2); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("In block comment") { - JsonError err = deserializeJson(doc, "/* comment */", 10); + DeserializationError err = deserializeJson(doc, "/* comment */", 10); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("In double quoted string") { - JsonError err = deserializeJson(doc, "\"hello\"", 6); + DeserializationError err = deserializeJson(doc, "\"hello\"", 6); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } SECTION("In single quoted string") { - JsonError err = deserializeJson(doc, "'hello'", 6); + DeserializationError err = deserializeJson(doc, "'hello'", 6); - REQUIRE(err == JsonError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } } } diff --git a/test/JsonDeserializer/nestingLimit.cpp b/test/JsonDeserializer/nestingLimit.cpp index d2c41d5b4..fb116762e 100644 --- a/test/JsonDeserializer/nestingLimit.cpp +++ b/test/JsonDeserializer/nestingLimit.cpp @@ -5,8 +5,9 @@ #include #include -#define SHOULD_WORK(expression) REQUIRE(JsonError::Ok == expression); -#define SHOULD_FAIL(expression) REQUIRE(JsonError::TooDeep == expression); +#define SHOULD_WORK(expression) REQUIRE(DeserializationError::Ok == expression); +#define SHOULD_FAIL(expression) \ + REQUIRE(DeserializationError::TooDeep == expression); TEST_CASE("JsonDeserializer nestingLimit") { DynamicJsonDocument doc; diff --git a/test/JsonDeserializer/std_istream.cpp b/test/JsonDeserializer/std_istream.cpp index b1f242185..3e894fe07 100644 --- a/test/JsonDeserializer/std_istream.cpp +++ b/test/JsonDeserializer/std_istream.cpp @@ -12,10 +12,10 @@ TEST_CASE("deserializeJson(std::istream&)") { SECTION("array") { std::istringstream json(" [ 42 /* comment */ ] "); - JsonError err = deserializeJson(doc, json); + DeserializationError err = deserializeJson(doc, json); JsonArray& arr = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == arr.size()); REQUIRE(42 == arr[0]); } @@ -23,10 +23,10 @@ TEST_CASE("deserializeJson(std::istream&)") { SECTION("object") { std::istringstream json(" { hello : world // comment\n }"); - JsonError err = deserializeJson(doc, json); + DeserializationError err = deserializeJson(doc, json); JsonObject& obj = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(1 == obj.size()); REQUIRE(std::string("world") == obj["hello"]); } diff --git a/test/JsonDeserializer/std_string.cpp b/test/JsonDeserializer/std_string.cpp index baa5ee531..bd5e383b1 100644 --- a/test/JsonDeserializer/std_string.cpp +++ b/test/JsonDeserializer/std_string.cpp @@ -11,25 +11,25 @@ TEST_CASE("deserializeJson(const std::string&)") { SECTION("should accept const string") { const std::string input("[42]"); - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("should accept temporary string") { - JsonError err = deserializeJson(doc, std::string("[42]")); + DeserializationError err = deserializeJson(doc, std::string("[42]")); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("should duplicate content") { std::string input("[\"hello\"]"); - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); input[2] = 'X'; // alter the string tomake sure we made a copy JsonArray &array = doc.as(); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(std::string("hello") == array[0]); } } diff --git a/test/Misc/unsigned_char.cpp b/test/Misc/unsigned_char.cpp index 4471e6767..04b70f82f 100644 --- a/test/Misc/unsigned_char.cpp +++ b/test/Misc/unsigned_char.cpp @@ -14,18 +14,18 @@ TEST_CASE("unsigned char[]") { unsigned char input[] = "{\"a\":42}"; StaticJsonDocument doc; - JsonError err = deserializeJson(doc, input); + DeserializationError err = deserializeJson(doc, input); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("deserializeMsgPack()") { unsigned char input[] = "\xDE\x00\x01\xA5Hello\xA5world"; StaticJsonDocument doc; - MsgPackError err = deserializeMsgPack(doc, input); + DeserializationError err = deserializeMsgPack(doc, input); - REQUIRE(err == MsgPackError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("JsonVariant") { diff --git a/test/Misc/vla.cpp b/test/Misc/vla.cpp index 89207c89b..b7b5929ad 100644 --- a/test/Misc/vla.cpp +++ b/test/Misc/vla.cpp @@ -23,9 +23,9 @@ TEST_CASE("Variable Length Array") { strcpy(vla, "{\"a\":42}"); StaticJsonDocument doc; - JsonError err = deserializeJson(doc, vla); + DeserializationError err = deserializeJson(doc, vla); - REQUIRE(err == JsonError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("deserializeMsgPack()") { @@ -34,9 +34,9 @@ TEST_CASE("Variable Length Array") { memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15); StaticJsonDocument doc; - MsgPackError err = deserializeMsgPack(doc, vla); + DeserializationError err = deserializeMsgPack(doc, vla); - REQUIRE(err == MsgPackError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("JsonVariant") { diff --git a/test/MsgPack/CMakeLists.txt b/test/MsgPack/CMakeLists.txt index 4565892b0..74b7cb3f6 100644 --- a/test/MsgPack/CMakeLists.txt +++ b/test/MsgPack/CMakeLists.txt @@ -3,7 +3,6 @@ # MIT License add_executable(MsgPackTests - MsgPackError.cpp deserializeArray.cpp deserializeObject.cpp deserializeStaticVariant.cpp diff --git a/test/MsgPack/MsgPackError.cpp b/test/MsgPack/MsgPackError.cpp deleted file mode 100644 index eba414344..000000000 --- a/test/MsgPack/MsgPackError.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#include -#include - -void testStringification(MsgPackError error, std::string expected) { - REQUIRE(error.c_str() == expected); -} - -void testBoolification(MsgPackError error, bool expected) { - CHECK(error == expected); -} - -#define TEST_STRINGIFICATION(symbol) \ - testStringification(MsgPackError::symbol, #symbol) - -#define TEST_BOOLIFICATION(symbol, expected) \ - testBoolification(MsgPackError::symbol, expected) - -TEST_CASE("MsgPackError") { - SECTION("c_str()") { - TEST_STRINGIFICATION(Ok); - TEST_STRINGIFICATION(NotSupported); - TEST_STRINGIFICATION(NoMemory); - TEST_STRINGIFICATION(TooDeep); - TEST_STRINGIFICATION(IncompleteInput); - } - - SECTION("as boolean") { - TEST_BOOLIFICATION(Ok, false); - TEST_BOOLIFICATION(NotSupported, true); - TEST_BOOLIFICATION(NoMemory, true); - TEST_BOOLIFICATION(TooDeep, true); - TEST_BOOLIFICATION(IncompleteInput, true); - } - - SECTION("ostream") { - std::stringstream s; - s << MsgPackError::NotSupported; - REQUIRE(s.str() == "NotSupported"); - } -} diff --git a/test/MsgPack/deserializeArray.cpp b/test/MsgPack/deserializeArray.cpp index c1b8beed1..30e2aea8b 100644 --- a/test/MsgPack/deserializeArray.cpp +++ b/test/MsgPack/deserializeArray.cpp @@ -12,20 +12,20 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("empty") { const char* input = "\x90"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonArray& array = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(array.size() == 0); } SECTION("two integers") { const char* input = "\x92\x01\x02"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonArray& array = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(array.size() == 2); REQUIRE(array[0] == 1); REQUIRE(array[1] == 2); @@ -36,20 +36,20 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("empty") { const char* input = "\xDC\x00\x00"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonArray& array = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(array.size() == 0); } SECTION("two strings") { const char* input = "\xDC\x00\x02\xA5hello\xA5world"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonArray& array = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(array.size() == 2); REQUIRE(array[0] == "hello"); REQUIRE(array[1] == "world"); @@ -60,10 +60,10 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { SECTION("empty") { const char* input = "\xDD\x00\x00\x00\x00"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonArray& array = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(array.size() == 0); } @@ -71,10 +71,10 @@ TEST_CASE("deserializeMsgPack(JsonArray&)") { const char* input = "\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonArray& array = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(array.size() == 2); REQUIRE(array[0] == 0.0f); REQUIRE(array[1] == 3.14f); diff --git a/test/MsgPack/deserializeObject.cpp b/test/MsgPack/deserializeObject.cpp index 9557a28e5..1530beb7b 100644 --- a/test/MsgPack/deserializeObject.cpp +++ b/test/MsgPack/deserializeObject.cpp @@ -12,10 +12,10 @@ TEST_CASE("deserialize MsgPack object") { SECTION("empty") { const char* input = "\x80"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonObject& obj = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 0); } @@ -23,10 +23,10 @@ TEST_CASE("deserialize MsgPack object") { SECTION("two integers") { const char* input = "\x82\xA3one\x01\xA3two\x02"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonObject& obj = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["one"] == 1); @@ -38,10 +38,10 @@ TEST_CASE("deserialize MsgPack object") { SECTION("empty") { const char* input = "\xDE\x00\x00"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonObject& obj = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 0); } @@ -49,10 +49,10 @@ TEST_CASE("deserialize MsgPack object") { SECTION("two strings") { const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonObject& obj = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["H"] == "hello"); @@ -64,10 +64,10 @@ TEST_CASE("deserialize MsgPack object") { SECTION("empty") { const char* input = "\xDF\x00\x00\x00\x00"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonObject& obj = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 0); } @@ -77,10 +77,10 @@ TEST_CASE("deserialize MsgPack object") { "\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48" "\xF5\xC3"; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); JsonObject& obj = doc.as(); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(doc.is()); REQUIRE(obj.size() == 2); REQUIRE(obj["zero"] == 0.0f); diff --git a/test/MsgPack/deserializeStaticVariant.cpp b/test/MsgPack/deserializeStaticVariant.cpp index f4eb831cf..5944f7c7e 100644 --- a/test/MsgPack/deserializeStaticVariant.cpp +++ b/test/MsgPack/deserializeStaticVariant.cpp @@ -8,124 +8,133 @@ static const size_t epsilon = sizeof(void*); template -static void check(const char* input, MsgPackError expected) { +static void check(const char* input, DeserializationError expected) { StaticJsonDocument variant; - MsgPackError error = deserializeMsgPack(variant, input); + DeserializationError error = deserializeMsgPack(variant, input); REQUIRE(error == expected); } TEST_CASE("deserializeMsgPack(StaticJsonDocument&)") { SECTION("single values always fit") { - check<0>("\xc0", MsgPackError::Ok); // nil - check<0>("\xc2", MsgPackError::Ok); // false - check<0>("\xc3", MsgPackError::Ok); // true - check<0>("\xcc\x00", MsgPackError::Ok); // uint 8 - check<0>("\xcd\x30\x39", MsgPackError::Ok); // uint 16 - check<0>("\xCE\x12\x34\x56\x78", MsgPackError::Ok); // uint 32 + check<0>("\xc0", DeserializationError::Ok); // nil + check<0>("\xc2", DeserializationError::Ok); // false + check<0>("\xc3", DeserializationError::Ok); // true + check<0>("\xcc\x00", DeserializationError::Ok); // uint 8 + check<0>("\xcd\x30\x39", DeserializationError::Ok); // uint 16 + check<0>("\xCE\x12\x34\x56\x78", DeserializationError::Ok); // uint 32 } SECTION("fixstr") { - check<0>("\xA0", MsgPackError::Ok); - check<0>("\xA1H", MsgPackError::NoMemory); - check<4>("\xA1H", MsgPackError::Ok); - check<4>("\xA5Hello", MsgPackError::NoMemory); + check<0>("\xA0", DeserializationError::Ok); + check<0>("\xA1H", DeserializationError::NoMemory); + check<4>("\xA1H", DeserializationError::Ok); + check<4>("\xA5Hello", DeserializationError::NoMemory); } SECTION("str 8") { - check<0>("\xD9\x00", MsgPackError::Ok); - check<0>("\xD9\x01H", MsgPackError::NoMemory); - check<4>("\xD9\x01H", MsgPackError::Ok); - check<4>("\xD9\x05Hello", MsgPackError::NoMemory); + check<0>("\xD9\x00", DeserializationError::Ok); + check<0>("\xD9\x01H", DeserializationError::NoMemory); + check<4>("\xD9\x01H", DeserializationError::Ok); + check<4>("\xD9\x05Hello", DeserializationError::NoMemory); } SECTION("str 16") { - check<0>("\xDA\x00\x00", MsgPackError::Ok); - check<0>("\xDA\x00\x01H", MsgPackError::NoMemory); - check<4>("\xDA\x00\x01H", MsgPackError::Ok); - check<4>("\xDA\x00\x05Hello", MsgPackError::NoMemory); + check<0>("\xDA\x00\x00", DeserializationError::Ok); + check<0>("\xDA\x00\x01H", DeserializationError::NoMemory); + check<4>("\xDA\x00\x01H", DeserializationError::Ok); + check<4>("\xDA\x00\x05Hello", DeserializationError::NoMemory); } SECTION("str 32") { - check<0>("\xDB\x00\x00\x00\x00", MsgPackError::Ok); - check<0>("\xDB\x00\x00\x00\x01H", MsgPackError::NoMemory); - check<4>("\xDB\x00\x00\x00\x01H", MsgPackError::Ok); - check<4>("\xDB\x00\x00\x00\x05Hello", MsgPackError::NoMemory); + check<0>("\xDB\x00\x00\x00\x00", DeserializationError::Ok); + check<0>("\xDB\x00\x00\x00\x01H", DeserializationError::NoMemory); + check<4>("\xDB\x00\x00\x00\x01H", DeserializationError::Ok); + check<4>("\xDB\x00\x00\x00\x05Hello", DeserializationError::NoMemory); } SECTION("fixarray") { - check("\x90", MsgPackError::Ok); // [] - check("\x91\x01", MsgPackError::NoMemory); // [1] - check("\x91\x01", MsgPackError::Ok); // [1] - check("\x92\x01\x02", MsgPackError::NoMemory); // [1,2] + check("\x90", DeserializationError::Ok); // [] + check("\x91\x01", + DeserializationError::NoMemory); // [1] + check("\x91\x01", DeserializationError::Ok); // [1] + check("\x92\x01\x02", + DeserializationError::NoMemory); // [1,2] } SECTION("array 16") { - check("\xDC\x00\x00", MsgPackError::Ok); - check("\xDC\x00\x01\x01", MsgPackError::NoMemory); - check("\xDC\x00\x01\x01", MsgPackError::Ok); - check("\xDC\x00\x02\x01\x02", MsgPackError::NoMemory); + check("\xDC\x00\x00", DeserializationError::Ok); + check("\xDC\x00\x01\x01", + DeserializationError::NoMemory); + check("\xDC\x00\x01\x01", DeserializationError::Ok); + check("\xDC\x00\x02\x01\x02", + DeserializationError::NoMemory); } SECTION("array 32") { - check("\xDD\x00\x00\x00\x00", MsgPackError::Ok); + check("\xDD\x00\x00\x00\x00", DeserializationError::Ok); check("\xDD\x00\x00\x00\x01\x01", - MsgPackError::NoMemory); - check("\xDD\x00\x00\x00\x01\x01", MsgPackError::Ok); + DeserializationError::NoMemory); + check("\xDD\x00\x00\x00\x01\x01", + DeserializationError::Ok); check("\xDD\x00\x00\x00\x02\x01\x02", - MsgPackError::NoMemory); + DeserializationError::NoMemory); } SECTION("fixmap") { SECTION("{}") { - check("\x80", MsgPackError::Ok); + check("\x80", DeserializationError::Ok); } SECTION("{H:1}") { - check("\x81\xA1H\x01", MsgPackError::NoMemory); - check("\x81\xA1H\x01", MsgPackError::Ok); + check("\x81\xA1H\x01", + DeserializationError::NoMemory); + check("\x81\xA1H\x01", + DeserializationError::Ok); } SECTION("{H:1,W:2}") { check("\x82\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); + DeserializationError::NoMemory); check("\x82\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + DeserializationError::Ok); } } SECTION("map 16") { SECTION("{}") { - check("\xDE\x00\x00", MsgPackError::Ok); + check("\xDE\x00\x00", DeserializationError::Ok); } SECTION("{H:1}") { check("\xDE\x00\x01\xA1H\x01", - MsgPackError::NoMemory); + DeserializationError::NoMemory); check("\xDE\x00\x01\xA1H\x01", - MsgPackError::Ok); + DeserializationError::Ok); } SECTION("{H:1,W:2}") { check("\xDE\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::NoMemory); + DeserializationError::NoMemory); check("\xDE\x00\x02\xA1H\x01\xA1W\x02", - MsgPackError::Ok); + DeserializationError::Ok); } } SECTION("map 32") { SECTION("{}") { - check("\xDF\x00\x00\x00\x00", MsgPackError::Ok); + check("\xDF\x00\x00\x00\x00", + DeserializationError::Ok); } SECTION("{H:1}") { check("\xDF\x00\x00\x00\x01\xA1H\x01", - MsgPackError::NoMemory); + DeserializationError::NoMemory); check("\xDF\x00\x00\x00\x01\xA1H\x01", - MsgPackError::Ok); + DeserializationError::Ok); } SECTION("{H:1,W:2}") { check( - "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::NoMemory); + "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", + DeserializationError::NoMemory); check( - "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", MsgPackError::Ok); + "\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02", DeserializationError::Ok); } } } diff --git a/test/MsgPack/deserializeVariant.cpp b/test/MsgPack/deserializeVariant.cpp index 25c32c321..11efa490f 100644 --- a/test/MsgPack/deserializeVariant.cpp +++ b/test/MsgPack/deserializeVariant.cpp @@ -9,9 +9,9 @@ template static void check(const char* input, U expected) { DynamicJsonDocument variant; - MsgPackError error = deserializeMsgPack(variant, input); + DeserializationError error = deserializeMsgPack(variant, input); - REQUIRE(error == MsgPackError::Ok); + REQUIRE(error == DeserializationError::Ok); REQUIRE(variant.is()); REQUIRE(variant.as() == expected); } diff --git a/test/MsgPack/incompleteInput.cpp b/test/MsgPack/incompleteInput.cpp index 8d1715c83..64a494d67 100644 --- a/test/MsgPack/incompleteInput.cpp +++ b/test/MsgPack/incompleteInput.cpp @@ -5,17 +5,17 @@ #include #include -MsgPackError deserialize(const char* input, size_t len) { +DeserializationError deserialize(const char* input, size_t len) { DynamicJsonDocument doc; return deserializeMsgPack(doc, input, len); } void checkAllSizes(const char* input, size_t len) { - REQUIRE(deserialize(input, len) == MsgPackError::Ok); + REQUIRE(deserialize(input, len) == DeserializationError::Ok); while (--len) { - REQUIRE(deserialize(input, len) == MsgPackError::IncompleteInput); + REQUIRE(deserialize(input, len) == DeserializationError::IncompleteInput); } } diff --git a/test/MsgPack/nestingLimit.cpp b/test/MsgPack/nestingLimit.cpp index a56acc2fe..5a4963f71 100644 --- a/test/MsgPack/nestingLimit.cpp +++ b/test/MsgPack/nestingLimit.cpp @@ -5,27 +5,28 @@ #include #include -static void check(const char* input, MsgPackError expected, uint8_t limit) { +static void check(const char* input, DeserializationError expected, + uint8_t limit) { DynamicJsonDocument doc; doc.nestingLimit = limit; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); REQUIRE(error == expected); } TEST_CASE("Errors returned by deserializeMsgPack()") { SECTION("object too deep") { - check("\x80", MsgPackError::TooDeep, 0); // {} - check("\x80", MsgPackError::Ok, 1); // {} - check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}} - check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}} + check("\x80", DeserializationError::TooDeep, 0); // {} + check("\x80", DeserializationError::Ok, 1); // {} + check("\x81\xA1H\x80", DeserializationError::TooDeep, 1); // {H:{}} + check("\x81\xA1H\x80", DeserializationError::Ok, 2); // {H:{}} } SECTION("array too deep") { - check("\x90", MsgPackError::TooDeep, 0); // [] - check("\x90", MsgPackError::Ok, 1); // [] - check("\x91\x90", MsgPackError::TooDeep, 1); // [[]] - check("\x91\x90", MsgPackError::Ok, 2); // [[]] + check("\x90", DeserializationError::TooDeep, 0); // [] + check("\x90", DeserializationError::Ok, 1); // [] + check("\x91\x90", DeserializationError::TooDeep, 1); // [[]] + check("\x91\x90", DeserializationError::Ok, 2); // [[]] } } diff --git a/test/MsgPack/notSupported.cpp b/test/MsgPack/notSupported.cpp index e6ab63008..a5673b0c2 100644 --- a/test/MsgPack/notSupported.cpp +++ b/test/MsgPack/notSupported.cpp @@ -8,9 +8,9 @@ static void checkNotSupported(const char* input) { DynamicJsonDocument doc; - MsgPackError error = deserializeMsgPack(doc, input); + DeserializationError error = deserializeMsgPack(doc, input); - REQUIRE(error == MsgPackError::NotSupported); + REQUIRE(error == DeserializationError::NotSupported); } TEST_CASE("deserializeMsgPack() return NotSupported") { diff --git a/test/MsgPack/std_istream.cpp b/test/MsgPack/std_istream.cpp index d04dc935d..dc6eedba4 100644 --- a/test/MsgPack/std_istream.cpp +++ b/test/MsgPack/std_istream.cpp @@ -11,9 +11,9 @@ TEST_CASE("deserializeMsgPack(std::istream&)") { SECTION("should accept a zero in input") { std::istringstream input(std::string("\x92\x00\x02", 3)); - MsgPackError err = deserializeMsgPack(doc, input); + DeserializationError err = deserializeMsgPack(doc, input); - REQUIRE(err == MsgPackError::Ok); + REQUIRE(err == DeserializationError::Ok); JsonArray& arr = doc.as(); REQUIRE(arr[0] == 0); REQUIRE(arr[1] == 2); @@ -22,8 +22,8 @@ TEST_CASE("deserializeMsgPack(std::istream&)") { SECTION("should detect incomplete input") { std::istringstream input("\x92\x00\x02"); - MsgPackError err = deserializeMsgPack(doc, input); + DeserializationError err = deserializeMsgPack(doc, input); - REQUIRE(err == MsgPackError::IncompleteInput); + REQUIRE(err == DeserializationError::IncompleteInput); } } diff --git a/test/MsgPack/std_string.cpp b/test/MsgPack/std_string.cpp index bc3747193..7b03e51df 100644 --- a/test/MsgPack/std_string.cpp +++ b/test/MsgPack/std_string.cpp @@ -11,32 +11,34 @@ TEST_CASE("deserializeMsgPack(const std::string&)") { SECTION("should accept const string") { const std::string input("\x92\x01\x02"); - MsgPackError err = deserializeMsgPack(doc, input); + DeserializationError err = deserializeMsgPack(doc, input); - REQUIRE(err == MsgPackError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("should accept temporary string") { - MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x01\x02")); + DeserializationError err = + deserializeMsgPack(doc, std::string("\x92\x01\x02")); - REQUIRE(err == MsgPackError::Ok); + REQUIRE(err == DeserializationError::Ok); } SECTION("should duplicate content") { std::string input("\x91\xA5hello"); - MsgPackError err = deserializeMsgPack(doc, input); + DeserializationError err = deserializeMsgPack(doc, input); input[2] = 'X'; // alter the string tomake sure we made a copy JsonArray& array = doc.as(); - REQUIRE(err == MsgPackError::Ok); + REQUIRE(err == DeserializationError::Ok); REQUIRE(std::string("hello") == array[0]); } SECTION("should accept a zero in input") { - MsgPackError err = deserializeMsgPack(doc, std::string("\x92\x00\x02", 3)); + DeserializationError err = + deserializeMsgPack(doc, std::string("\x92\x00\x02", 3)); - REQUIRE(err == MsgPackError::Ok); + REQUIRE(err == DeserializationError::Ok); JsonArray& arr = doc.as(); REQUIRE(arr[0] == 0); REQUIRE(arr[1] == 2); From 58cb793c9671919d7d7a0f984dddeb36abf1acb9 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Thu, 17 May 2018 13:46:23 +0200 Subject: [PATCH 0030/1079] Reorganized polyfills --- src/ArduinoJson.hpp | 2 +- .../{TypeTraits => Data}/IsVariant.hpp | 8 +- src/ArduinoJson/Data/ValueSaver.hpp | 6 +- src/ArduinoJson/DynamicJsonDocument.hpp | 12 +- .../Json/{Encoding.hpp => EscapeSequence.hpp} | 6 +- .../{Serialization => }/IndentedPrint.hpp | 0 .../JsonDeserializer.hpp | 17 +-- .../{Serialization => }/JsonSerializer.hpp | 24 ++-- .../Json/{Serialization => }/JsonWriter.hpp | 14 +-- .../Json/{Serialization => }/Prettyfier.hpp | 0 src/ArduinoJson/JsonArray.hpp | 8 +- src/ArduinoJson/JsonObject.hpp | 5 +- src/ArduinoJson/JsonObjectSubscript.hpp | 6 +- src/ArduinoJson/JsonVariant.hpp | 111 +++++++++--------- src/ArduinoJson/JsonVariantComparisons.hpp | 16 +-- src/ArduinoJson/JsonVariantImpl.hpp | 8 +- src/ArduinoJson/JsonVariantOr.hpp | 7 +- src/ArduinoJson/JsonVariantSubscripts.hpp | 18 +-- src/ArduinoJson/Memory/StaticJsonBuffer.hpp | 2 +- .../MsgPack/MsgPackDeserializer.hpp | 11 +- src/ArduinoJson/MsgPack/endianess.hpp | 5 +- .../Serialization => Numbers}/FloatParts.hpp | 6 +- .../{TypeTraits => Numbers}/FloatTraits.hpp | 4 +- src/ArduinoJson/{Text => Numbers}/isFloat.hpp | 0 .../{Text => Numbers}/isInteger.hpp | 0 .../{Text => Numbers}/parseFloat.hpp | 2 +- .../{Text => Numbers}/parseInteger.hpp | 0 src/ArduinoJson/Polyfills/math.hpp | 8 +- .../Max.hpp => Polyfills/mpl/max.hpp} | 0 src/ArduinoJson/Polyfills/type_traits.hpp | 18 +++ .../type_traits/enable_if.hpp} | 8 +- .../type_traits/integral_constant.hpp | 19 +++ .../Polyfills/type_traits/is_array.hpp | 19 +++ .../type_traits/is_base_of.hpp} | 6 +- .../type_traits/is_const.hpp} | 14 +-- .../type_traits/is_floating_point.hpp | 21 ++++ .../Polyfills/type_traits/is_integral.hpp | 35 ++++++ .../type_traits/is_same.hpp} | 14 +-- .../Polyfills/type_traits/is_signed.hpp | 44 +++++++ .../Polyfills/type_traits/is_unsigned.hpp | 38 ++++++ .../type_traits/remove_const.hpp} | 8 +- .../type_traits/remove_reference.hpp} | 8 +- src/ArduinoJson/StaticJsonDocument.hpp | 12 +- src/ArduinoJson/Strings/CharPointer.hpp | 8 +- src/ArduinoJson/Strings/StringTraits.hpp | 10 +- src/ArduinoJson/TypeTraits/IsArray.hpp | 24 ---- src/ArduinoJson/TypeTraits/IsChar.hpp | 23 ---- .../TypeTraits/IsFloatingPoint.hpp | 18 --- src/ArduinoJson/TypeTraits/IsIntegral.hpp | 26 ---- .../TypeTraits/IsSignedIntegral.hpp | 28 ----- .../TypeTraits/IsUnsignedIntegral.hpp | 28 ----- src/ArduinoJson/Writing/Writer.hpp | 2 +- src/ArduinoJson/deserializeJson.hpp | 6 +- src/ArduinoJson/deserializeMsgPack.hpp | 4 +- test/JsonWriter/writeFloat.cpp | 2 +- test/JsonWriter/writeString.cpp | 2 +- test/Misc/FloatParts.cpp | 2 +- test/Misc/TypeTraits.cpp | 48 ++++++-- test/Polyfills/isFloat.cpp | 2 +- test/Polyfills/isInteger.cpp | 2 +- test/Polyfills/parseFloat.cpp | 2 +- test/Polyfills/parseInteger.cpp | 2 +- 62 files changed, 431 insertions(+), 378 deletions(-) rename src/ArduinoJson/{TypeTraits => Data}/IsVariant.hpp (57%) rename src/ArduinoJson/Json/{Encoding.hpp => EscapeSequence.hpp} (90%) rename src/ArduinoJson/Json/{Serialization => }/IndentedPrint.hpp (100%) rename src/ArduinoJson/Json/{Deserialization => }/JsonDeserializer.hpp (95%) rename src/ArduinoJson/Json/{Serialization => }/JsonSerializer.hpp (89%) rename src/ArduinoJson/Json/{Serialization => }/JsonWriter.hpp (90%) rename src/ArduinoJson/Json/{Serialization => }/Prettyfier.hpp (100%) rename src/ArduinoJson/{Json/Serialization => Numbers}/FloatParts.hpp (95%) rename src/ArduinoJson/{TypeTraits => Numbers}/FloatTraits.hpp (98%) rename src/ArduinoJson/{Text => Numbers}/isFloat.hpp (100%) rename src/ArduinoJson/{Text => Numbers}/isInteger.hpp (100%) rename src/ArduinoJson/{Text => Numbers}/parseFloat.hpp (97%) rename src/ArduinoJson/{Text => Numbers}/parseInteger.hpp (100%) rename src/ArduinoJson/{TypeTraits/Max.hpp => Polyfills/mpl/max.hpp} (100%) create mode 100644 src/ArduinoJson/Polyfills/type_traits.hpp rename src/ArduinoJson/{TypeTraits/EnableIf.hpp => Polyfills/type_traits/enable_if.hpp} (74%) create mode 100644 src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp create mode 100644 src/ArduinoJson/Polyfills/type_traits/is_array.hpp rename src/ArduinoJson/{TypeTraits/IsBaseOf.hpp => Polyfills/type_traits/is_base_of.hpp} (88%) rename src/ArduinoJson/{TypeTraits/IsConst.hpp => Polyfills/type_traits/is_const.hpp} (61%) create mode 100644 src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp create mode 100644 src/ArduinoJson/Polyfills/type_traits/is_integral.hpp rename src/ArduinoJson/{TypeTraits/IsSame.hpp => Polyfills/type_traits/is_same.hpp} (63%) create mode 100644 src/ArduinoJson/Polyfills/type_traits/is_signed.hpp create mode 100644 src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp rename src/ArduinoJson/{TypeTraits/RemoveConst.hpp => Polyfills/type_traits/remove_const.hpp} (73%) rename src/ArduinoJson/{TypeTraits/RemoveReference.hpp => Polyfills/type_traits/remove_reference.hpp} (73%) delete mode 100644 src/ArduinoJson/TypeTraits/IsArray.hpp delete mode 100644 src/ArduinoJson/TypeTraits/IsChar.hpp delete mode 100644 src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp delete mode 100644 src/ArduinoJson/TypeTraits/IsIntegral.hpp delete mode 100644 src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp delete mode 100644 src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index a1a015083..8b7e35945 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -9,7 +9,7 @@ #include "ArduinoJson/deserializeJson.hpp" #include "ArduinoJson/deserializeMsgPack.hpp" -#include "ArduinoJson/Json/Serialization/JsonSerializer.hpp" +#include "ArduinoJson/Json/JsonSerializer.hpp" #include "ArduinoJson/JsonArrayImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp" #include "ArduinoJson/JsonVariantImpl.hpp" diff --git a/src/ArduinoJson/TypeTraits/IsVariant.hpp b/src/ArduinoJson/Data/IsVariant.hpp similarity index 57% rename from src/ArduinoJson/TypeTraits/IsVariant.hpp rename to src/ArduinoJson/Data/IsVariant.hpp index f8b299f7a..2c5434171 100644 --- a/src/ArduinoJson/TypeTraits/IsVariant.hpp +++ b/src/ArduinoJson/Data/IsVariant.hpp @@ -4,7 +4,7 @@ #pragma once -#include "IsBaseOf.hpp" +#include "../Polyfills/type_traits.hpp" namespace ArduinoJson { namespace Internals { @@ -12,6 +12,6 @@ namespace Internals { class JsonVariantTag {}; template -struct IsVariant : IsBaseOf {}; -} -} +struct IsVariant : is_base_of {}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Data/ValueSaver.hpp b/src/ArduinoJson/Data/ValueSaver.hpp index 4416ebc91..d3f7e3aef 100644 --- a/src/ArduinoJson/Data/ValueSaver.hpp +++ b/src/ArduinoJson/Data/ValueSaver.hpp @@ -6,8 +6,8 @@ #include "../JsonVariant.hpp" #include "../Memory/JsonBuffer.hpp" +#include "../Polyfills/type_traits.hpp" #include "../Strings/StringTraits.hpp" -#include "../TypeTraits/EnableIf.hpp" namespace ArduinoJson { namespace Internals { @@ -23,7 +23,7 @@ struct ValueSaver { template struct ValueSaver< - Source, typename EnableIf::should_duplicate>::type> { + Source, typename enable_if::should_duplicate>::type> { template static bool save(JsonBuffer* buffer, Destination& dest, Source source) { if (!StringTraits::is_null(source)) { @@ -41,7 +41,7 @@ struct ValueSaver< // const char*, const signed char*, const unsigned char* template struct ValueSaver< - Char*, typename EnableIf::should_duplicate>::type> { + Char*, typename enable_if::should_duplicate>::type> { template static bool save(JsonBuffer*, Destination& dest, Char* source) { dest = reinterpret_cast(source); diff --git a/src/ArduinoJson/DynamicJsonDocument.hpp b/src/ArduinoJson/DynamicJsonDocument.hpp index 884c615df..7f88f76ca 100644 --- a/src/ArduinoJson/DynamicJsonDocument.hpp +++ b/src/ArduinoJson/DynamicJsonDocument.hpp @@ -34,8 +34,8 @@ class DynamicJsonDocument { // JsonObject& to() template - typename Internals::EnableIf::value, - JsonObject&>::type + typename Internals::enable_if::value, + JsonObject&>::type to() { clear(); JsonObject* object = new (&_buffer) JsonObject(&_buffer); @@ -46,8 +46,8 @@ class DynamicJsonDocument { // JsonArray& to() template - typename Internals::EnableIf::value, - JsonArray&>::type + typename Internals::enable_if::value, + JsonArray&>::type to() { clear(); JsonArray* array = new (&_buffer) JsonArray(&_buffer); @@ -58,8 +58,8 @@ class DynamicJsonDocument { // JsonVariant& to() template - typename Internals::EnableIf::value, - T&>::type + typename Internals::enable_if::value, + T&>::type to() { clear(); return _root; diff --git a/src/ArduinoJson/Json/Encoding.hpp b/src/ArduinoJson/Json/EscapeSequence.hpp similarity index 90% rename from src/ArduinoJson/Json/Encoding.hpp rename to src/ArduinoJson/Json/EscapeSequence.hpp index a0efa2c74..fd3a760c7 100644 --- a/src/ArduinoJson/Json/Encoding.hpp +++ b/src/ArduinoJson/Json/EscapeSequence.hpp @@ -7,7 +7,7 @@ namespace ArduinoJson { namespace Internals { -class Encoding { +class EscapeSequence { public: // Optimized for code size on a 8-bit AVR static char escapeChar(char c) { @@ -33,5 +33,5 @@ class Encoding { return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0]; } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Json/Serialization/IndentedPrint.hpp b/src/ArduinoJson/Json/IndentedPrint.hpp similarity index 100% rename from src/ArduinoJson/Json/Serialization/IndentedPrint.hpp rename to src/ArduinoJson/Json/IndentedPrint.hpp diff --git a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp b/src/ArduinoJson/Json/JsonDeserializer.hpp similarity index 95% rename from src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp rename to src/ArduinoJson/Json/JsonDeserializer.hpp index 3b5d33012..b5457852b 100644 --- a/src/ArduinoJson/Json/Deserialization/JsonDeserializer.hpp +++ b/src/ArduinoJson/Json/JsonDeserializer.hpp @@ -4,12 +4,12 @@ #pragma once -#include "../../DeserializationError.hpp" -#include "../../JsonVariant.hpp" -#include "../../Memory/JsonBuffer.hpp" -#include "../../Reading/Reader.hpp" -#include "../../TypeTraits/IsConst.hpp" -#include "../Encoding.hpp" +#include "../DeserializationError.hpp" +#include "../JsonVariant.hpp" +#include "../Memory/JsonBuffer.hpp" +#include "../Polyfills/type_traits.hpp" +#include "../Reading/Reader.hpp" +#include "./EscapeSequence.hpp" namespace ArduinoJson { namespace Internals { @@ -168,7 +168,8 @@ class JsonDeserializer { } DeserializationError parseString(const char **result) { - typename RemoveReference::type::String str = _writer.startString(); + typename remove_reference::type::String str = + _writer.startString(); char c = current(); if (c == '\0') return DeserializationError::IncompleteInput; @@ -188,7 +189,7 @@ class JsonDeserializer { if (c == '\0') return DeserializationError::IncompleteInput; if (c == 'u') return DeserializationError::NotSupported; // replace char - c = Encoding::unescapeChar(c); + c = EscapeSequence::unescapeChar(c); if (c == '\0') return DeserializationError::InvalidInput; move(); } diff --git a/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp b/src/ArduinoJson/Json/JsonSerializer.hpp similarity index 89% rename from src/ArduinoJson/Json/Serialization/JsonSerializer.hpp rename to src/ArduinoJson/Json/JsonSerializer.hpp index cae6ac84d..6bcb0ba88 100644 --- a/src/ArduinoJson/Json/Serialization/JsonSerializer.hpp +++ b/src/ArduinoJson/Json/JsonSerializer.hpp @@ -4,15 +4,15 @@ #pragma once -#include "../../Print/DummyPrint.hpp" -#include "../../Print/DynamicStringBuilder.hpp" -#include "../../Print/StaticStringBuilder.hpp" +#include "../Print/DummyPrint.hpp" +#include "../Print/DynamicStringBuilder.hpp" +#include "../Print/StaticStringBuilder.hpp" #include "./IndentedPrint.hpp" #include "./JsonWriter.hpp" #include "./Prettyfier.hpp" #if ARDUINOJSON_ENABLE_STD_STREAM -#include "../../Print/StreamPrintAdapter.hpp" +#include "../Print/StreamPrintAdapter.hpp" #endif namespace ArduinoJson { @@ -96,8 +96,8 @@ class JsonSerializer { } // namespace Internals template -typename Internals::EnableIf::has_append, - size_t>::type +typename Internals::enable_if< + !Internals::StringTraits::has_append, size_t>::type serializeJson(const TSource &source, TDestination &destination) { Internals::JsonWriter writer(destination); Internals::JsonSerializer >::serialize( @@ -126,8 +126,8 @@ size_t serializeJson(const TSource &source, char (&buffer)[N]) { } template -typename Internals::EnableIf::has_append, - size_t>::type +typename Internals::enable_if::has_append, + size_t>::type serializeJson(const TSource &source, TDestination &str) { Internals::DynamicStringBuilder sb(str); return serializeJson(source, sb); @@ -153,16 +153,16 @@ size_t serializeJsonPretty(const TSource &source, char (&buffer)[N]) { } template -typename Internals::EnableIf::has_append, - size_t>::type +typename Internals::enable_if< + !Internals::StringTraits::has_append, size_t>::type serializeJsonPretty(const TSource &source, TDestination &print) { Internals::IndentedPrint indentedPrint(print); return serializeJsonPretty(source, indentedPrint); } template -typename Internals::EnableIf::has_append, - size_t>::type +typename Internals::enable_if::has_append, + size_t>::type serializeJsonPretty(const TSource &source, TDestination &str) { Internals::DynamicStringBuilder sb(str); return serializeJsonPretty(source, sb); diff --git a/src/ArduinoJson/Json/Serialization/JsonWriter.hpp b/src/ArduinoJson/Json/JsonWriter.hpp similarity index 90% rename from src/ArduinoJson/Json/Serialization/JsonWriter.hpp rename to src/ArduinoJson/Json/JsonWriter.hpp index f613f7e5b..93d7694c4 100644 --- a/src/ArduinoJson/Json/Serialization/JsonWriter.hpp +++ b/src/ArduinoJson/Json/JsonWriter.hpp @@ -5,10 +5,10 @@ #pragma once #include -#include "../../Data/JsonInteger.hpp" -#include "../../Polyfills/attributes.hpp" -#include "../Encoding.hpp" -#include "./FloatParts.hpp" +#include "../Data/JsonInteger.hpp" +#include "../Numbers/FloatParts.hpp" +#include "../Polyfills/attributes.hpp" +#include "./EscapeSequence.hpp" namespace ArduinoJson { namespace Internals { @@ -66,7 +66,7 @@ class JsonWriter { } void writeChar(char c) { - char specialChar = Encoding::escapeChar(c); + char specialChar = EscapeSequence::escapeChar(c); if (specialChar) { writeRaw('\\'); writeRaw(specialChar); @@ -77,14 +77,14 @@ class JsonWriter { template void writeFloat(TFloat value) { - if (isNaN(value)) return writeRaw("NaN"); + if (isnan(value)) return writeRaw("NaN"); if (value < 0.0) { writeRaw('-'); value = -value; } - if (isInfinity(value)) return writeRaw("Infinity"); + if (isinf(value)) return writeRaw("Infinity"); FloatParts parts(value); diff --git a/src/ArduinoJson/Json/Serialization/Prettyfier.hpp b/src/ArduinoJson/Json/Prettyfier.hpp similarity index 100% rename from src/ArduinoJson/Json/Serialization/Prettyfier.hpp rename to src/ArduinoJson/Json/Prettyfier.hpp diff --git a/src/ArduinoJson/JsonArray.hpp b/src/ArduinoJson/JsonArray.hpp index d52430fd8..d174c621e 100644 --- a/src/ArduinoJson/JsonArray.hpp +++ b/src/ArduinoJson/JsonArray.hpp @@ -9,11 +9,8 @@ #include "Data/ValueSaver.hpp" #include "JsonVariant.hpp" #include "Memory/JsonBufferAllocated.hpp" +#include "Polyfills/type_traits.hpp" #include "Strings/StringTraits.hpp" -#include "TypeTraits/EnableIf.hpp" -#include "TypeTraits/IsArray.hpp" -#include "TypeTraits/IsFloatingPoint.hpp" -#include "TypeTraits/IsSame.hpp" // Returns the size (in bytes) of an array with n elements. // Can be very handy to determine the size of a StaticJsonBuffer. @@ -88,7 +85,8 @@ class JsonArray : public Internals::ReferenceType, // bool set(size_t index, TValue value, uint8_t decimals); // TValue = float, double template - typename Internals::EnableIf::value, bool>::type + typename Internals::enable_if::value, + bool>::type set(size_t index, T value, uint8_t decimals) { return set_impl(index, JsonVariant(value, decimals)); } diff --git a/src/ArduinoJson/JsonObject.hpp b/src/ArduinoJson/JsonObject.hpp index def89b956..22c8af8e5 100644 --- a/src/ArduinoJson/JsonObject.hpp +++ b/src/ArduinoJson/JsonObject.hpp @@ -9,11 +9,8 @@ #include "Data/ValueSaver.hpp" #include "JsonPair.hpp" #include "Memory/JsonBufferAllocated.hpp" +#include "Polyfills/type_traits.hpp" #include "Strings/StringTraits.hpp" -#include "TypeTraits/EnableIf.hpp" -#include "TypeTraits/IsArray.hpp" -#include "TypeTraits/IsFloatingPoint.hpp" -#include "TypeTraits/IsSame.hpp" // Returns the size (in bytes) of an object with n elements. // Can be very handy to determine the size of a StaticJsonBuffer. diff --git a/src/ArduinoJson/JsonObjectSubscript.hpp b/src/ArduinoJson/JsonObjectSubscript.hpp index f323fb328..9d11ac201 100644 --- a/src/ArduinoJson/JsonObjectSubscript.hpp +++ b/src/ArduinoJson/JsonObjectSubscript.hpp @@ -6,7 +6,7 @@ #include "Configuration.hpp" #include "JsonVariantBase.hpp" -#include "TypeTraits/EnableIf.hpp" +#include "Polyfills/type_traits.hpp" #ifdef _MSC_VER #pragma warning(push) @@ -36,7 +36,7 @@ class JsonObjectSubscript // TValue = bool, char, long, int, short, float, double, // std::string, String, JsonArray, JsonObject template - FORCE_INLINE typename EnableIf::value, this_type&>::type + FORCE_INLINE typename enable_if::value, this_type&>::type operator=(const TValue& src) { _object.set(_key, src); return *this; @@ -70,7 +70,7 @@ class JsonObjectSubscript // TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant, // std::string, String, JsonArray, JsonObject template - FORCE_INLINE typename EnableIf::value, bool>::type set( + FORCE_INLINE typename enable_if::value, bool>::type set( const TValue& value) { return _object.set(_key, value); } diff --git a/src/ArduinoJson/JsonVariant.hpp b/src/ArduinoJson/JsonVariant.hpp index 1a79af063..a4ad82ee2 100644 --- a/src/ArduinoJson/JsonVariant.hpp +++ b/src/ArduinoJson/JsonVariant.hpp @@ -11,16 +11,8 @@ #include "Data/JsonVariantDefault.hpp" #include "Data/JsonVariantType.hpp" #include "JsonVariantBase.hpp" +#include "Polyfills/type_traits.hpp" #include "RawJson.hpp" -#include "TypeTraits/EnableIf.hpp" -#include "TypeTraits/IsChar.hpp" -#include "TypeTraits/IsFloatingPoint.hpp" -#include "TypeTraits/IsIntegral.hpp" -#include "TypeTraits/IsSame.hpp" -#include "TypeTraits/IsSignedIntegral.hpp" -#include "TypeTraits/IsUnsignedIntegral.hpp" -#include "TypeTraits/RemoveConst.hpp" -#include "TypeTraits/RemoveReference.hpp" namespace ArduinoJson { @@ -52,8 +44,9 @@ class JsonVariant : public Internals::JsonVariantBase { // JsonVariant(double value); // JsonVariant(float value); template - JsonVariant(T value, typename Internals::EnableIf< - Internals::IsFloatingPoint::value>::type * = 0) { + JsonVariant(T value, + typename Internals::enable_if< + Internals::is_floating_point::value>::type * = 0) { using namespace Internals; _type = JSON_FLOAT; _content.asFloat = static_cast(value); @@ -68,8 +61,8 @@ class JsonVariant : public Internals::JsonVariantBase { template JsonVariant( T value, - typename Internals::EnableIf::value || - Internals::IsSame::value>::type * = + typename Internals::enable_if::value && + Internals::is_signed::value>::type * = 0) { using namespace Internals; if (value >= 0) { @@ -84,9 +77,11 @@ class JsonVariant : public Internals::JsonVariantBase { // JsonVariant(unsigned int) // JsonVariant(unsigned long) template - JsonVariant(T value, - typename Internals::EnableIf< - Internals::IsUnsignedIntegral::value>::type * = 0) { + JsonVariant( + T value, + typename Internals::enable_if::value && + Internals::is_unsigned::value>::type * = + 0) { using namespace Internals; _type = JSON_POSITIVE_INTEGER; _content.asInteger = static_cast(value); @@ -97,10 +92,8 @@ class JsonVariant : public Internals::JsonVariantBase { // JsonVariant(const signed char*); // JsonVariant(const unsigned char*); template - JsonVariant( - const TChar *value, - typename Internals::EnableIf::value>::type * = - 0) { + JsonVariant(const TChar *value, + typename Internals::enable_if::type * = 0) { _type = Internals::JSON_STRING; _content.asString = reinterpret_cast(value); } @@ -143,13 +136,14 @@ class JsonVariant : public Internals::JsonVariantBase { // unsigned int as() const; // unsigned long as() const; template - const typename Internals::EnableIf::value, T>::type + const typename Internals::enable_if::value, T>::type as() const { return variantAsInteger(); } // bool as() const template - const typename Internals::EnableIf::value, T>::type + const typename Internals::enable_if::value, + T>::type as() const { return variantAsInteger() != 0; } @@ -157,8 +151,8 @@ class JsonVariant : public Internals::JsonVariantBase { // double as() const; // float as() const; template - const typename Internals::EnableIf::value, - T>::type + const typename Internals::enable_if::value, + T>::type as() const { return variantAsFloat(); } @@ -166,9 +160,9 @@ class JsonVariant : public Internals::JsonVariantBase { // const char* as() const; // const char* as() const; template - typename Internals::EnableIf::value || - Internals::IsSame::value, - const char *>::type + typename Internals::enable_if::value || + Internals::is_same::value, + const char *>::type as() const { return variantAsString(); } @@ -176,7 +170,7 @@ class JsonVariant : public Internals::JsonVariantBase { // std::string as() const; // String as() const; template - typename Internals::EnableIf::has_append, T>::type + typename Internals::enable_if::has_append, T>::type as() const { const char *cstr = variantAsString(); if (cstr) return T(cstr); @@ -188,9 +182,9 @@ class JsonVariant : public Internals::JsonVariantBase { // JsonArray& as const; // JsonArray& as const; template - typename Internals::EnableIf< - Internals::IsSame::type, - JsonArray>::value, + typename Internals::enable_if< + Internals::is_same::type, + JsonArray>::value, JsonArray &>::type as() const { return variantAsArray(); @@ -198,9 +192,9 @@ class JsonVariant : public Internals::JsonVariantBase { // // const JsonArray& as const; template - typename Internals::EnableIf< - Internals::IsSame::type, - const JsonArray>::value, + typename Internals::enable_if< + Internals::is_same::type, + const JsonArray>::value, const JsonArray &>::type as() const { return variantAsArray(); @@ -209,9 +203,9 @@ class JsonVariant : public Internals::JsonVariantBase { // JsonObject& as const; // JsonObject& as const; template - typename Internals::EnableIf< - Internals::IsSame::type, - JsonObject>::value, + typename Internals::enable_if< + Internals::is_same::type, + JsonObject>::value, JsonObject &>::type as() const { return variantAsObject(); @@ -220,9 +214,9 @@ class JsonVariant : public Internals::JsonVariantBase { // JsonObject& as const; // JsonObject& as const; template - typename Internals::EnableIf< - Internals::IsSame::type, - const JsonObject>::value, + typename Internals::enable_if< + Internals::is_same::type, + const JsonObject>::value, const JsonObject &>::type as() const { return variantAsObject(); @@ -230,8 +224,8 @@ class JsonVariant : public Internals::JsonVariantBase { // // JsonVariant as const; template - typename Internals::EnableIf::value, - T>::type + typename Internals::enable_if::value, + T>::type as() const { return *this; } @@ -249,22 +243,23 @@ class JsonVariant : public Internals::JsonVariantBase { // bool is() const; // bool is() const; template - typename Internals::EnableIf::value, bool>::type is() - const { + typename Internals::enable_if::value, bool>::type + is() const { return variantIsInteger(); } // // bool is() const; // bool is() const; template - typename Internals::EnableIf::value, bool>::type + typename Internals::enable_if::value, + bool>::type is() const { return variantIsFloat(); } // // bool is() const template - typename Internals::EnableIf::value, bool>::type + typename Internals::enable_if::value, bool>::type is() const { return variantIsBoolean(); } @@ -272,9 +267,9 @@ class JsonVariant : public Internals::JsonVariantBase { // bool is() const; // bool is() const; template - typename Internals::EnableIf::value || - Internals::IsSame::value, - bool>::type + typename Internals::enable_if::value || + Internals::is_same::value, + bool>::type is() const { return variantIsString(); } @@ -283,10 +278,11 @@ class JsonVariant : public Internals::JsonVariantBase { // bool is const; // bool is const; template - typename Internals::EnableIf< - Internals::IsSame::type>::type, - JsonArray>::value, + typename Internals::enable_if< + Internals::is_same< + typename Internals::remove_const< + typename Internals::remove_reference::type>::type, + JsonArray>::value, bool>::type is() const { return variantIsArray(); @@ -296,10 +292,11 @@ class JsonVariant : public Internals::JsonVariantBase { // bool is const; // bool is const; template - typename Internals::EnableIf< - Internals::IsSame::type>::type, - JsonObject>::value, + typename Internals::enable_if< + Internals::is_same< + typename Internals::remove_const< + typename Internals::remove_reference::type>::type, + JsonObject>::value, bool>::type is() const { return variantIsObject(); diff --git a/src/ArduinoJson/JsonVariantComparisons.hpp b/src/ArduinoJson/JsonVariantComparisons.hpp index dbd84d978..39317a679 100644 --- a/src/ArduinoJson/JsonVariantComparisons.hpp +++ b/src/ArduinoJson/JsonVariantComparisons.hpp @@ -4,9 +4,9 @@ #pragma once +#include "Data/IsVariant.hpp" +#include "Polyfills/type_traits.hpp" #include "Strings/StringTraits.hpp" -#include "TypeTraits/EnableIf.hpp" -#include "TypeTraits/IsVariant.hpp" namespace ArduinoJson { namespace Internals { @@ -21,7 +21,7 @@ class JsonVariantComparisons { } template - friend typename EnableIf::value, bool>::type + friend typename enable_if::value, bool>::type operator==(TComparand comparand, const JsonVariantComparisons &variant) { return variant.equals(comparand); } @@ -33,7 +33,7 @@ class JsonVariantComparisons { } template - friend typename EnableIf::value, bool>::type + friend typename enable_if::value, bool>::type operator!=(TComparand comparand, const JsonVariantComparisons &variant) { return !variant.equals(comparand); } @@ -101,16 +101,16 @@ class JsonVariantComparisons { } template - typename EnableIf::has_equals, bool>::type equals( + typename enable_if::has_equals, bool>::type equals( const TString &comparand) const { const char *value = as(); return StringTraits::equals(comparand, value); } template - typename EnableIf::value && - !StringTraits::has_equals, - bool>::type + typename enable_if::value && + !StringTraits::has_equals, + bool>::type equals(const TComparand &comparand) const { return as() == comparand; } diff --git a/src/ArduinoJson/JsonVariantImpl.hpp b/src/ArduinoJson/JsonVariantImpl.hpp index 138827cba..d7ffec086 100644 --- a/src/ArduinoJson/JsonVariantImpl.hpp +++ b/src/ArduinoJson/JsonVariantImpl.hpp @@ -8,10 +8,10 @@ #include "JsonArray.hpp" #include "JsonObject.hpp" #include "JsonVariant.hpp" -#include "Text/isFloat.hpp" -#include "Text/isInteger.hpp" -#include "Text/parseFloat.hpp" -#include "Text/parseInteger.hpp" +#include "Numbers/isFloat.hpp" +#include "Numbers/isInteger.hpp" +#include "Numbers/parseFloat.hpp" +#include "Numbers/parseInteger.hpp" #include // for strcmp diff --git a/src/ArduinoJson/JsonVariantOr.hpp b/src/ArduinoJson/JsonVariantOr.hpp index d8022fcb2..912831f7f 100644 --- a/src/ArduinoJson/JsonVariantOr.hpp +++ b/src/ArduinoJson/JsonVariantOr.hpp @@ -6,8 +6,7 @@ #include "Data/JsonVariantAs.hpp" #include "Polyfills/attributes.hpp" -#include "TypeTraits/EnableIf.hpp" -#include "TypeTraits/IsIntegral.hpp" +#include "Polyfills/type_traits.hpp" namespace ArduinoJson { namespace Internals { @@ -17,7 +16,7 @@ class JsonVariantOr { public: // Returns the default value if the JsonVariant is undefined of incompatible template - typename EnableIf::value, T>::type operator|( + typename enable_if::value, T>::type operator|( const T &defaultValue) const { if (impl()->template is()) return impl()->template as(); @@ -35,7 +34,7 @@ class JsonVariantOr { // Returns the default value if the JsonVariant is undefined of incompatible // Special case for integers: we also accept double template - typename EnableIf::value, Integer>::type operator|( + typename enable_if::value, Integer>::type operator|( const Integer &defaultValue) const { if (impl()->template is()) return impl()->template as(); diff --git a/src/ArduinoJson/JsonVariantSubscripts.hpp b/src/ArduinoJson/JsonVariantSubscripts.hpp index ec28c6862..d75ec0524 100644 --- a/src/ArduinoJson/JsonVariantSubscripts.hpp +++ b/src/ArduinoJson/JsonVariantSubscripts.hpp @@ -6,8 +6,8 @@ #include "Data/JsonVariantAs.hpp" #include "Polyfills/attributes.hpp" +#include "Polyfills/type_traits.hpp" #include "Strings/StringTraits.hpp" -#include "TypeTraits/EnableIf.hpp" namespace ArduinoJson { namespace Internals { @@ -43,8 +43,8 @@ class JsonVariantSubscripts { // TKey = const std::string&, const String& template FORCE_INLINE - typename EnableIf::has_equals, - const JsonObjectSubscript >::type + typename enable_if::has_equals, + const JsonObjectSubscript >::type operator[](const TString &key) const { return impl()->template as()[key]; } @@ -52,8 +52,8 @@ class JsonVariantSubscripts { // const JsonObjectSubscript operator[](TKey) const; // TKey = const std::string&, const String& template - FORCE_INLINE typename EnableIf::has_equals, - JsonObjectSubscript >::type + FORCE_INLINE typename enable_if::has_equals, + JsonObjectSubscript >::type operator[](const TString &key) { return impl()->template as()[key]; } @@ -61,8 +61,8 @@ class JsonVariantSubscripts { // JsonObjectSubscript operator[](TKey); // TKey = const char*, const char[N], const FlashStringHelper* template - FORCE_INLINE typename EnableIf::has_equals, - JsonObjectSubscript >::type + FORCE_INLINE typename enable_if::has_equals, + JsonObjectSubscript >::type operator[](const TString *key) { return impl()->template as()[key]; } @@ -71,8 +71,8 @@ class JsonVariantSubscripts { // TKey = const char*, const char[N], const FlashStringHelper* template FORCE_INLINE - typename EnableIf::has_equals, - const JsonObjectSubscript >::type + typename enable_if::has_equals, + const JsonObjectSubscript >::type operator[](const TString *key) const { return impl()->template as()[key]; } diff --git a/src/ArduinoJson/Memory/StaticJsonBuffer.hpp b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp index eb4fc36e2..71d6ddbc5 100644 --- a/src/ArduinoJson/Memory/StaticJsonBuffer.hpp +++ b/src/ArduinoJson/Memory/StaticJsonBuffer.hpp @@ -4,7 +4,7 @@ #pragma once -#include "../TypeTraits/Max.hpp" +#include "../Polyfills/mpl/max.hpp" #include "JsonBuffer.hpp" namespace ArduinoJson { diff --git a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp index 34dc11de4..c043eca32 100644 --- a/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp +++ b/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp @@ -7,8 +7,8 @@ #include "../DeserializationError.hpp" #include "../JsonVariant.hpp" #include "../Memory/JsonBuffer.hpp" +#include "../Polyfills/type_traits.hpp" #include "../Reading/Reader.hpp" -#include "../TypeTraits/IsConst.hpp" #include "../Writing/Writer.hpp" #include "./endianess.hpp" #include "./ieee754.hpp" @@ -181,7 +181,7 @@ class MsgPackDeserializer { } template - typename EnableIf::type readFloat( + typename enable_if::type readFloat( JsonVariant &variant) { T value; if (!readBytes(value)) return DeserializationError::IncompleteInput; @@ -191,7 +191,7 @@ class MsgPackDeserializer { } template - typename EnableIf::type readDouble( + typename enable_if::type readDouble( JsonVariant &variant) { T value; if (!readBytes(value)) return DeserializationError::IncompleteInput; @@ -201,7 +201,7 @@ class MsgPackDeserializer { } template - typename EnableIf::type readDouble( + typename enable_if::type readDouble( JsonVariant &variant) { uint8_t i[8]; // input is 8 bytes T value; // output is 4 bytes @@ -221,7 +221,8 @@ class MsgPackDeserializer { } DeserializationError readString(JsonVariant &variant, size_t n) { - typename RemoveReference::type::String str = _writer.startString(); + typename remove_reference::type::String str = + _writer.startString(); for (; n; --n) { uint8_t c; if (!readBytes(c)) return DeserializationError::IncompleteInput; diff --git a/src/ArduinoJson/MsgPack/endianess.hpp b/src/ArduinoJson/MsgPack/endianess.hpp index 26f2b9063..aa6bb8375 100644 --- a/src/ArduinoJson/MsgPack/endianess.hpp +++ b/src/ArduinoJson/MsgPack/endianess.hpp @@ -4,12 +4,11 @@ #pragma once +#include "../Polyfills/type_traits.hpp" + namespace ArduinoJson { namespace Internals { -template -struct integral_constant {}; - template inline void swap(T& a, T& b) { T t(a); diff --git a/src/ArduinoJson/Json/Serialization/FloatParts.hpp b/src/ArduinoJson/Numbers/FloatParts.hpp similarity index 95% rename from src/ArduinoJson/Json/Serialization/FloatParts.hpp rename to src/ArduinoJson/Numbers/FloatParts.hpp index 4f42a9c22..d7c342742 100644 --- a/src/ArduinoJson/Json/Serialization/FloatParts.hpp +++ b/src/ArduinoJson/Numbers/FloatParts.hpp @@ -4,9 +4,9 @@ #pragma once -#include "../../Configuration.hpp" -#include "../../Polyfills/math.hpp" -#include "../../TypeTraits/FloatTraits.hpp" +#include "../Configuration.hpp" +#include "../Polyfills/math.hpp" +#include "./FloatTraits.hpp" namespace ArduinoJson { namespace Internals { diff --git a/src/ArduinoJson/TypeTraits/FloatTraits.hpp b/src/ArduinoJson/Numbers/FloatTraits.hpp similarity index 98% rename from src/ArduinoJson/TypeTraits/FloatTraits.hpp rename to src/ArduinoJson/Numbers/FloatTraits.hpp index 5044807a6..a6ebcc12f 100644 --- a/src/ArduinoJson/TypeTraits/FloatTraits.hpp +++ b/src/ArduinoJson/Numbers/FloatTraits.hpp @@ -146,5 +146,5 @@ struct FloatTraits { return forge(0x7f800000); } }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Text/isFloat.hpp b/src/ArduinoJson/Numbers/isFloat.hpp similarity index 100% rename from src/ArduinoJson/Text/isFloat.hpp rename to src/ArduinoJson/Numbers/isFloat.hpp diff --git a/src/ArduinoJson/Text/isInteger.hpp b/src/ArduinoJson/Numbers/isInteger.hpp similarity index 100% rename from src/ArduinoJson/Text/isInteger.hpp rename to src/ArduinoJson/Numbers/isInteger.hpp diff --git a/src/ArduinoJson/Text/parseFloat.hpp b/src/ArduinoJson/Numbers/parseFloat.hpp similarity index 97% rename from src/ArduinoJson/Text/parseFloat.hpp rename to src/ArduinoJson/Numbers/parseFloat.hpp index 763ab3d83..e50f90590 100644 --- a/src/ArduinoJson/Text/parseFloat.hpp +++ b/src/ArduinoJson/Numbers/parseFloat.hpp @@ -4,9 +4,9 @@ #pragma once +#include "../Numbers/FloatTraits.hpp" #include "../Polyfills/ctype.hpp" #include "../Polyfills/math.hpp" -#include "../TypeTraits/FloatTraits.hpp" namespace ArduinoJson { namespace Internals { diff --git a/src/ArduinoJson/Text/parseInteger.hpp b/src/ArduinoJson/Numbers/parseInteger.hpp similarity index 100% rename from src/ArduinoJson/Text/parseInteger.hpp rename to src/ArduinoJson/Numbers/parseInteger.hpp diff --git a/src/ArduinoJson/Polyfills/math.hpp b/src/ArduinoJson/Polyfills/math.hpp index 48773edd2..32417c0cf 100644 --- a/src/ArduinoJson/Polyfills/math.hpp +++ b/src/ArduinoJson/Polyfills/math.hpp @@ -7,13 +7,13 @@ namespace ArduinoJson { namespace Internals { template -bool isNaN(T x) { +bool isnan(T x) { return x != x; } template -bool isInfinity(T x) { +bool isinf(T x) { return x != 0.0 && x * 2 == x; } -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/Max.hpp b/src/ArduinoJson/Polyfills/mpl/max.hpp similarity index 100% rename from src/ArduinoJson/TypeTraits/Max.hpp rename to src/ArduinoJson/Polyfills/mpl/max.hpp diff --git a/src/ArduinoJson/Polyfills/type_traits.hpp b/src/ArduinoJson/Polyfills/type_traits.hpp new file mode 100644 index 000000000..fa5b9e50a --- /dev/null +++ b/src/ArduinoJson/Polyfills/type_traits.hpp @@ -0,0 +1,18 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "type_traits/enable_if.hpp" +#include "type_traits/integral_constant.hpp" +#include "type_traits/is_array.hpp" +#include "type_traits/is_base_of.hpp" +#include "type_traits/is_const.hpp" +#include "type_traits/is_floating_point.hpp" +#include "type_traits/is_integral.hpp" +#include "type_traits/is_same.hpp" +#include "type_traits/is_signed.hpp" +#include "type_traits/is_unsigned.hpp" +#include "type_traits/remove_const.hpp" +#include "type_traits/remove_reference.hpp" diff --git a/src/ArduinoJson/TypeTraits/EnableIf.hpp b/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp similarity index 74% rename from src/ArduinoJson/TypeTraits/EnableIf.hpp rename to src/ArduinoJson/Polyfills/type_traits/enable_if.hpp index 83fc5e07f..70dd92e61 100644 --- a/src/ArduinoJson/TypeTraits/EnableIf.hpp +++ b/src/ArduinoJson/Polyfills/type_traits/enable_if.hpp @@ -9,11 +9,11 @@ namespace Internals { // A meta-function that return the type T if Condition is true. template -struct EnableIf {}; +struct enable_if {}; template -struct EnableIf { +struct enable_if { typedef T type; }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp b/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp new file mode 100644 index 000000000..7ce931c3e --- /dev/null +++ b/src/ArduinoJson/Polyfills/type_traits/integral_constant.hpp @@ -0,0 +1,19 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +template +struct integral_constant { + static const T value = v; +}; + +typedef integral_constant true_type; +typedef integral_constant false_type; + +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/type_traits/is_array.hpp b/src/ArduinoJson/Polyfills/type_traits/is_array.hpp new file mode 100644 index 000000000..17075d4ac --- /dev/null +++ b/src/ArduinoJson/Polyfills/type_traits/is_array.hpp @@ -0,0 +1,19 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +namespace ArduinoJson { +namespace Internals { + +template +struct is_array : false_type {}; + +template +struct is_array : true_type {}; + +template +struct is_array : true_type {}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/IsBaseOf.hpp b/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp similarity index 88% rename from src/ArduinoJson/TypeTraits/IsBaseOf.hpp rename to src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp index bf24e965e..be6ddeac3 100644 --- a/src/ArduinoJson/TypeTraits/IsBaseOf.hpp +++ b/src/ArduinoJson/Polyfills/type_traits/is_base_of.hpp @@ -10,7 +10,7 @@ namespace Internals { // A meta-function that returns true if Derived inherits from TBase is an // integral type. template -class IsBaseOf { +class is_base_of { protected: // <- to avoid GCC's "all member functions in class are private" typedef char Yes[1]; typedef char No[2]; @@ -23,5 +23,5 @@ class IsBaseOf { value = sizeof(probe(reinterpret_cast(0))) == sizeof(Yes) }; }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/IsConst.hpp b/src/ArduinoJson/Polyfills/type_traits/is_const.hpp similarity index 61% rename from src/ArduinoJson/TypeTraits/IsConst.hpp rename to src/ArduinoJson/Polyfills/type_traits/is_const.hpp index 512ee5ca0..0a2dfda98 100644 --- a/src/ArduinoJson/TypeTraits/IsConst.hpp +++ b/src/ArduinoJson/Polyfills/type_traits/is_const.hpp @@ -4,18 +4,16 @@ #pragma once +#include "integral_constant.hpp" + namespace ArduinoJson { namespace Internals { // A meta-function that return the type T without the const modifier template -struct IsConst { - static const bool value = false; -}; +struct is_const : false_type {}; template -struct IsConst { - static const bool value = true; -}; -} -} +struct is_const : true_type {}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp b/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp new file mode 100644 index 000000000..24e74ab77 --- /dev/null +++ b/src/ArduinoJson/Polyfills/type_traits/is_floating_point.hpp @@ -0,0 +1,21 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "integral_constant.hpp" + +namespace ArduinoJson { +namespace Internals { + +template +struct is_floating_point : false_type {}; + +template <> +struct is_floating_point : true_type {}; + +template <> +struct is_floating_point : true_type {}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp b/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp new file mode 100644 index 000000000..e97a09ccd --- /dev/null +++ b/src/ArduinoJson/Polyfills/type_traits/is_integral.hpp @@ -0,0 +1,35 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "is_same.hpp" + +namespace ArduinoJson { +namespace Internals { + +// A meta-function that returns true if T is an integral type. +template +struct is_integral { + static const bool value = + is_same::value || is_same::value || + is_same::value || is_same::value || + is_same::value || is_same::value || + is_same::value || is_same::value || +#if ARDUINOJSON_USE_LONG_LONG + is_same::value || + is_same::value || +#endif +#if ARDUINOJSON_USE_INT64 + is_same::value || + is_same::value || +#endif + is_same::value; + // CAUTION: differs from std::is_integral as it doesn't include bool +}; + +template +struct is_integral : is_integral {}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/IsSame.hpp b/src/ArduinoJson/Polyfills/type_traits/is_same.hpp similarity index 63% rename from src/ArduinoJson/TypeTraits/IsSame.hpp rename to src/ArduinoJson/Polyfills/type_traits/is_same.hpp index 06567c93b..920f5b541 100644 --- a/src/ArduinoJson/TypeTraits/IsSame.hpp +++ b/src/ArduinoJson/Polyfills/type_traits/is_same.hpp @@ -4,18 +4,16 @@ #pragma once +#include "integral_constant.hpp" + namespace ArduinoJson { namespace Internals { // A meta-function that returns true if types T and U are the same. template -struct IsSame { - static const bool value = false; -}; +struct is_same : false_type {}; template -struct IsSame { - static const bool value = true; -}; -} -} +struct is_same : true_type {}; +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp b/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp new file mode 100644 index 000000000..b145c5ea9 --- /dev/null +++ b/src/ArduinoJson/Polyfills/type_traits/is_signed.hpp @@ -0,0 +1,44 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "integral_constant.hpp" +namespace ArduinoJson { +namespace Internals { + +template +struct is_signed : false_type {}; + +template <> +struct is_signed : true_type {}; + +template <> +struct is_signed : true_type {}; + +template <> +struct is_signed : true_type {}; + +template <> +struct is_signed : true_type {}; + +template <> +struct is_signed : true_type {}; + +template <> +struct is_signed : true_type {}; + +template <> +struct is_signed : true_type {}; + +#if ARDUINOJSON_USE_LONG_LONG +template <> +struct is_signed : true_type {}; +#endif +#if ARDUINOJSON_USE_INT64 +template <> +struct is_signed : true_type {}; +#endif +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp b/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp new file mode 100644 index 000000000..4de418d0c --- /dev/null +++ b/src/ArduinoJson/Polyfills/type_traits/is_unsigned.hpp @@ -0,0 +1,38 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "integral_constant.hpp" +namespace ArduinoJson { +namespace Internals { + +template +struct is_unsigned : false_type {}; + +template <> +struct is_unsigned : true_type {}; + +template <> +struct is_unsigned : true_type {}; + +template <> +struct is_unsigned : true_type {}; + +template <> +struct is_unsigned : true_type {}; + +template <> +struct is_unsigned : true_type {}; + +#if ARDUINOJSON_USE_LONG_LONG +template <> +struct is_unsigned : true_type {}; +#endif +#if ARDUINOJSON_USE_INT64 +template <> +struct is_unsigned : true_type {}; +#endif +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/RemoveConst.hpp b/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp similarity index 73% rename from src/ArduinoJson/TypeTraits/RemoveConst.hpp rename to src/ArduinoJson/Polyfills/type_traits/remove_const.hpp index 39d4cb5a5..9cb7421b5 100644 --- a/src/ArduinoJson/TypeTraits/RemoveConst.hpp +++ b/src/ArduinoJson/Polyfills/type_traits/remove_const.hpp @@ -9,12 +9,12 @@ namespace Internals { // A meta-function that return the type T without the const modifier template -struct RemoveConst { +struct remove_const { typedef T type; }; template -struct RemoveConst { +struct remove_const { typedef T type; }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/TypeTraits/RemoveReference.hpp b/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp similarity index 73% rename from src/ArduinoJson/TypeTraits/RemoveReference.hpp rename to src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp index 395a12889..f0103dd22 100644 --- a/src/ArduinoJson/TypeTraits/RemoveReference.hpp +++ b/src/ArduinoJson/Polyfills/type_traits/remove_reference.hpp @@ -9,12 +9,12 @@ namespace Internals { // A meta-function that return the type T without the reference modifier. template -struct RemoveReference { +struct remove_reference { typedef T type; }; template -struct RemoveReference { +struct remove_reference { typedef T type; }; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/StaticJsonDocument.hpp b/src/ArduinoJson/StaticJsonDocument.hpp index b111485cb..beab5ce40 100644 --- a/src/ArduinoJson/StaticJsonDocument.hpp +++ b/src/ArduinoJson/StaticJsonDocument.hpp @@ -35,8 +35,8 @@ class StaticJsonDocument { // JsonObject& to() template - typename Internals::EnableIf::value, - JsonObject&>::type + typename Internals::enable_if::value, + JsonObject&>::type to() { clear(); JsonObject* object = new (&_buffer) JsonObject(&_buffer); @@ -47,8 +47,8 @@ class StaticJsonDocument { // JsonArray& to() template - typename Internals::EnableIf::value, - JsonArray&>::type + typename Internals::enable_if::value, + JsonArray&>::type to() { clear(); JsonArray* array = new (&_buffer) JsonArray(&_buffer); @@ -59,8 +59,8 @@ class StaticJsonDocument { // JsonVariant to() template - typename Internals::EnableIf::value, - T&>::type + typename Internals::enable_if::value, + T&>::type to() { clear(); return _root; diff --git a/src/ArduinoJson/Strings/CharPointer.hpp b/src/ArduinoJson/Strings/CharPointer.hpp index 2b804ab3b..07a08284c 100644 --- a/src/ArduinoJson/Strings/CharPointer.hpp +++ b/src/ArduinoJson/Strings/CharPointer.hpp @@ -30,13 +30,13 @@ struct CharPointerTraits { static const bool has_append = false; static const bool has_equals = true; - static const bool should_duplicate = !IsConst::value; + static const bool should_duplicate = !is_const::value; }; // char*, unsigned char*, signed char* // const char*, const unsigned char*, const signed char* template -struct StringTraits::value>::type> +struct StringTraits::type> : CharPointerTraits {}; -} -} +} // namespace Internals +} // namespace ArduinoJson diff --git a/src/ArduinoJson/Strings/StringTraits.hpp b/src/ArduinoJson/Strings/StringTraits.hpp index 5201c1723..8b62e9782 100644 --- a/src/ArduinoJson/Strings/StringTraits.hpp +++ b/src/ArduinoJson/Strings/StringTraits.hpp @@ -6,11 +6,7 @@ #include #include "../Configuration.hpp" -#include "../TypeTraits/EnableIf.hpp" -#include "../TypeTraits/IsBaseOf.hpp" -#include "../TypeTraits/IsChar.hpp" -#include "../TypeTraits/IsConst.hpp" -#include "../TypeTraits/RemoveReference.hpp" +#include "../Polyfills/type_traits.hpp" namespace ArduinoJson { namespace Internals { @@ -26,8 +22,8 @@ struct StringTraits : StringTraits {}; template struct StringTraits : StringTraits {}; -} -} +} // namespace Internals +} // namespace ArduinoJson #include "CharPointer.hpp" #include "FlashString.hpp" diff --git a/src/ArduinoJson/TypeTraits/IsArray.hpp b/src/ArduinoJson/TypeTraits/IsArray.hpp deleted file mode 100644 index 259923115..000000000 --- a/src/ArduinoJson/TypeTraits/IsArray.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -namespace ArduinoJson { -namespace Internals { - -// A meta-function that return the type T without the const modifier -template -struct IsArray { - static const bool value = false; -}; -template -struct IsArray { - static const bool value = true; -}; -template -struct IsArray { - static const bool value = true; -}; -} -} diff --git a/src/ArduinoJson/TypeTraits/IsChar.hpp b/src/ArduinoJson/TypeTraits/IsChar.hpp deleted file mode 100644 index d97cec213..000000000 --- a/src/ArduinoJson/TypeTraits/IsChar.hpp +++ /dev/null @@ -1,23 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "IsSame.hpp" - -namespace ArduinoJson { -namespace Internals { - -// A meta-function that returns true if T is a charater -template -struct IsChar { - static const bool value = IsSame::value || - IsSame::value || - IsSame::value; -}; - -template -struct IsChar : IsChar {}; -} -} diff --git a/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp b/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp deleted file mode 100644 index e41a6824c..000000000 --- a/src/ArduinoJson/TypeTraits/IsFloatingPoint.hpp +++ /dev/null @@ -1,18 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "IsSame.hpp" - -namespace ArduinoJson { -namespace Internals { - -// A meta-function that returns true if T is a floating point type -template -struct IsFloatingPoint { - static const bool value = IsSame::value || IsSame::value; -}; -} -} diff --git a/src/ArduinoJson/TypeTraits/IsIntegral.hpp b/src/ArduinoJson/TypeTraits/IsIntegral.hpp deleted file mode 100644 index 17ae5f284..000000000 --- a/src/ArduinoJson/TypeTraits/IsIntegral.hpp +++ /dev/null @@ -1,26 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "IsSame.hpp" -#include "IsSignedIntegral.hpp" -#include "IsUnsignedIntegral.hpp" - -namespace ArduinoJson { -namespace Internals { - -// A meta-function that returns true if T is an integral type. -template -struct IsIntegral { - static const bool value = IsSignedIntegral::value || - IsUnsignedIntegral::value || - IsSame::value; - // CAUTION: differs from std::is_integral as it doesn't include bool -}; - -template -struct IsIntegral : IsIntegral {}; -} -} diff --git a/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp b/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp deleted file mode 100644 index 7334eb9c7..000000000 --- a/src/ArduinoJson/TypeTraits/IsSignedIntegral.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "../Configuration.hpp" -#include "IsSame.hpp" - -namespace ArduinoJson { -namespace Internals { - -// A meta-function that returns true if T is an integral type. -template -struct IsSignedIntegral { - static const bool value = - IsSame::value || IsSame::value || - IsSame::value || IsSame::value || -#if ARDUINOJSON_USE_LONG_LONG - IsSame::value || -#endif -#if ARDUINOJSON_USE_INT64 - IsSame::value || -#endif - false; -}; -} -} diff --git a/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp b/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp deleted file mode 100644 index 938423f5c..000000000 --- a/src/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp +++ /dev/null @@ -1,28 +0,0 @@ -// ArduinoJson - arduinojson.org -// Copyright Benoit Blanchon 2014-2018 -// MIT License - -#pragma once - -#include "../Configuration.hpp" -#include "IsSame.hpp" - -namespace ArduinoJson { -namespace Internals { - -// A meta-function that returns true if T is an integral type. -template -struct IsUnsignedIntegral { - static const bool value = - IsSame::value || IsSame::value || - IsSame::value || IsSame::value || -#if ARDUINOJSON_USE_LONG_LONG - IsSame::value || -#endif -#if ARDUINOJSON_USE_INT64 - IsSame::value || -#endif - false; -}; -} -} diff --git a/src/ArduinoJson/Writing/Writer.hpp b/src/ArduinoJson/Writing/Writer.hpp index 7a5292793..66c57a533 100644 --- a/src/ArduinoJson/Writing/Writer.hpp +++ b/src/ArduinoJson/Writing/Writer.hpp @@ -21,7 +21,7 @@ struct Writer { template struct Writer::value>::type> { + typename enable_if::value>::type> { typedef StringWriter type; static type create(TJsonBuffer&, TChar* input) { diff --git a/src/ArduinoJson/deserializeJson.hpp b/src/ArduinoJson/deserializeJson.hpp index b0eafc8bf..d4e11834a 100644 --- a/src/ArduinoJson/deserializeJson.hpp +++ b/src/ArduinoJson/deserializeJson.hpp @@ -4,7 +4,7 @@ #pragma once -#include "Json/Deserialization/JsonDeserializer.hpp" +#include "Json/JsonDeserializer.hpp" #include "Reading/Reader.hpp" #include "Writing/Writer.hpp" @@ -13,8 +13,8 @@ namespace ArduinoJson { // TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& template -typename Internals::EnableIf::value, - DeserializationError>::type +typename Internals::enable_if::value, + DeserializationError>::type deserializeJson(TDocument &doc, const TString &input) { using namespace Internals; return makeJsonDeserializer(&doc.buffer(), makeReader(input), diff --git a/src/ArduinoJson/deserializeMsgPack.hpp b/src/ArduinoJson/deserializeMsgPack.hpp index 9256a4112..7c38cdc5b 100644 --- a/src/ArduinoJson/deserializeMsgPack.hpp +++ b/src/ArduinoJson/deserializeMsgPack.hpp @@ -13,8 +13,8 @@ namespace ArduinoJson { // TDocument = DynamicJsonDocument, StaticJsonDocument // TString = const std::string&, const String& template -typename Internals::EnableIf::value, - DeserializationError>::type +typename Internals::enable_if::value, + DeserializationError>::type deserializeMsgPack(TDocument &doc, const TString &input) { using namespace Internals; return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), diff --git a/test/JsonWriter/writeFloat.cpp b/test/JsonWriter/writeFloat.cpp index aa06552b1..73bc1912a 100644 --- a/test/JsonWriter/writeFloat.cpp +++ b/test/JsonWriter/writeFloat.cpp @@ -6,7 +6,7 @@ #include #include -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/JsonWriter/writeString.cpp b/test/JsonWriter/writeString.cpp index eded06e32..104bc104a 100644 --- a/test/JsonWriter/writeString.cpp +++ b/test/JsonWriter/writeString.cpp @@ -4,7 +4,7 @@ #include -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Misc/FloatParts.cpp b/test/Misc/FloatParts.cpp index d9cf18a1f..f3e10a743 100644 --- a/test/Misc/FloatParts.cpp +++ b/test/Misc/FloatParts.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Misc/TypeTraits.cpp b/test/Misc/TypeTraits.cpp index 8d730b219..41cdebbc2 100644 --- a/test/Misc/TypeTraits.cpp +++ b/test/Misc/TypeTraits.cpp @@ -7,21 +7,21 @@ using namespace ArduinoJson::Internals; -TEST_CASE("TypeTraits") { - SECTION("IsBaseOf") { +TEST_CASE("Polyfills/type_traits") { + SECTION("is_base_of") { REQUIRE_FALSE( - static_cast(IsBaseOf::value)); + static_cast(is_base_of::value)); REQUIRE( - static_cast(IsBaseOf::value)); + static_cast(is_base_of::value)); REQUIRE(static_cast( - IsBaseOf >, - JsonObjectSubscript >::value)); + is_base_of >, + JsonObjectSubscript >::value)); } - SECTION("IsArray") { - REQUIRE_FALSE((IsArray::value)); - REQUIRE((IsArray::value)); - REQUIRE((IsArray::value)); + SECTION("is_array") { + REQUIRE_FALSE((is_array::value)); + REQUIRE((is_array::value)); + REQUIRE((is_array::value)); } SECTION("IsVariant") { @@ -30,8 +30,30 @@ TEST_CASE("TypeTraits") { REQUIRE(static_cast(IsVariant::value)); } - SECTION("IsConst") { - REQUIRE_FALSE((IsConst::value)); - REQUIRE((IsConst::value)); + SECTION("is_const") { + CHECK(is_const::value == false); + CHECK(is_const::value == true); + } + + SECTION("is_signed") { + CHECK(is_signed::value == true); + CHECK(is_signed::value == true); + CHECK(is_signed::value == true); + CHECK(is_signed::value == true); + CHECK(is_signed::value == true); + CHECK(is_signed::value == true); + CHECK(is_signed::value == true); + CHECK(is_signed::value == false); + } + + SECTION("is_unsigned") { + CHECK(is_unsigned::value == true); + CHECK(is_unsigned::value == true); + CHECK(is_unsigned::value == true); + CHECK(is_unsigned::value == true); + CHECK(is_unsigned::value == true); + CHECK(is_unsigned::value == false); + CHECK(is_unsigned::value == false); + CHECK(is_unsigned::value == false); } } diff --git a/test/Polyfills/isFloat.cpp b/test/Polyfills/isFloat.cpp index f4fbe16b8..3d77ac493 100644 --- a/test/Polyfills/isFloat.cpp +++ b/test/Polyfills/isFloat.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Polyfills/isInteger.cpp b/test/Polyfills/isInteger.cpp index 8cc74dd11..a2f11fc9f 100644 --- a/test/Polyfills/isInteger.cpp +++ b/test/Polyfills/isInteger.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Polyfills/parseFloat.cpp b/test/Polyfills/parseFloat.cpp index bd481ea27..18cb0cfbf 100644 --- a/test/Polyfills/parseFloat.cpp +++ b/test/Polyfills/parseFloat.cpp @@ -2,7 +2,7 @@ // Copyright Benoit Blanchon 2014-2018 // MIT License -#include +#include #include using namespace ArduinoJson::Internals; diff --git a/test/Polyfills/parseInteger.cpp b/test/Polyfills/parseInteger.cpp index afac3bf51..786834b1f 100644 --- a/test/Polyfills/parseInteger.cpp +++ b/test/Polyfills/parseInteger.cpp @@ -3,7 +3,7 @@ // MIT License #include -#include +#include #include using namespace ArduinoJson::Internals; From fc2e3a4ab37d2c1ad833dfe77e3acc50d6c9d374 Mon Sep 17 00:00:00 2001 From: Benoit Blanchon Date: Tue, 29 May 2018 08:31:17 +0200 Subject: [PATCH 0031/1079] Added `serializeMsgPack()` and `measureMsgPack()` (closes #358) --- .gitignore | 1 + CHANGELOG.md | 2 +- src/ArduinoJson.hpp | 8 +- .../ArduinoStreamReader.hpp | 0 .../CharPointerReader.hpp | 0 .../DeserializationError.hpp | 0 .../FlashStringReader.hpp | 0 .../IteratorReader.hpp | 0 .../StdStreamReader.hpp | 0 .../Deserialization/deserialize.hpp | 82 ++++++++ src/ArduinoJson/DynamicJsonDocument.hpp | 2 +- src/ArduinoJson/Json/JsonDeserializer.hpp | 49 +++-- src/ArduinoJson/Json/JsonSerializer.hpp | 197 ++++++------------ src/ArduinoJson/Json/PrettyJsonSerializer.hpp | 57 +++++ src/ArduinoJson/JsonArray.hpp | 2 +- src/ArduinoJson/JsonArraySubscript.hpp | 2 +- src/ArduinoJson/JsonObject.hpp | 2 +- src/ArduinoJson/JsonObjectSubscript.hpp | 2 +- src/ArduinoJson/JsonVariant.hpp | 4 +- .../MsgPack/MsgPackDeserializer.hpp | 48 +++-- src/ArduinoJson/MsgPack/MsgPackSerializer.hpp | 191 +++++++++++++++++ src/ArduinoJson/MsgPack/endianess.hpp | 8 +- src/ArduinoJson/Polyfills/utility.hpp | 16 ++ src/ArduinoJson/Reading/Reader.hpp | 11 - .../{Print => Serialization}/DummyPrint.hpp | 1 - .../DynamicStringBuilder.hpp | 0 .../StaticStringBuilder.hpp | 4 +- .../StreamPrintAdapter.hpp | 0 src/ArduinoJson/Serialization/measure.hpp | 21 ++ src/ArduinoJson/Serialization/serialize.hpp | 55 +++++ src/ArduinoJson/StaticJsonDocument.hpp | 2 +- .../StringCopier.hpp} | 6 +- .../StringMover.hpp} | 8 +- .../StringStorage/StringStorage.hpp | 44 ++++ src/ArduinoJson/Writing/Writer.hpp | 44 ---- src/ArduinoJson/deserializeJson.hpp | 58 ------ src/ArduinoJson/deserializeMsgPack.hpp | 63 ------ test/CMakeLists.txt | 3 +- .../JsonDeserializer/DeserializationError.cpp | 8 +- test/JsonSerializer/std_string.cpp | 8 +- test/JsonWriter/writeFloat.cpp | 2 +- test/JsonWriter/writeString.cpp | 2 +- .../CMakeLists.txt | 6 +- .../deserializeArray.cpp | 2 +- .../deserializeObject.cpp | 0 .../deserializeStaticVariant.cpp | 0 .../deserializeVariant.cpp | 2 +- .../doubleToFloat.cpp | 0 .../incompleteInput.cpp | 0 .../nestingLimit.cpp | 0 .../notSupported.cpp | 0 .../std_istream.cpp | 0 .../std_string.cpp | 0 test/MsgPackSerializer/CMakeLists.txt | 14 ++ test/MsgPackSerializer/destination_types.cpp | 47 +++++ test/MsgPackSerializer/measure.cpp | 14 ++ test/MsgPackSerializer/serializeArray.cpp | 60 ++++++ test/MsgPackSerializer/serializeObject.cpp | 73 +++++++ test/MsgPackSerializer/serializeVariant.cpp | 129 ++++++++++++ 59 files changed, 972 insertions(+), 388 deletions(-) rename src/ArduinoJson/{Reading => Deserialization}/ArduinoStreamReader.hpp (100%) rename src/ArduinoJson/{Reading => Deserialization}/CharPointerReader.hpp (100%) rename src/ArduinoJson/{ => Deserialization}/DeserializationError.hpp (100%) rename src/ArduinoJson/{Reading => Deserialization}/FlashStringReader.hpp (100%) rename src/ArduinoJson/{Reading => Deserialization}/IteratorReader.hpp (100%) rename src/ArduinoJson/{Reading => Deserialization}/StdStreamReader.hpp (100%) create mode 100644 src/ArduinoJson/Deserialization/deserialize.hpp create mode 100644 src/ArduinoJson/Json/PrettyJsonSerializer.hpp create mode 100644 src/ArduinoJson/MsgPack/MsgPackSerializer.hpp create mode 100644 src/ArduinoJson/Polyfills/utility.hpp delete mode 100644 src/ArduinoJson/Reading/Reader.hpp rename src/ArduinoJson/{Print => Serialization}/DummyPrint.hpp (86%) rename src/ArduinoJson/{Print => Serialization}/DynamicStringBuilder.hpp (100%) rename src/ArduinoJson/{Print => Serialization}/StaticStringBuilder.hpp (92%) rename src/ArduinoJson/{Print => Serialization}/StreamPrintAdapter.hpp (100%) create mode 100644 src/ArduinoJson/Serialization/measure.hpp create mode 100644 src/ArduinoJson/Serialization/serialize.hpp rename src/ArduinoJson/{Writing/JsonBufferWriter.hpp => StringStorage/StringCopier.hpp} (78%) rename src/ArduinoJson/{Writing/StringWriter.hpp => StringStorage/StringMover.hpp} (83%) create mode 100644 src/ArduinoJson/StringStorage/StringStorage.hpp delete mode 100644 src/ArduinoJson/Writing/Writer.hpp delete mode 100644 src/ArduinoJson/deserializeJson.hpp delete mode 100644 src/ArduinoJson/deserializeMsgPack.hpp rename test/{MsgPack => MsgPackDeserializer}/CMakeLists.txt (66%) rename test/{MsgPack => MsgPackDeserializer}/deserializeArray.cpp (97%) rename test/{MsgPack => MsgPackDeserializer}/deserializeObject.cpp (100%) rename test/{MsgPack => MsgPackDeserializer}/deserializeStaticVariant.cpp (100%) rename test/{MsgPack => MsgPackDeserializer}/deserializeVariant.cpp (98%) rename test/{MsgPack => MsgPackDeserializer}/doubleToFloat.cpp (100%) rename test/{MsgPack => MsgPackDeserializer}/incompleteInput.cpp (100%) rename test/{MsgPack => MsgPackDeserializer}/nestingLimit.cpp (100%) rename test/{MsgPack => MsgPackDeserializer}/notSupported.cpp (100%) rename test/{MsgPack => MsgPackDeserializer}/std_istream.cpp (100%) rename test/{MsgPack => MsgPackDeserializer}/std_string.cpp (100%) create mode 100644 test/MsgPackSerializer/CMakeLists.txt create mode 100644 test/MsgPackSerializer/destination_types.cpp create mode 100644 test/MsgPackSerializer/measure.cpp create mode 100644 test/MsgPackSerializer/serializeArray.cpp create mode 100644 test/MsgPackSerializer/serializeObject.cpp create mode 100644 test/MsgPackSerializer/serializeVariant.cpp diff --git a/.gitignore b/.gitignore index 567dc13be..1071ea6b1 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ /fuzzing/*_fuzzer /fuzzing/*_fuzzer.options /fuzzing/*_fuzzer_seed_corpus.zip +.vs/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b53dee9..817a380a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ HEAD * Added `deserializeJson()` * Added `serializeJson()` and `serializeJsonPretty()` * Added `measureJson()` and `measureJsonPretty()` -* Added `deserializeMsgPack()` (issue #358) +* Added `serializeMsgPack()`, `deserializeMsgPack()` and `measureMsgPack()` (issue #358) * Added example `MsgPackParser.ino` (issue #358) * Added support for non zero-terminated strings (issue #704) * Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` diff --git a/src/ArduinoJson.hpp b/src/ArduinoJson.hpp index 8b7e35945..bbe94a3cb 100644 --- a/src/ArduinoJson.hpp +++ b/src/ArduinoJson.hpp @@ -5,11 +5,13 @@ #pragma once #include "ArduinoJson/DynamicJsonDocument.hpp" +#include "ArduinoJson/Json/JsonDeserializer.hpp" +#include "ArduinoJson/Json/JsonSerializer.hpp" +#include "ArduinoJson/Json/PrettyJsonSerializer.hpp" +#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" +#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp" #include "ArduinoJson/StaticJsonDocument.hpp" -#include "ArduinoJson/deserializeJson.hpp" -#include "ArduinoJson/deserializeMsgPack.hpp" -#include "ArduinoJson/Json/JsonSerializer.hpp" #include "ArduinoJson/JsonArrayImpl.hpp" #include "ArduinoJson/JsonObjectImpl.hpp" #include "ArduinoJson/JsonVariantImpl.hpp" diff --git a/src/ArduinoJson/Reading/ArduinoStreamReader.hpp b/src/ArduinoJson/Deserialization/ArduinoStreamReader.hpp similarity index 100% rename from src/ArduinoJson/Reading/ArduinoStreamReader.hpp rename to src/ArduinoJson/Deserialization/ArduinoStreamReader.hpp diff --git a/src/ArduinoJson/Reading/CharPointerReader.hpp b/src/ArduinoJson/Deserialization/CharPointerReader.hpp similarity index 100% rename from src/ArduinoJson/Reading/CharPointerReader.hpp rename to src/ArduinoJson/Deserialization/CharPointerReader.hpp diff --git a/src/ArduinoJson/DeserializationError.hpp b/src/ArduinoJson/Deserialization/DeserializationError.hpp similarity index 100% rename from src/ArduinoJson/DeserializationError.hpp rename to src/ArduinoJson/Deserialization/DeserializationError.hpp diff --git a/src/ArduinoJson/Reading/FlashStringReader.hpp b/src/ArduinoJson/Deserialization/FlashStringReader.hpp similarity index 100% rename from src/ArduinoJson/Reading/FlashStringReader.hpp rename to src/ArduinoJson/Deserialization/FlashStringReader.hpp diff --git a/src/ArduinoJson/Reading/IteratorReader.hpp b/src/ArduinoJson/Deserialization/IteratorReader.hpp similarity index 100% rename from src/ArduinoJson/Reading/IteratorReader.hpp rename to src/ArduinoJson/Deserialization/IteratorReader.hpp diff --git a/src/ArduinoJson/Reading/StdStreamReader.hpp b/src/ArduinoJson/Deserialization/StdStreamReader.hpp similarity index 100% rename from src/ArduinoJson/Reading/StdStreamReader.hpp rename to src/ArduinoJson/Deserialization/StdStreamReader.hpp diff --git a/src/ArduinoJson/Deserialization/deserialize.hpp b/src/ArduinoJson/Deserialization/deserialize.hpp new file mode 100644 index 000000000..25abe9de6 --- /dev/null +++ b/src/ArduinoJson/Deserialization/deserialize.hpp @@ -0,0 +1,82 @@ +// ArduinoJson - arduinojson.org +// Copyright Benoit Blanchon 2014-2018 +// MIT License + +#pragma once + +#include "../StringStorage/StringStorage.hpp" +#include "./ArduinoStreamReader.hpp" +#include "./CharPointerReader.hpp" +#include "./DeserializationError.hpp" +#include "./FlashStringReader.hpp" +#include "./IteratorReader.hpp" +#include "./StdStreamReader.hpp" + +namespace ArduinoJson { +namespace Internals { + +template