Compare commits

..

11 Commits

46 changed files with 503 additions and 180 deletions

View File

@ -1,6 +1,15 @@
ArduinoJson: change log
=======================
v6.15.1 (2020-04-08)
-------
* Fixed "maybe-uninitialized" warning (issue #1217)
* Fixed "statement is unreachable" warning on IAR (issue #1233)
* Fixed "pointless integer comparison" warning on IAR (issue #1233)
* Added CMake "install" target (issue #1209)
* Disabled alignment on AVR (issue #1231)
v6.15.0 (2020-03-22)
-------
@ -32,7 +41,7 @@ v6.15.0 (2020-03-22)
>
> DynamicJsonDocument doc2 = doc1;
> Serial.print(doc2.capacity()); // 8 with ArduinoJson 6.14
// 64 with ArduinoJson 6.15
> // 64 with ArduinoJson 6.15
> ```
>
> I made this change to get consistent results between copy-constructor and move-constructor, and whether RVO applies or not.

View File

@ -5,17 +5,40 @@
cmake_minimum_required(VERSION 3.0)
project(ArduinoJson)
set(CMAKE_SKIP_INSTALL_ALL_DEPENDENCY true)
enable_testing()
add_definitions(-DARDUINOJSON_DEBUG=1)
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
add_compile_options(-g -O0)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.8)
add_compile_options(-g -Og)
else()
add_compile_options(-g -O0)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0)
add_compile_options(-g -Og)
else()
add_compile_options(-g -O0)
endif()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 9.0)
add_compile_options(-g -Og)
else()
add_compile_options(-g -O0)
endif()
endif()
if(${COVERAGE})
set(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage")
endif()
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)
add_subdirectory(src)
add_subdirectory(extras/tests)
add_subdirectory(extras/fuzzing)

View File

@ -2,7 +2,7 @@
---
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.15.0)](https://www.ardu-badge.com/ArduinoJson/6.15.0)
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.15.1)](https://www.ardu-badge.com/ArduinoJson/6.15.1)
[![Build Status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
[![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=6.x)](https://travis-ci.org/bblanchon/ArduinoJson)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arduinojson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
@ -13,29 +13,30 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
## Features
* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/)
* [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/)
* [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/)
* [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/)
* Optionally filters the input to keep only desired values
* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
* [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/?utm_source=github&utm_medium=readme)
* [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
* [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/?utm_source=github&utm_medium=readme)
* [Optionally filters the input to keep only desired values](https://arduinojson.org/v6/api/json/deserializejson/#filtering?utm_source=github&utm_medium=readme)
* Supports single quotes as a string delimiter
* Compatible with NDJSON and JSON Lines
* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/)
* [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/)
* [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/)
* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/)
* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/)
* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
* [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
* [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/?utm_source=github&utm_medium=readme)
* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/?utm_source=github&utm_medium=readme)
* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/?utm_source=github&utm_medium=readme)
* Efficient
* [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/)
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/)
* [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/?utm_source=github&utm_medium=readme)
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/?utm_source=github&utm_medium=readme)
* Versatile
* [Supports custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/)
* Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/)
* Supports Arduino's `Stream` and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/)
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/)
* [Supports custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
* Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme)
* Supports Arduino's `Stream` and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/#custom-writer?utm_source=github&utm_medium=readme)
* Portable
* Usable on any C++ project (not limited to Arduino)
* Compatible with C++98
@ -66,8 +67,9 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
* [Thread-safe](https://en.wikipedia.org/wiki/Thread_safety)
* Self-contained (no external dependency)
* `const` friendly
* `for` friendly
* [`for` friendly](https://arduinojson.org/v6/api/jsonobject/begin_end/?utm_source=github&utm_medium=readme)
* [TMP friendly](https://en.wikipedia.org/wiki/Template_metaprogramming)
* Handles [integer overflows](https://arduinojson.org/v6/api/jsonvariant/as/#integer-overflows?utm_source=github&utm_medium=readme)
* Well tested
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
* Continuously tested on
@ -76,11 +78,11 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
* [Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7, 8](https://travis-ci.org/bblanchon/ArduinoJson)
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
* Well documented
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/)
* [Examples](https://arduinojson.org/v6/example/)
* [How-tos](https://arduinojson.org/v6/example/)
* [FAQ](https://arduinojson.org/v6/faq/)
* [Book](https://arduinojson.org/book/)
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/?utm_source=github&utm_medium=readme)
* [Examples](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
* [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
* [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme)
* [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme)
* Vibrant user community
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories) and [PlatformIO](https://platformio.org/lib/search)
* [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson)
@ -115,10 +117,8 @@ DynamicJsonDocument doc(1024);
doc["sensor"] = "gps";
doc["time"] = 1351824120;
JsonArray data = doc.createNestedArray("data");
data.add(48.756080);
data.add(2.302038);
doc["data"][0] = 48.756080;
doc["data"][1] = 2.302038;
serializeJson(doc, Serial);
// This prints:
@ -131,5 +131,5 @@ See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?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!
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.

View File

@ -1,4 +1,4 @@
version: 6.15.0.{build}
version: 6.15.1.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019

View File

@ -0,0 +1,4 @@
@PACKAGE_INIT@
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@")

View File

@ -10,8 +10,14 @@ add_executable(msgpack_fuzzer
msgpack_fuzzer.cpp
fuzzer_main.cpp
)
target_link_libraries(msgpack_fuzzer
ArduinoJson
)
add_executable(json_fuzzer
json_fuzzer.cpp
fuzzer_main.cpp
)
target_link_libraries(json_fuzzer
ArduinoJson
)

View File

@ -11,5 +11,9 @@ add_executable(ElementProxyTests
size.cpp
)
target_link_libraries(ElementProxyTests catch)
target_link_libraries(ElementProxyTests
ArduinoJson
catch
)
add_test(ElementProxy ElementProxyTests)

View File

@ -16,5 +16,9 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
)
endif()
target_link_libraries(IntegrationTests catch)
target_link_libraries(IntegrationTests
ArduinoJson
catch
)
add_test(IntegrationTests IntegrationTests)

View File

@ -19,5 +19,9 @@ add_executable(JsonArrayTests
undefined.cpp
)
target_link_libraries(JsonArrayTests catch)
target_link_libraries(JsonArrayTests
ArduinoJson
catch
)
add_test(JsonArray JsonArrayTests)

View File

@ -18,7 +18,11 @@ add_executable(JsonDeserializerTests
string.cpp
)
target_link_libraries(JsonDeserializerTests catch)
target_link_libraries(JsonDeserializerTests
ArduinoJson
catch
)
set_target_properties(JsonDeserializerTests PROPERTIES UNITY_BUILD OFF)
add_test(JsonDeserializer JsonDeserializerTests)

View File

@ -18,5 +18,9 @@ add_executable(JsonDocumentTests
subscript.cpp
)
target_link_libraries(JsonDocumentTests catch)
target_link_libraries(JsonDocumentTests
ArduinoJson
catch
)
add_test(JsonDocument JsonDocumentTests)

View File

@ -19,5 +19,9 @@ add_executable(JsonObjectTests
subscript.cpp
)
target_link_libraries(JsonObjectTests catch)
target_link_libraries(JsonObjectTests
ArduinoJson
catch
)
add_test(JsonObject JsonObjectTests)

View File

@ -14,5 +14,9 @@ add_executable(JsonSerializerTests
std_string.cpp
)
target_link_libraries(JsonSerializerTests catch)
target_link_libraries(JsonSerializerTests
ArduinoJson
catch
)
add_test(JsonSerializer JsonSerializerTests)

View File

@ -24,5 +24,9 @@ add_executable(JsonVariantTests
undefined.cpp
)
target_link_libraries(JsonVariantTests catch)
target_link_libraries(JsonVariantTests
ArduinoJson
catch
)
add_test(JsonVariant JsonVariantTests)

View File

@ -13,5 +13,9 @@ add_executable(MemberProxyTests
subscript.cpp
)
target_link_libraries(MemberProxyTests catch)
target_link_libraries(MemberProxyTests
ArduinoJson
catch
)
add_test(MemberProxy MemberProxyTests)

View File

@ -10,5 +10,9 @@ add_executable(MemoryPoolTests
StringBuilder.cpp
)
target_link_libraries(MemoryPoolTests catch)
target_link_libraries(MemoryPoolTests
ArduinoJson
catch
)
add_test(MemoryPool MemoryPoolTests)

View File

@ -15,7 +15,11 @@ add_executable(MiscTests
version.cpp
)
target_link_libraries(MiscTests catch)
target_link_libraries(MiscTests
ArduinoJson
catch
)
set_target_properties(MiscTests PROPERTIES UNITY_BUILD OFF)
add_test(Misc MiscTests)

View File

@ -9,20 +9,26 @@ add_executable(MixedConfigurationTests
cpp11.cpp
decode_unicode_0.cpp
decode_unicode_1.cpp
enable_alignment_0.cpp
enable_alignment_1.cpp
enable_comments_0.cpp
enable_comments_1.cpp
enable_infinity_0.cpp
enable_infinity_1.cpp
enable_nan_0.cpp
enable_nan_1.cpp
enable_progmem_1.cpp
use_double_0.cpp
use_double_1.cpp
use_long_long_0.cpp
use_long_long_1.cpp
enable_progmem_1.cpp
enable_comments_1.cpp
enable_comments_0.cpp
)
target_link_libraries(MixedConfigurationTests catch)
target_link_libraries(MixedConfigurationTests
ArduinoJson
catch
)
set_target_properties(MixedConfigurationTests PROPERTIES UNITY_BUILD OFF)
add_test(MixedConfiguration MixedConfigurationTests)

View File

@ -0,0 +1,41 @@
#define ARDUINOJSON_NAMESPACE ArduinoJson_NoAlignment
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("ARDUINOJSON_ENABLE_ALIGNMENT == 0") {
using namespace ARDUINOJSON_NAMESPACE;
const size_t N = sizeof(void*);
SECTION("isAligned()") {
CHECK(isAligned(0) == true);
CHECK(isAligned(1) == true);
CHECK(isAligned(N) == true);
CHECK(isAligned(N + 1) == true);
CHECK(isAligned(2 * N) == true);
CHECK(isAligned(2 * N + 1) == true);
}
SECTION("addPadding()") {
CHECK(addPadding(0) == 0);
CHECK(addPadding(1) == 1);
CHECK(addPadding(N) == N);
CHECK(addPadding(N + 1) == N + 1);
}
SECTION("AddPadding<>") {
const size_t a = AddPadding<0>::value;
CHECK(a == 0);
const size_t b = AddPadding<1>::value;
CHECK(b == 1);
const size_t c = AddPadding<N>::value;
CHECK(c == N);
const size_t d = AddPadding<N + 1>::value;
CHECK(d == N + 1);
}
}

View File

@ -0,0 +1,40 @@
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("ARDUINOJSON_ENABLE_ALIGNMENT == 1") {
using namespace ARDUINOJSON_NAMESPACE;
const size_t N = sizeof(void*);
SECTION("isAligned()") {
CHECK(isAligned(0) == true);
CHECK(isAligned(1) == false);
CHECK(isAligned(N) == true);
CHECK(isAligned(N + 1) == false);
CHECK(isAligned(2 * N) == true);
CHECK(isAligned(2 * N + 1) == false);
}
SECTION("addPadding()") {
CHECK(addPadding(0) == 0);
CHECK(addPadding(1) == N);
CHECK(addPadding(N) == N);
CHECK(addPadding(N + 1) == 2 * N);
}
SECTION("AddPadding<>") {
const size_t a = AddPadding<0>::value;
CHECK(a == 0);
const size_t b = AddPadding<1>::value;
CHECK(b == N);
const size_t c = AddPadding<N>::value;
CHECK(c == N);
const size_t d = AddPadding<N + 1>::value;
CHECK(d == 2 * N);
}
}

View File

@ -14,5 +14,9 @@ add_executable(MsgPackDeserializerTests
notSupported.cpp
)
target_link_libraries(MsgPackDeserializerTests catch)
target_link_libraries(MsgPackDeserializerTests
ArduinoJson
catch
)
add_test(MsgPackDeserializer MsgPackDeserializerTests)

View File

@ -11,5 +11,9 @@ add_executable(MsgPackSerializerTests
serializeVariant.cpp
)
target_link_libraries(MsgPackSerializerTests catch)
target_link_libraries(MsgPackSerializerTests
ArduinoJson
catch
)
add_test(MsgPackSerializer MsgPackSerializerTests)

View File

@ -8,6 +8,10 @@ add_executable(NumbersTests
parseNumber.cpp
)
target_link_libraries(NumbersTests catch)
target_link_libraries(NumbersTests
ArduinoJson
catch
)
add_test(Numbers NumbersTests)

View File

@ -7,7 +7,11 @@ add_executable(TextFormatterTests
writeString.cpp
)
target_link_libraries(TextFormatterTests catch)
target_link_libraries(TextFormatterTests
ArduinoJson
catch
)
set_target_properties(TextFormatterTests PROPERTIES UNITY_BUILD OFF)
add_test(TextFormatter TextFormatterTests)

View File

@ -1,22 +1,20 @@
{
"name": "ArduinoJson",
"keywords": "json, rest, http, web",
"description": "An elegant and efficient JSON library for embedded systems",
"description": "A simple and efficient JSON library for embedded C++. ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation.",
"homepage": "https://arduinojson.org/?utm_source=meta&utm_medium=library.json",
"repository": {
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "6.15.0",
"version": "6.15.1",
"authors": {
"name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr"
},
"exclude": [
"fuzzing",
"scripts",
"test",
"third-party"
".github",
"extras"
],
"frameworks": "arduino",
"platforms": "*"

View File

@ -1,9 +1,9 @@
name=ArduinoJson
version=6.15.0
version=6.15.1
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=An efficient and elegant JSON library for Arduino.
paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation.
sentence=A simple and efficient JSON library for embedded C++.
paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, 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/?utm_source=meta&utm_medium=library.properties
architectures=*

View File

@ -6,7 +6,7 @@
#include "ArduinoJson/Configuration.hpp"
#if ARDUINOJSON_DEBUG
#if !ARDUINOJSON_DEBUG
#ifdef __clang__
#pragma clang system_header
#elif defined __GNUC__

View File

@ -72,6 +72,11 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
return getUpstreamElement().template as<T>();
}
template <typename T>
FORCE_INLINE operator T() const {
return getUpstreamElement();
}
template <typename T>
FORCE_INLINE bool is() const {
return getUpstreamElement().template is<T>();

View File

@ -203,6 +203,14 @@
#endif
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
#if defined(__AVR)
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#else
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
#endif
#ifndef ARDUINOJSON_TAB
#define ARDUINOJSON_TAB " "
#endif

View File

@ -22,6 +22,15 @@ class JsonDeserializer {
typedef typename remove_reference<TStringStorage>::type::StringBuilder
StringBuilder;
struct StringOrError {
DeserializationError err;
const char *value;
StringOrError(DeserializationError e) : err(e) {}
StringOrError(DeserializationError::Code c) : err(c) {}
StringOrError(const char *s) : err(DeserializationError::Ok), value(s) {}
};
public:
JsonDeserializer(MemoryPool &pool, TReader reader,
TStringStorage stringStorage)
@ -216,8 +225,8 @@ class JsonDeserializer {
// Read each key value pair
for (;;) {
// Parse key
const char *key;
err = parseKey(key);
StringOrError key = parseKey();
err = key.err; // <- this trick saves 62 bytes on AVR
if (err)
return err;
@ -228,17 +237,17 @@ class JsonDeserializer {
if (!eat(':'))
return DeserializationError::InvalidInput;
TFilter memberFilter = filter[key];
TFilter memberFilter = filter[key.value];
if (memberFilter.allow()) {
VariantData *variant = object.getMember(adaptString(key));
VariantData *variant = object.getMember(adaptString(key.value));
if (!variant) {
// Allocate slot in object
VariantSlot *slot = object.addSlot(_pool);
if (!slot)
return DeserializationError::NoMemory;
slot->setOwnedKey(make_not_null(key));
slot->setOwnedKey(make_not_null(key.value));
variant = slot->data();
}
@ -248,7 +257,7 @@ class JsonDeserializer {
if (err)
return err;
} else {
_stringStorage.reclaim(key);
_stringStorage.reclaim(key.value);
err = skipVariant(nestingLimit.decrement());
if (err)
return err;
@ -323,24 +332,23 @@ class JsonDeserializer {
}
}
DeserializationError parseKey(const char *&key) {
StringOrError parseKey() {
if (isQuote(current())) {
return parseQuotedString(key);
return parseQuotedString();
} else {
return parseNonQuotedString(key);
return parseNonQuotedString();
}
}
DeserializationError parseStringValue(VariantData &variant) {
const char *value;
DeserializationError err = parseQuotedString(value);
if (err)
return err;
variant.setOwnedString(make_not_null(value));
StringOrError result = parseQuotedString();
if (result.err)
return result.err;
variant.setOwnedString(make_not_null(result.value));
return DeserializationError::Ok;
}
DeserializationError parseQuotedString(const char *&result) {
StringOrError parseQuotedString() {
StringBuilder builder = _stringStorage.startString();
#if ARDUINOJSON_DECODE_UNICODE
Utf16::Codepoint codepoint;
@ -385,13 +393,13 @@ class JsonDeserializer {
builder.append(c);
}
result = builder.complete();
const char *result = builder.complete();
if (!result)
return DeserializationError::NoMemory;
return DeserializationError::Ok;
return result;
}
DeserializationError parseNonQuotedString(const char *&result) {
StringOrError parseNonQuotedString() {
StringBuilder builder = _stringStorage.startString();
char c = current();
@ -407,10 +415,10 @@ class JsonDeserializer {
return DeserializationError::InvalidInput;
}
result = builder.complete();
const char *result = builder.complete();
if (!result)
return DeserializationError::NoMemory;
return DeserializationError::Ok;
return result;
}
DeserializationError skipString() {

View File

@ -8,6 +8,16 @@
#include <stdint.h> // uint16_t, uint32_t
// The high surrogate may be uninitialized if the pair is invalid,
// we choose to ignore the problem to reduce the size of the code
// Garbage in => Garbage out
#if defined(__GNUC__)
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
#endif
namespace ARDUINOJSON_NAMESPACE {
namespace Utf16 {
@ -47,3 +57,9 @@ class Codepoint {
};
} // namespace Utf16
} // namespace ARDUINOJSON_NAMESPACE
#if defined(__GNUC__)
#if __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -10,9 +10,11 @@
namespace ARDUINOJSON_NAMESPACE {
inline bool isAligned(void *ptr) {
#if ARDUINOJSON_ENABLE_ALIGNMENT
inline bool isAligned(size_t value) {
const size_t mask = sizeof(void *) - 1;
size_t addr = reinterpret_cast<size_t>(ptr);
size_t addr = value;
return (addr & mask) == 0;
}
@ -21,16 +23,38 @@ inline size_t addPadding(size_t bytes) {
return (bytes + mask) & ~mask;
}
template <typename T>
inline T *addPadding(T *p) {
size_t address = addPadding(reinterpret_cast<size_t>(p));
return reinterpret_cast<T *>(address);
}
template <size_t bytes>
struct AddPadding {
static const size_t mask = sizeof(void *) - 1;
static const size_t value = (bytes + mask) & ~mask;
};
#else
inline bool isAligned(size_t) {
return true;
}
inline size_t addPadding(size_t bytes) {
return bytes;
}
template <size_t bytes>
struct AddPadding {
static const size_t value = bytes;
};
#endif
template <typename T>
inline bool isAligned(T *ptr) {
return isAligned(reinterpret_cast<size_t>(ptr));
}
template <typename T>
inline T *addPadding(T *p) {
size_t address = addPadding(reinterpret_cast<size_t>(p));
return reinterpret_cast<T *>(address);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -233,7 +233,7 @@ class MsgPackDeserializer {
}
DeserializationError readString(VariantData &variant, size_t n) {
const char *s;
const char *s = 0; // <- mute "maybe-uninitialized" (+4 bytes on AVR)
DeserializationError err = readString(s, n);
if (!err)
variant.setOwnedString(make_not_null(s));
@ -300,7 +300,7 @@ class MsgPackDeserializer {
if (!slot)
return DeserializationError::NoMemory;
const char *key;
const char *key = 0; // <- mute "maybe-uninitialized" (+4 bytes on AVR)
DeserializationError err = parseKey(key);
if (err)
return err;

View File

@ -125,7 +125,13 @@ class MsgPackSerializer {
} else if (value <= 0xFFFF) {
writeByte(0xCD);
writeInteger(uint16_t(value));
} else if (value <= 0xFFFFFFFF) {
}
#if ARDUINOJSON_USE_LONG_LONG
else if (value <= 0xFFFFFFFF)
#else
else
#endif
{
writeByte(0xCE);
writeInteger(uint32_t(value));
}

View File

@ -7,6 +7,8 @@
#include <ArduinoJson/Configuration.hpp>
#include <ArduinoJson/version.hpp>
#ifndef ARDUINOJSON_NAMESPACE
#define ARDUINOJSON_DO_CONCAT(A, B) A##B
#define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_DO_CONCAT(A, B)
#define ARDUINOJSON_CONCAT4(A, B, C, D) \
@ -25,3 +27,5 @@
ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_DECODE_UNICODE, \
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_ENABLE_COMMENTS)
#endif

View File

@ -73,6 +73,11 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
return getUpstreamMember().template as<TValue>();
}
template <typename T>
FORCE_INLINE operator T() const {
return getUpstreamMember();
}
template <typename TValue>
FORCE_INLINE bool is() const {
return getUpstreamMember().template is<TValue>();

View File

@ -1,24 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2020
// MIT License
#pragma once
#include <ArduinoJson/Polyfills/attributes.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <typename TImpl>
class VariantCasts {
public:
template <typename T>
FORCE_INLINE operator T() const {
return impl()->template as<T>();
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -4,7 +4,6 @@
#pragma once
#include <ArduinoJson/Operators/VariantCasts.hpp>
#include <ArduinoJson/Operators/VariantComparisons.hpp>
#include <ArduinoJson/Operators/VariantOr.hpp>
#include <ArduinoJson/Operators/VariantShortcuts.hpp>
@ -12,8 +11,7 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename TImpl>
class VariantOperators : public VariantCasts<TImpl>,
public VariantComparisons<TImpl>,
class VariantOperators : public VariantComparisons<TImpl>,
public VariantOr<TImpl>,
public VariantShortcuts<TImpl> {};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -24,7 +24,6 @@ inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool,
} else {
return slotSetKey(var, key, pool, storage_policy::store_by_copy());
}
return true;
}
template <typename TAdaptedString>

View File

@ -53,44 +53,52 @@ struct VariantConstAs<ArrayRef> {
template <typename T>
inline typename enable_if<is_integral<T>::value, T>::type variantAs(
const VariantData* _data) {
return _data != 0 ? _data->asIntegral<T>() : T(0);
const VariantData* data) {
return data != 0 ? data->asIntegral<T>() : T(0);
}
template <typename T>
inline typename enable_if<is_same<T, bool>::value, T>::type variantAs(
const VariantData* _data) {
return _data != 0 ? _data->asBoolean() : false;
const VariantData* data) {
return data != 0 ? data->asBoolean() : false;
}
template <typename T>
inline typename enable_if<is_floating_point<T>::value, T>::type variantAs(
const VariantData* _data) {
return _data != 0 ? _data->asFloat<T>() : T(0);
const VariantData* data) {
return data != 0 ? data->asFloat<T>() : T(0);
}
template <typename T>
inline typename enable_if<is_same<T, const char*>::value ||
is_same<T, char*>::value,
const char*>::type
variantAs(const VariantData* _data) {
return _data != 0 ? _data->asString() : 0;
variantAs(const VariantData* data) {
return data != 0 ? data->asString() : 0;
}
template <typename T>
T variantAs(VariantData* data, MemoryPool*) {
// By default use the read-only conversion.
// There are specializations for
// - ArrayRef
return variantAs<T>(data);
}
template <typename T>
inline typename enable_if<is_same<ArrayConstRef, T>::value, T>::type variantAs(
const VariantData* _data);
const VariantData* data);
template <typename T>
inline typename enable_if<is_same<ObjectConstRef, T>::value, T>::type variantAs(
const VariantData* _data);
const VariantData* data);
template <typename T>
inline typename enable_if<is_same<VariantConstRef, T>::value, T>::type
variantAs(const VariantData* _data);
variantAs(const VariantData* data);
template <typename T>
inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
const VariantData* _data);
const VariantData* data);
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -39,4 +39,19 @@ inline typename enable_if<IsWriteableString<T>::value, T>::type variantAs(
return s;
}
template <>
inline ArrayRef variantAs<ArrayRef>(VariantData* data, MemoryPool* pool) {
return ArrayRef(pool, data != 0 ? data->asArray() : 0);
}
template <>
inline ObjectRef variantAs<ObjectRef>(VariantData* data, MemoryPool* pool) {
return ObjectRef(pool, data != 0 ? data->asObject() : 0);
}
template <>
inline VariantRef variantAs<VariantRef>(VariantData* data, MemoryPool* pool) {
return VariantRef(pool, data);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -10,6 +10,16 @@
#include <ArduinoJson/Strings/RamStringAdapter.hpp>
#include <ArduinoJson/Variant/VariantContent.hpp>
// VariantData can't have a constructor (to be a POD), so we have no way to fix
// this warning
#if defined(__GNUC__)
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
#endif
namespace ARDUINOJSON_NAMESPACE {
class VariantData {
@ -383,3 +393,9 @@ class VariantData {
};
} // namespace ARDUINOJSON_NAMESPACE
#if defined(__GNUC__)
#if __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -83,18 +83,6 @@ typename enable_if<IsVisitable<TVariant>::value, bool>::type VariantRef::set(
return variantCopyFrom(_data, v._data, _pool);
}
template <typename T>
inline typename enable_if<is_same<T, ArrayRef>::value, T>::type VariantRef::as()
const {
return ArrayRef(_pool, _data != 0 ? _data->asArray() : 0);
}
template <typename T>
inline typename enable_if<is_same<T, ObjectRef>::value, T>::type
VariantRef::as() const {
return ObjectRef(_pool, variantAsObject(_data));
}
template <typename T>
inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type
VariantRef::to() const {

View File

@ -246,36 +246,14 @@ class VariantRef : public VariantRefBase<VariantData>,
return variantSetSignedInteger(_data, static_cast<Integer>(value));
}
// Get the variant as the specified type.
//
// std::string as<std::string>() const;
// String as<String>() const;
template <typename T>
FORCE_INLINE typename enable_if<!is_same<T, ArrayRef>::value &&
!is_same<T, ObjectRef>::value &&
!is_same<T, VariantRef>::value,
typename VariantAs<T>::type>::type
as() const {
return variantAs<T>(_data);
FORCE_INLINE typename VariantAs<T>::type as() const {
return variantAs<typename VariantAs<T>::type>(_data, _pool);
}
//
// ArrayRef as<ArrayRef>() const;
// const ArrayRef as<const ArrayRef>() const;
template <typename T>
FORCE_INLINE typename enable_if<is_same<T, ArrayRef>::value, T>::type as()
const;
//
// ObjectRef as<ObjectRef>() const;
// const ObjectRef as<const ObjectRef>() const;
template <typename T>
FORCE_INLINE typename enable_if<is_same<T, ObjectRef>::value, T>::type as()
const;
//
// VariantRef as<VariantRef> const;
template <typename T>
FORCE_INLINE typename enable_if<is_same<T, VariantRef>::value, T>::type as()
const {
return *this;
FORCE_INLINE operator T() const {
return variantAs<T>(_data, _pool);
}
template <typename Visitor>
@ -376,13 +354,16 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
variantAccept(_data, visitor);
}
// Get the variant as the specified type.
//
template <typename T>
FORCE_INLINE typename VariantConstAs<T>::type as() const {
return variantAs<typename VariantConstAs<T>::type>(_data);
}
template <typename T>
FORCE_INLINE operator T() const {
return variantAs<T>(_data);
}
FORCE_INLINE VariantConstRef getElement(size_t) const;
FORCE_INLINE VariantConstRef operator[](size_t index) const {

View File

@ -4,7 +4,7 @@
#pragma once
#define ARDUINOJSON_VERSION "6.15.0"
#define ARDUINOJSON_VERSION "6.15.1"
#define ARDUINOJSON_VERSION_MAJOR 6
#define ARDUINOJSON_VERSION_MINOR 15
#define ARDUINOJSON_VERSION_REVISION 0
#define ARDUINOJSON_VERSION_REVISION 1

79
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,79 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2020
# MIT License
# I have no idea what this is about, I simply followed the instructions from:
# https://dominikberner.ch/cmake-interface-lib/
add_library(ArduinoJson INTERFACE)
include(GNUInstallDirs)
# Adding the install interface generator expression makes sure that the include
# files are installed to the proper location (provided by GNUInstallDirs)
target_include_directories(ArduinoJson
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
# locations are provided by GNUInstallDirs
install(
TARGETS
ArduinoJson
EXPORT
ArduinoJson_Targets
ARCHIVE DESTINATION
${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION
${CMAKE_INSTALL_BINDIR}
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake"
VERSION
6.15.0
COMPATIBILITY
SameMajorVersion
)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/extras/ArduinoJsonConfig.cmake.in"
"${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake"
INSTALL_DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake)
install(
EXPORT
ArduinoJson_Targets
FILE
ArduinoJsonTargets.cmake
DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake
)
install(
FILES
"${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake"
"${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake"
DESTINATION
"${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake"
)
install(
FILES
ArduinoJson.h
ArduinoJson.hpp
DESTINATION
include
)
install(
DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}/ArduinoJson"
DESTINATION
include
)