mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-03 21:57:02 +02:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
67b6797b6d | |||
8d9504239b | |||
bf5d0c790c | |||
f4379f97ae | |||
3dc67c5663 | |||
47f90b02c3 | |||
27c924746b | |||
7abf875071 | |||
e3e375f5cd | |||
ff06292d74 | |||
c1278797f2 | |||
421ecec0dd | |||
89ed54362b | |||
986f77fa15 | |||
f831ed395d | |||
a880614a75 | |||
ef8379df1b | |||
702f8c2e2f | |||
6806393285 | |||
dea8387586 |
19
.github/workflows/ci.yml
vendored
19
.github/workflows/ci.yml
vendored
@ -40,6 +40,7 @@ jobs:
|
||||
- gcc: "9"
|
||||
cxxflags: -fsanitize=address -fno-sanitize-recover=all
|
||||
- gcc: "10"
|
||||
cxxflags: -funsigned-char # Issue #1715
|
||||
- gcc: "11"
|
||||
steps:
|
||||
- name: Install
|
||||
@ -47,10 +48,10 @@ jobs:
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
sudo add-apt-repository -yn 'deb http://mirrors.kernel.org/ubuntu hirsute main universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
sudo add-apt-repository -yn 'deb http://mirrors.kernel.org/ubuntu hirsute main universe'
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y gcc-${{ matrix.gcc }} g++-${{ matrix.gcc }}
|
||||
- name: Checkout
|
||||
@ -103,9 +104,9 @@ jobs:
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic main'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe'
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang-${{ matrix.clang }}
|
||||
- name: Checkout
|
||||
@ -131,7 +132,9 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Install
|
||||
run: sudo apt-get install -y g++-multilib
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y g++-multilib
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: GCC 32-bit
|
||||
@ -424,7 +427,9 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Install
|
||||
run: sudo apt-get install -y valgrind ninja-build
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y valgrind ninja-build
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Configure
|
||||
|
21
CHANGELOG.md
21
CHANGELOG.md
@ -1,6 +1,27 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
v6.19.4 (2022-04-05)
|
||||
-------
|
||||
|
||||
* Add `ElementProxy::memoryUsage()`
|
||||
* Add `MemberProxy::memoryUsage()` (issue #1730)
|
||||
* Add implicit conversion from `JsonDocument` to `JsonVariant`
|
||||
* Fix comparisons operators with `const JsonDocument&`
|
||||
|
||||
v6.19.3 (2022-03-08)
|
||||
-------
|
||||
|
||||
* Fix `call of overloaded 'String(const char*, int)' is ambiguous`
|
||||
* Fix `JsonString` operator `==` and `!=` for non-zero-terminated string
|
||||
* Fix `-Wsign-conversion` on GCC 8 (issue #1715)
|
||||
* MessagePack: serialize round floats as integers (issue #1718)
|
||||
|
||||
v6.19.2 (2022-02-14)
|
||||
-------
|
||||
|
||||
* Fix `cannot convert 'pgm_p' to 'const void*'` (issue #1707)
|
||||
|
||||
v6.19.1 (2022-01-14)
|
||||
-------
|
||||
|
||||
|
@ -10,7 +10,7 @@ if(ESP_PLATFORM)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(ArduinoJson VERSION 6.19.1)
|
||||
project(ArduinoJson VERSION 6.19.4)
|
||||
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
include(CTest)
|
||||
|
@ -7,8 +7,8 @@
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
[](https://lgtm.com/projects/g/bblanchon/ArduinoJson/)
|
||||
[](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.19.1)
|
||||
[](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.19.1)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.19.4)
|
||||
[](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.19.4)
|
||||
[](https://github.com/bblanchon/ArduinoJson/stargazers)
|
||||
[](https://github.com/sponsors/bblanchon)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 6.19.1.{build}
|
||||
version: 6.19.4.{build}
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
|
||||
|
@ -18,6 +18,7 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||
-Wparentheses
|
||||
-Wredundant-decls
|
||||
-Wshadow
|
||||
-Wsign-conversion
|
||||
-Wsign-promo
|
||||
-Wstrict-aliasing
|
||||
-Wundef
|
||||
@ -92,3 +93,9 @@ if(MSVC)
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
# Static link on MinGW to avoid linking with the wrong DLLs when multiple
|
||||
# versions are installed.
|
||||
add_link_options(-static)
|
||||
endif()
|
||||
|
@ -69,7 +69,7 @@ push
|
||||
extras/scripts/build-arduino-package.sh . "../ArduinoJson-$TAG.zip"
|
||||
extras/scripts/build-single-header.sh "src/ArduinoJson.h" "../ArduinoJson-$TAG.h"
|
||||
extras/scripts/build-single-header.sh "src/ArduinoJson.hpp" "../ArduinoJson-$TAG.hpp"
|
||||
extras/scripts/wandbox/publish.sh "../ArduinoJson-$TAG.h" > "../ArduinoJson-$TAG-wandbox.txt"
|
||||
extras/scripts/wandbox/publish.sh "../ArduinoJson-$TAG.h" > "../ArduinoJson-$TAG-wandbox.txt" || echo "Wandbox failed!"
|
||||
extras/scripts/get-release-page.sh "$VERSION" "CHANGELOG.md" "../ArduinoJson-$TAG-wandbox.txt" > "../ArduinoJson-$TAG.md"
|
||||
|
||||
echo "You can now copy ../ArduinoJson-$TAG.md into arduinojson.org/collections/_versions/$VERSION.md"
|
||||
|
@ -15,13 +15,13 @@ compile() {
|
||||
"code":$(read_string "$FILE_PATH"),
|
||||
"codes": [{"file":"ArduinoJson.h","code":$(read_string "$ARDUINOJSON_H")}],
|
||||
"options": "warning",
|
||||
"compiler": "gcc-4.9.3",
|
||||
"compiler": "gcc-4.9.4",
|
||||
"save": true
|
||||
}
|
||||
END
|
||||
URL=$(curl -sS -H "Content-type: application/json" -d @parameters.json https://wandbox.org/api/compile.json | jq --raw-output .url)
|
||||
rm parameters.json
|
||||
echo "$1: $URL"
|
||||
[ -n "$URL" ] && echo "$1: $URL"
|
||||
}
|
||||
|
||||
compile "JsonGeneratorExample"
|
||||
|
@ -40,7 +40,7 @@ TEST_CASE("JsonArray::add()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("vla") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
|
@ -135,7 +135,7 @@ TEST_CASE("JsonArray::operator[]") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("set(VLA)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
@ -146,7 +146,7 @@ TEST_CASE("JsonArray::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("operator=(VLA)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
|
@ -366,7 +366,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up element error even if array is skipped
|
||||
// bubble up element error even if array is skipped
|
||||
"[1,'2,3]",
|
||||
"false",
|
||||
10,
|
||||
@ -375,7 +375,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up member error even if object is skipped
|
||||
// bubble up member error even if object is skipped
|
||||
"{'hello':'worl}",
|
||||
"false",
|
||||
10,
|
||||
@ -384,7 +384,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up colon error even if object is skipped
|
||||
// bubble up colon error even if object is skipped
|
||||
"{'hello','world'}",
|
||||
"false",
|
||||
10,
|
||||
@ -393,7 +393,7 @@ TEST_CASE("Filtering") {
|
||||
0
|
||||
},
|
||||
{
|
||||
// bubble up key error even if object is skipped
|
||||
// bubble up key error even if object is skipped
|
||||
"{'hello:1}",
|
||||
"false",
|
||||
10,
|
||||
@ -404,7 +404,7 @@ TEST_CASE("Filtering") {
|
||||
{
|
||||
// detect invalid value in skipped object
|
||||
"{'hello':!}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
@ -413,235 +413,235 @@ TEST_CASE("Filtering") {
|
||||
{
|
||||
// ignore invalid value in skipped object
|
||||
"{'hello':\\}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored objects
|
||||
"{}",
|
||||
"false",
|
||||
"false",
|
||||
0,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored objects
|
||||
"{'hello':{}}",
|
||||
"false",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored values in objects
|
||||
"{'hello':{}}",
|
||||
"{}",
|
||||
"{}",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored arrays
|
||||
"[]",
|
||||
"false",
|
||||
"false",
|
||||
0,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored arrays
|
||||
"[[]]",
|
||||
"false",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// check nesting limit even for ignored values in arrays
|
||||
"[[]]",
|
||||
"[]",
|
||||
"[]",
|
||||
1,
|
||||
DeserializationError::TooDeep,
|
||||
"[]",
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// supports back-slash at the end of skipped string
|
||||
"\"hell\\",
|
||||
"false",
|
||||
"false",
|
||||
1,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment at after an element in a skipped array
|
||||
"[1/]",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete comment at after an element in a skipped array
|
||||
"[1/*]",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// missing comma in a skipped array
|
||||
"[1 2]",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment at the beginning of array
|
||||
"[/1]",
|
||||
"[false]",
|
||||
"[false]",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"[]",
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment at the begining of an array
|
||||
"[/*]",
|
||||
"[false]",
|
||||
"[false]",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"[]",
|
||||
"[]",
|
||||
JSON_ARRAY_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment before key
|
||||
"{/1:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment before key
|
||||
"{/*:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment after key
|
||||
"{\"example\"/1:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment after key
|
||||
"{\"example\"/*:2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment after colon
|
||||
"{\"example\":/12}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// incomplete comment after colon
|
||||
"{\"example\":/*2}",
|
||||
"{}",
|
||||
"{}",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// comment next to an integer
|
||||
"{\"ignore\":1//,\"example\":2\n}",
|
||||
"{\"example\":true}",
|
||||
"{\"example\":true}",
|
||||
10,
|
||||
DeserializationError::Ok,
|
||||
"{}",
|
||||
"{}",
|
||||
JSON_OBJECT_SIZE(0)
|
||||
},
|
||||
{
|
||||
// invalid comment after opening brace of a skipped object
|
||||
"{/1:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete after opening brace of a skipped object
|
||||
"{/*:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment after key of a skipped object
|
||||
"{\"example\"/:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete after after key of a skipped object
|
||||
"{\"example\"/*:2}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// invalid comment after value in a skipped object
|
||||
"{\"example\":2/}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::InvalidInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
{
|
||||
// incomplete after after value of a skipped object
|
||||
"{\"example\":2/*}",
|
||||
"false",
|
||||
"false",
|
||||
10,
|
||||
DeserializationError::IncompleteInput,
|
||||
"null",
|
||||
"null",
|
||||
0
|
||||
},
|
||||
}; // clang-format on
|
||||
@ -708,7 +708,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, Filter(filter));
|
||||
@ -736,7 +736,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter, NestingLimit") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, Filter(filter), NestingLimit(5));
|
||||
@ -764,7 +764,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], NestingLimit, Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeJson(doc, vla, NestingLimit(5), Filter(filter));
|
||||
|
@ -121,7 +121,7 @@ TEST_CASE("deserializeJson(std::istream&)") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
TEST_CASE("deserializeJson(VLA)") {
|
||||
int i = 9;
|
||||
size_t i = 9;
|
||||
char vla[i];
|
||||
strcpy(vla, "{\"a\":42}");
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
add_executable(JsonDocumentTests
|
||||
add.cpp
|
||||
BasicJsonDocument.cpp
|
||||
cast.cpp
|
||||
compare.cpp
|
||||
containsKey.cpp
|
||||
createNested.cpp
|
||||
|
@ -205,4 +205,26 @@ TEST_CASE("DynamicJsonDocument assignment") {
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from MemberProxy") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
doc1["value"] = 42;
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = doc1["value"];
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
|
||||
SECTION("Assign from ElementProxy") {
|
||||
StaticJsonDocument<200> doc1;
|
||||
doc1[0] = 42;
|
||||
|
||||
DynamicJsonDocument doc2(4096);
|
||||
doc2 = doc1[0];
|
||||
|
||||
REQUIRE_JSON(doc2, "42");
|
||||
REQUIRE(doc2.capacity() == 4096);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ using namespace ARDUINOJSON_NAMESPACE;
|
||||
TEST_CASE("ElementProxy::add()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
SECTION("add(int)") {
|
||||
ep.add(42);
|
||||
@ -36,7 +36,7 @@ TEST_CASE("ElementProxy::add()") {
|
||||
TEST_CASE("ElementProxy::clear()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
SECTION("size goes back to zero") {
|
||||
ep.add(42);
|
||||
@ -96,7 +96,7 @@ TEST_CASE("ElementProxy::operator==()") {
|
||||
TEST_CASE("ElementProxy::remove()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
SECTION("remove(int)") {
|
||||
ep.add(1);
|
||||
@ -131,7 +131,7 @@ TEST_CASE("ElementProxy::remove()") {
|
||||
ep["a"] = 1;
|
||||
ep["b"] = 2;
|
||||
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
ep.remove(vla);
|
||||
@ -143,7 +143,7 @@ TEST_CASE("ElementProxy::remove()") {
|
||||
|
||||
TEST_CASE("ElementProxy::set()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
SECTION("set(int)") {
|
||||
ep.set(42);
|
||||
@ -169,7 +169,7 @@ TEST_CASE("ElementProxy::set()") {
|
||||
TEST_CASE("ElementProxy::size()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument&> ep = doc[0];
|
||||
ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
SECTION("returns 0") {
|
||||
REQUIRE(ep.size() == 0);
|
||||
@ -188,9 +188,24 @@ TEST_CASE("ElementProxy::size()") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::memoryUsage()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc.addElement();
|
||||
ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
SECTION("returns 0 for null") {
|
||||
REQUIRE(ep.memoryUsage() == 0);
|
||||
}
|
||||
|
||||
SECTION("returns size for string") {
|
||||
ep.set(std::string("hello"));
|
||||
REQUIRE(ep.memoryUsage() == 6);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
ElementProxy<JsonDocument&> ep = doc[1];
|
||||
ElementProxy<JsonDocument &> ep = doc[1];
|
||||
|
||||
SECTION("set member") {
|
||||
ep["world"] = 42;
|
||||
@ -204,3 +219,29 @@ TEST_CASE("ElementProxy::operator[]") {
|
||||
REQUIRE(doc.as<std::string>() == "[null,[null,null,42]]");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy cast to JsonVariantConst") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc[0] = "world";
|
||||
|
||||
const ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
JsonVariantConst var = ep;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
}
|
||||
|
||||
TEST_CASE("ElementProxy cast to JsonVariant") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc[0] = "world";
|
||||
|
||||
ElementProxy<JsonDocument &> ep = doc[0];
|
||||
|
||||
JsonVariant var = ep;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
|
||||
var.set("toto");
|
||||
|
||||
CHECK(doc.as<std::string>() == "[\"toto\"]");
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ TEST_CASE("MemberProxy::remove()") {
|
||||
mp["a"] = 1;
|
||||
mp["b"] = 2;
|
||||
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
mp.remove(vla);
|
||||
@ -229,6 +229,20 @@ TEST_CASE("MemberProxy::size()") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::memoryUsage()") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
|
||||
SECTION("returns 0 when null") {
|
||||
REQUIRE(mp.memoryUsage() == 0);
|
||||
}
|
||||
|
||||
SECTION("return the size for a string") {
|
||||
mp.set(std::string("hello"));
|
||||
REQUIRE(mp.memoryUsage() == 6);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy::operator[]") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
@ -245,3 +259,29 @@ TEST_CASE("MemberProxy::operator[]") {
|
||||
REQUIRE(doc.as<std::string>() == "{\"hello\":[null,null,42]}");
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy cast to JsonVariantConst") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc["hello"] = "world";
|
||||
|
||||
const MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
|
||||
JsonVariantConst var = mp;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
}
|
||||
|
||||
TEST_CASE("MemberProxy cast to JsonVariant") {
|
||||
DynamicJsonDocument doc(4096);
|
||||
doc["hello"] = "world";
|
||||
|
||||
MemberProxy<JsonDocument &, const char *> mp = doc["hello"];
|
||||
|
||||
JsonVariant var = mp;
|
||||
|
||||
CHECK(var.as<std::string>() == "world");
|
||||
|
||||
var.set("toto");
|
||||
|
||||
CHECK(doc.as<std::string>() == "{\"hello\":\"toto\"}");
|
||||
}
|
||||
|
18
extras/tests/JsonDocument/cast.cpp
Normal file
18
extras/tests/JsonDocument/cast.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <catch.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST_CASE("Implicit cast to JsonVariant") {
|
||||
StaticJsonDocument<128> doc;
|
||||
|
||||
doc["hello"] = "world";
|
||||
|
||||
JsonVariant var = doc;
|
||||
|
||||
CHECK(var.as<std::string>() == "{\"hello\":\"world\"}");
|
||||
}
|
@ -75,3 +75,29 @@ TEST_CASE("StaticJsonDocument::operator==(const DynamicJsonDocument&)") {
|
||||
REQUIRE(doc1 != doc2);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("JsonDocument::operator==(const JsonDocument&)") {
|
||||
StaticJsonDocument<256> doc1;
|
||||
StaticJsonDocument<256> doc2;
|
||||
const JsonDocument& ref1 = doc1;
|
||||
const JsonDocument& ref2 = doc2;
|
||||
|
||||
SECTION("Empty") {
|
||||
REQUIRE(ref1 == ref2);
|
||||
REQUIRE_FALSE(ref1 != ref2);
|
||||
}
|
||||
|
||||
SECTION("With same object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["hello"] = "world";
|
||||
REQUIRE(ref1 == ref2);
|
||||
REQUIRE_FALSE(ref1 != ref2);
|
||||
}
|
||||
|
||||
SECTION("With different object") {
|
||||
doc1["hello"] = "world";
|
||||
doc2["world"] = "hello";
|
||||
REQUIRE_FALSE(ref1 == ref2);
|
||||
REQUIRE(ref1 != ref2);
|
||||
}
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ TEST_CASE("JsonDocument::remove()") {
|
||||
doc["a"] = 1;
|
||||
doc["b"] = 2;
|
||||
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
doc.remove(vla);
|
||||
|
@ -29,7 +29,7 @@ TEST_CASE("JsonObject::containsKey()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -16,7 +16,7 @@ TEST_CASE("JsonObject::createNestedArray()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -15,7 +15,7 @@ TEST_CASE("JsonObject::createNestedObject()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -60,7 +60,7 @@ TEST_CASE("JsonObject::remove()") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("key is a vla") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "b");
|
||||
obj.remove(vla);
|
||||
|
@ -141,13 +141,13 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("should duplicate a non-static JsonString key") {
|
||||
obj[JsonString("hello", false)] = "world";
|
||||
obj[JsonString("hello", JsonString::Copied)] = "world";
|
||||
const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(5);
|
||||
REQUIRE(expectedSize == doc.memoryUsage());
|
||||
}
|
||||
|
||||
SECTION("should not duplicate a static JsonString key") {
|
||||
obj[JsonString("hello", true)] = "world";
|
||||
obj[JsonString("hello", JsonString::Linked)] = "world";
|
||||
const size_t expectedSize = JSON_OBJECT_SIZE(1);
|
||||
REQUIRE(expectedSize == doc.memoryUsage());
|
||||
}
|
||||
@ -172,7 +172,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
|
||||
!defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
|
||||
SECTION("obj[VLA] = str") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
@ -182,7 +182,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj[str] = VLA") { // issue #416
|
||||
int i = 32;
|
||||
size_t i = 32;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
@ -192,7 +192,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj.set(VLA, str)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
@ -202,7 +202,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj.set(str, VLA)") {
|
||||
int i = 32;
|
||||
size_t i = 32;
|
||||
char vla[i];
|
||||
strcpy(vla, "world");
|
||||
|
||||
@ -212,7 +212,7 @@ TEST_CASE("JsonObject::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("obj[VLA]") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -136,7 +136,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
|
||||
REQUIRE(variant.as<long>() == 42L);
|
||||
REQUIRE(variant.as<JsonString>() == "42");
|
||||
REQUIRE(variant.as<JsonString>().isStatic() == true);
|
||||
REQUIRE(variant.as<JsonString>().isLinked() == true);
|
||||
}
|
||||
|
||||
SECTION("set(\"hello\")") {
|
||||
@ -159,7 +159,7 @@ TEST_CASE("JsonVariant::as()") {
|
||||
REQUIRE(variant.as<const char*>() == std::string("4.2"));
|
||||
REQUIRE(variant.as<std::string>() == std::string("4.2"));
|
||||
REQUIRE(variant.as<JsonString>() == "4.2");
|
||||
REQUIRE(variant.as<JsonString>().isStatic() == false);
|
||||
REQUIRE(variant.as<JsonString>().isLinked() == false);
|
||||
}
|
||||
|
||||
SECTION("set(\"true\")") {
|
||||
|
@ -71,7 +71,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("VLA") {
|
||||
int n = 16;
|
||||
size_t n = 16;
|
||||
char str[n];
|
||||
|
||||
strcpy(str, "hello");
|
||||
@ -98,7 +98,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
char str[16];
|
||||
|
||||
strcpy(str, "hello");
|
||||
bool result = variant.set(JsonString(str, true));
|
||||
bool result = variant.set(JsonString(str, JsonString::Linked));
|
||||
strcpy(str, "world");
|
||||
|
||||
REQUIRE(result == true);
|
||||
@ -109,7 +109,7 @@ TEST_CASE("JsonVariant::set() when there is enough memory") {
|
||||
char str[16];
|
||||
|
||||
strcpy(str, "hello");
|
||||
bool result = variant.set(JsonString(str, false));
|
||||
bool result = variant.set(JsonString(str, JsonString::Copied));
|
||||
strcpy(str, "world");
|
||||
|
||||
REQUIRE(result == true);
|
||||
|
@ -108,7 +108,7 @@ TEST_CASE("JsonVariant::operator[]") {
|
||||
#if defined(HAS_VARIABLE_LENGTH_ARRAY) && \
|
||||
!defined(SUBSCRIPT_CONFLICTS_WITH_BUILTIN_OPERATOR)
|
||||
SECTION("key is a VLA") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
@ -119,7 +119,7 @@ TEST_CASE("JsonVariant::operator[]") {
|
||||
}
|
||||
|
||||
SECTION("key is a VLA, const JsonVariant") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
strcpy(vla, "hello");
|
||||
|
||||
|
@ -13,45 +13,54 @@ TEST_CASE("JsonString") {
|
||||
|
||||
CHECK(s.isNull() == true);
|
||||
CHECK(s.c_str() == 0);
|
||||
CHECK(s.isStatic() == true);
|
||||
CHECK(s.isLinked() == true);
|
||||
CHECK(s == JsonString());
|
||||
CHECK(s != "");
|
||||
}
|
||||
|
||||
SECTION("Compare null with boolean") {
|
||||
SECTION("Null converts to false") {
|
||||
JsonString s;
|
||||
|
||||
CHECK(bool(s) == false);
|
||||
CHECK(false == bool(s));
|
||||
CHECK(bool(s) != true);
|
||||
CHECK(true != bool(s));
|
||||
}
|
||||
|
||||
SECTION("Compare non-null with boolean") {
|
||||
JsonString s("hello");
|
||||
SECTION("Empty string converts to true") {
|
||||
JsonString s("");
|
||||
|
||||
CHECK(bool(s) == true);
|
||||
CHECK(true == bool(s));
|
||||
CHECK(bool(s) != false);
|
||||
CHECK(false != bool(s));
|
||||
}
|
||||
|
||||
SECTION("Compare null with null") {
|
||||
SECTION("Non-empty string converts to true") {
|
||||
JsonString s("");
|
||||
|
||||
CHECK(bool(s) == true);
|
||||
}
|
||||
|
||||
SECTION("Null strings equals each others") {
|
||||
JsonString a, b;
|
||||
|
||||
CHECK(a == b);
|
||||
CHECK_FALSE(a != b);
|
||||
}
|
||||
|
||||
SECTION("Compare null with non-null") {
|
||||
JsonString a(0), b("hello");
|
||||
SECTION("Null and empty strings differ") {
|
||||
JsonString a, b("");
|
||||
|
||||
CHECK_FALSE(a == b);
|
||||
CHECK(a != b);
|
||||
|
||||
CHECK_FALSE(b == a);
|
||||
CHECK(b != a);
|
||||
}
|
||||
|
||||
SECTION("Compare non-null with null") {
|
||||
JsonString a("hello"), b(0);
|
||||
SECTION("Null and non-empty strings differ") {
|
||||
JsonString a, b("hello");
|
||||
|
||||
CHECK_FALSE(a == b);
|
||||
CHECK(a != b);
|
||||
|
||||
CHECK_FALSE(b == a);
|
||||
CHECK(b != a);
|
||||
}
|
||||
|
||||
SECTION("Compare different strings") {
|
||||
@ -82,4 +91,13 @@ TEST_CASE("JsonString") {
|
||||
ss << JsonString("hello world!");
|
||||
CHECK(ss.str() == "hello world!");
|
||||
}
|
||||
|
||||
SECTION("Construct with a size") {
|
||||
JsonString s("hello world", 5);
|
||||
|
||||
CHECK(s.size() == 5);
|
||||
CHECK(s.isLinked() == true);
|
||||
CHECK(s == "hello");
|
||||
CHECK(s != "hello world");
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ add_executable(MixedConfigurationTests
|
||||
enable_progmem_1.cpp
|
||||
enable_string_deduplication_0.cpp
|
||||
enable_string_deduplication_1.cpp
|
||||
issue1707.cpp
|
||||
use_double_0.cpp
|
||||
use_double_1.cpp
|
||||
)
|
||||
|
17
extras/tests/MixedConfiguration/issue1707.cpp
Normal file
17
extras/tests/MixedConfiguration/issue1707.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
// ArduinoJson - https://arduinojson.org
|
||||
// Copyright © 2014-2022, Benoit BLANCHON
|
||||
// MIT License
|
||||
|
||||
#define ARDUINO
|
||||
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <catch.hpp>
|
||||
|
||||
TEST_CASE("Issue1707") {
|
||||
StaticJsonDocument<128> doc;
|
||||
|
||||
DeserializationError err = deserializeJson(doc, F("{\"hello\":12}"));
|
||||
REQUIRE(err == DeserializationError::Ok);
|
||||
}
|
@ -1068,7 +1068,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeMsgPack(doc, vla, Filter(filter));
|
||||
@ -1096,7 +1096,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], Filter, NestingLimit") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeMsgPack(doc, vla, Filter(filter), NestingLimit(5));
|
||||
@ -1124,7 +1124,7 @@ TEST_CASE("Overloads") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
SECTION("char[n], NestingLimit, Filter") {
|
||||
int i = 4;
|
||||
size_t i = 4;
|
||||
char vla[i];
|
||||
strcpy(vla, "{}");
|
||||
deserializeMsgPack(doc, vla, NestingLimit(5), Filter(filter));
|
||||
|
@ -72,7 +72,7 @@ TEST_CASE("deserializeMsgPack(std::istream&)") {
|
||||
|
||||
#ifdef HAS_VARIABLE_LENGTH_ARRAY
|
||||
TEST_CASE("deserializeMsgPack(VLA)") {
|
||||
int i = 16;
|
||||
size_t i = 16;
|
||||
char vla[i];
|
||||
memcpy(vla, "\xDE\x00\x01\xA5Hello\xA5world", 15);
|
||||
|
||||
|
@ -144,4 +144,18 @@ TEST_CASE("serialize MsgPack value") {
|
||||
checkVariant(serialized("\xDA\xFF\xFF"), "\xDA\xFF\xFF");
|
||||
checkVariant(serialized("\xDB\x00\x01\x00\x00", 5), "\xDB\x00\x01\x00\x00");
|
||||
}
|
||||
|
||||
SECTION("serialize round double as integer") { // Issue #1718
|
||||
checkVariant(-32768.0, "\xD1\x80\x00");
|
||||
checkVariant(-129.0, "\xD1\xFF\x7F");
|
||||
checkVariant(-128.0, "\xD0\x80");
|
||||
checkVariant(-33.0, "\xD0\xDF");
|
||||
checkVariant(-32.0, "\xE0");
|
||||
checkVariant(-1.0, "\xFF");
|
||||
checkVariant(0.0, "\x00");
|
||||
checkVariant(127.0, "\x7F");
|
||||
checkVariant(128.0, "\xCC\x80");
|
||||
checkVariant(255.0, "\xCC\xFF");
|
||||
checkVariant(256.0, "\xCD\x01\x00");
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "6.19.1",
|
||||
"version": "6.19.4",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "https://blog.benoitblanchon.fr"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=6.19.1
|
||||
version=6.19.4
|
||||
author=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
sentence=A simple and efficient JSON library for embedded C++.
|
||||
|
@ -118,6 +118,10 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
return getUpstreamElement().size();
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t memoryUsage() const {
|
||||
return getUpstreamElement().memoryUsage();
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getMember(TNestedKey* key) const {
|
||||
return getUpstreamElement().getMember(key);
|
||||
|
@ -64,7 +64,7 @@ inline bool CollectionData::copyFrom(const CollectionData& src,
|
||||
for (VariantSlot* s = src._head; s; s = s->next()) {
|
||||
VariantData* var;
|
||||
if (s->key() != 0) {
|
||||
String key(s->key(), !s->ownsKey());
|
||||
String key(s->key(), s->ownsKey() ? String::Copied : String::Linked);
|
||||
var = addMember(adaptString(key), pool, getStringStoragePolicy(key));
|
||||
} else {
|
||||
var = addElement(pool);
|
||||
|
@ -14,7 +14,8 @@
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class JsonDocument : public Visitable {
|
||||
class JsonDocument : public Visitable,
|
||||
public VariantOperators<const JsonDocument&> {
|
||||
public:
|
||||
template <typename TVisitor>
|
||||
typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||
@ -295,16 +296,12 @@ class JsonDocument : public Visitable {
|
||||
_data.remove(adaptString(key));
|
||||
}
|
||||
|
||||
FORCE_INLINE operator VariantRef() {
|
||||
return getVariant();
|
||||
}
|
||||
|
||||
FORCE_INLINE operator VariantConstRef() const {
|
||||
return VariantConstRef(&_data);
|
||||
}
|
||||
|
||||
bool operator==(VariantConstRef rhs) const {
|
||||
return getVariant() == rhs;
|
||||
}
|
||||
|
||||
bool operator!=(VariantConstRef rhs) const {
|
||||
return getVariant() != rhs;
|
||||
return getVariant();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -481,7 +481,7 @@ class MsgPackDeserializer {
|
||||
T size;
|
||||
if (!readInteger(size))
|
||||
return false;
|
||||
return skipBytes(size + 1);
|
||||
return skipBytes(size + 1U);
|
||||
}
|
||||
|
||||
MemoryPool *_pool;
|
||||
|
@ -23,6 +23,11 @@ class MsgPackSerializer : public Visitor<size_t> {
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) {
|
||||
if (canConvertNumber<Integer>(value32)) {
|
||||
Integer truncatedValue = Integer(value32);
|
||||
if (value32 == T(truncatedValue))
|
||||
return visitSignedInteger(truncatedValue);
|
||||
}
|
||||
writeByte(0xCA);
|
||||
writeInteger(value32);
|
||||
return bytesWritten();
|
||||
@ -32,13 +37,10 @@ class MsgPackSerializer : public Visitor<size_t> {
|
||||
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
||||
typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) {
|
||||
float value32 = float(value64);
|
||||
if (value32 == value64) {
|
||||
writeByte(0xCA);
|
||||
writeInteger(value32);
|
||||
} else {
|
||||
writeByte(0xCB);
|
||||
writeInteger(value64);
|
||||
}
|
||||
if (value32 == value64)
|
||||
return visitFloat(value32);
|
||||
writeByte(0xCB);
|
||||
writeInteger(value64);
|
||||
return bytesWritten();
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,10 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
return getUpstreamMember().size();
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t memoryUsage() const {
|
||||
return getUpstreamMember().memoryUsage();
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
getUpstreamMember().remove(index);
|
||||
}
|
||||
|
@ -13,7 +13,8 @@ class Pair {
|
||||
public:
|
||||
Pair(MemoryPool* pool, VariantSlot* slot) {
|
||||
if (slot) {
|
||||
_key = String(slot->key(), !slot->ownsKey());
|
||||
_key = String(slot->key(),
|
||||
slot->ownsKey() ? String::Copied : String::Linked);
|
||||
_value = VariantRef(pool, slot->data());
|
||||
}
|
||||
}
|
||||
@ -35,7 +36,8 @@ class PairConst {
|
||||
public:
|
||||
PairConst(const VariantSlot* slot) {
|
||||
if (slot) {
|
||||
_key = String(slot->key(), !slot->ownsKey());
|
||||
_key = String(slot->key(),
|
||||
slot->ownsKey() ? String::Copied : String::Linked);
|
||||
_value = VariantConstRef(slot->data());
|
||||
}
|
||||
}
|
||||
|
@ -99,7 +99,7 @@ inline void* memcpy_P(void* dst, ARDUINOJSON_NAMESPACE::pgm_p src, size_t n) {
|
||||
#ifndef pgm_read_dword
|
||||
inline uint32_t pgm_read_dword(ARDUINOJSON_NAMESPACE::pgm_p p) {
|
||||
uint32_t result;
|
||||
memcpy_P(&result, p, 4);
|
||||
memcpy_P(&result, p.address, 4);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
@ -107,7 +107,7 @@ inline uint32_t pgm_read_dword(ARDUINOJSON_NAMESPACE::pgm_p p) {
|
||||
#ifndef pgm_read_ptr
|
||||
inline void* pgm_read_ptr(ARDUINOJSON_NAMESPACE::pgm_p p) {
|
||||
void* result;
|
||||
memcpy_P(&result, p, sizeof(result));
|
||||
memcpy_P(&result, p.address, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
@ -22,7 +22,7 @@ class StringCopier {
|
||||
String save() {
|
||||
ARDUINOJSON_ASSERT(_ptr);
|
||||
ARDUINOJSON_ASSERT(_size < _capacity); // needs room for the terminator
|
||||
return String(_pool->saveStringFromFreeZone(_size), _size, false);
|
||||
return String(_pool->saveStringFromFreeZone(_size), _size, String::Copied);
|
||||
}
|
||||
|
||||
void append(const char* s) {
|
||||
@ -52,7 +52,7 @@ class StringCopier {
|
||||
ARDUINOJSON_ASSERT(_ptr);
|
||||
ARDUINOJSON_ASSERT(_size < _capacity);
|
||||
_ptr[_size] = 0;
|
||||
return String(_ptr, _size, false);
|
||||
return String(_ptr, _size, String::Copied);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -33,7 +33,7 @@ class StringMover {
|
||||
|
||||
String str() const {
|
||||
_writePtr[0] = 0; // terminator
|
||||
return String(_startPtr, size(), true);
|
||||
return String(_startPtr, size(), String::Linked);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
|
@ -106,13 +106,13 @@ inline SizedRamString adaptString(const char* s, size_t n) {
|
||||
return SizedRamString(s, n);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
template <size_t N>
|
||||
struct IsString<char[N]> : true_type {};
|
||||
|
||||
template <int N>
|
||||
template <size_t N>
|
||||
struct IsString<const char[N]> : true_type {};
|
||||
|
||||
template <int N>
|
||||
template <size_t N>
|
||||
inline SizedRamString adaptString(char s[N]) {
|
||||
return SizedRamString(s, strlen(s));
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace ARDUINOJSON_NAMESPACE {
|
||||
struct LinkStringStoragePolicy {
|
||||
template <typename TAdaptedString, typename TCallback>
|
||||
bool store(TAdaptedString str, MemoryPool *, TCallback callback) {
|
||||
String storedString(str.data(), str.size(), true);
|
||||
String storedString(str.data(), str.size(), String::Linked);
|
||||
callback(storedString);
|
||||
return !str.isNull();
|
||||
}
|
||||
@ -50,7 +50,7 @@ inline LinkStringStoragePolicy getStringStoragePolicy(const char *) {
|
||||
}
|
||||
|
||||
inline LinkOrCopyStringStoragePolicy getStringStoragePolicy(const String &s) {
|
||||
return LinkOrCopyStringStoragePolicy(s.isStatic());
|
||||
return LinkOrCopyStringStoragePolicy(s.isLinked());
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -14,15 +14,15 @@ namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class String : public SafeBoolIdom<String> {
|
||||
public:
|
||||
String() : _data(0), _size(0), _isStatic(true) {}
|
||||
enum Ownership { Copied, Linked };
|
||||
|
||||
String(const char* data, bool isStaticData = true)
|
||||
: _data(data),
|
||||
_size(data ? ::strlen(data) : 0),
|
||||
_isStatic(isStaticData) {}
|
||||
String() : _data(0), _size(0), _ownership(Linked) {}
|
||||
|
||||
String(const char* data, size_t sz, bool isStaticData = true)
|
||||
: _data(data), _size(sz), _isStatic(isStaticData) {}
|
||||
String(const char* data, Ownership ownership = Linked)
|
||||
: _data(data), _size(data ? ::strlen(data) : 0), _ownership(ownership) {}
|
||||
|
||||
String(const char* data, size_t sz, Ownership ownership = Linked)
|
||||
: _data(data), _size(sz), _ownership(ownership) {}
|
||||
|
||||
const char* c_str() const {
|
||||
return _data;
|
||||
@ -32,8 +32,8 @@ class String : public SafeBoolIdom<String> {
|
||||
return !_data;
|
||||
}
|
||||
|
||||
bool isStatic() const {
|
||||
return _isStatic;
|
||||
bool isLinked() const {
|
||||
return _ownership == Linked;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
@ -46,23 +46,19 @@ class String : public SafeBoolIdom<String> {
|
||||
}
|
||||
|
||||
friend bool operator==(String lhs, String rhs) {
|
||||
if (lhs._size != rhs._size)
|
||||
return false;
|
||||
if (lhs._data == rhs._data)
|
||||
return true;
|
||||
if (!lhs._data)
|
||||
return false;
|
||||
if (!rhs._data)
|
||||
return false;
|
||||
return strcmp(lhs._data, rhs._data) == 0;
|
||||
return memcmp(lhs._data, rhs._data, lhs._size) == 0;
|
||||
}
|
||||
|
||||
friend bool operator!=(String lhs, String rhs) {
|
||||
if (lhs._data == rhs._data)
|
||||
return false;
|
||||
if (!lhs._data)
|
||||
return true;
|
||||
if (!rhs._data)
|
||||
return true;
|
||||
return strcmp(lhs._data, rhs._data) != 0;
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
@ -75,7 +71,7 @@ class String : public SafeBoolIdom<String> {
|
||||
private:
|
||||
const char* _data;
|
||||
size_t _size;
|
||||
bool _isStatic;
|
||||
Ownership _ownership;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -208,7 +208,7 @@ class MemoryPoolPrint : public Print {
|
||||
|
||||
String str() {
|
||||
ARDUINOJSON_ASSERT(_size < _capacity);
|
||||
return String(_pool->saveStringFromFreeZone(_size), _size, false);
|
||||
return String(_pool->saveStringFromFreeZone(_size), _size, String::Copied);
|
||||
}
|
||||
|
||||
size_t write(uint8_t c) {
|
||||
|
@ -131,9 +131,9 @@ struct RawComparer : ComparerBase {
|
||||
template <typename T>
|
||||
struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type>
|
||||
: ComparerBase {
|
||||
T rhs;
|
||||
const T *rhs; // TODO: should be a VariantConstRef
|
||||
|
||||
explicit Comparer(T value) : rhs(value) {}
|
||||
explicit Comparer(const T &value) : rhs(&value) {}
|
||||
|
||||
CompareResult visitArray(const CollectionData &lhs) {
|
||||
ArrayComparer comparer(lhs);
|
||||
@ -183,7 +183,7 @@ struct Comparer<T, typename enable_if<IsVisitable<T>::value>::type>
|
||||
private:
|
||||
template <typename TComparer>
|
||||
CompareResult accept(TComparer &comparer) {
|
||||
CompareResult reversedResult = rhs.accept(comparer);
|
||||
CompareResult reversedResult = rhs->accept(comparer);
|
||||
switch (reversedResult) {
|
||||
case COMPARE_RESULT_GREATER:
|
||||
return COMPARE_RESULT_LESS;
|
||||
|
@ -210,7 +210,7 @@ class VariantData {
|
||||
|
||||
void setString(String s) {
|
||||
ARDUINOJSON_ASSERT(s);
|
||||
if (s.isStatic())
|
||||
if (s.isLinked())
|
||||
setType(VALUE_IS_LINKED_STRING);
|
||||
else
|
||||
setType(VALUE_IS_OWNED_STRING);
|
||||
|
@ -73,9 +73,11 @@ inline T VariantData::asFloat() const {
|
||||
inline String VariantData::asString() const {
|
||||
switch (type()) {
|
||||
case VALUE_IS_LINKED_STRING:
|
||||
return String(_content.asString.data, _content.asString.size, true);
|
||||
return String(_content.asString.data, _content.asString.size,
|
||||
String::Linked);
|
||||
case VALUE_IS_OWNED_STRING:
|
||||
return String(_content.asString.data, _content.asString.size, false);
|
||||
return String(_content.asString.data, _content.asString.size,
|
||||
String::Copied);
|
||||
default:
|
||||
return String();
|
||||
}
|
||||
@ -166,7 +168,7 @@ inline VariantConstRef operator|(VariantConstRef preferedValue,
|
||||
|
||||
// Out of class definition to avoid #1560
|
||||
inline bool VariantRef::set(char value) const {
|
||||
return set<signed char>(value);
|
||||
return set(static_cast<signed char>(value));
|
||||
}
|
||||
|
||||
// TODO: move somewhere else
|
||||
@ -174,7 +176,7 @@ template <typename TAdaptedString, typename TCallback>
|
||||
bool CopyStringStoragePolicy::store(TAdaptedString str, MemoryPool *pool,
|
||||
TCallback callback) {
|
||||
const char *copy = pool->saveString(str);
|
||||
String storedString(copy, str.size(), false);
|
||||
String storedString(copy, str.size(), String::Copied);
|
||||
callback(storedString);
|
||||
return copy != 0;
|
||||
}
|
||||
|
@ -119,7 +119,7 @@ class VariantRef : public VariantRefBase<VariantData>,
|
||||
ARDUINOJSON_DEPRECATED(
|
||||
"Support for char is deprecated, use int8_t or uint8_t instead")
|
||||
as() const {
|
||||
return as<signed char>();
|
||||
return static_cast<char>(as<signed char>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -265,7 +265,7 @@ class VariantConstRef : public VariantRefBase<const VariantData>,
|
||||
ARDUINOJSON_DEPRECATED(
|
||||
"Support for char is deprecated, use int8_t or uint8_t instead")
|
||||
as() const {
|
||||
return as<signed char>();
|
||||
return static_cast<char>(as<signed char>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -78,7 +78,7 @@ class VariantSlot {
|
||||
|
||||
void setKey(String k) {
|
||||
ARDUINOJSON_ASSERT(k);
|
||||
if (k.isStatic())
|
||||
if (k.isLinked())
|
||||
_flags &= VALUE_MASK;
|
||||
else
|
||||
_flags |= OWNED_KEY_BIT;
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ARDUINOJSON_VERSION "6.19.1"
|
||||
#define ARDUINOJSON_VERSION "6.19.4"
|
||||
#define ARDUINOJSON_VERSION_MAJOR 6
|
||||
#define ARDUINOJSON_VERSION_MINOR 19
|
||||
#define ARDUINOJSON_VERSION_REVISION 1
|
||||
#define ARDUINOJSON_VERSION_REVISION 4
|
||||
|
Reference in New Issue
Block a user