Compare commits

...

20 Commits

Author SHA1 Message Date
67b6797b6d Set version to 6.19.4 2022-04-05 10:53:11 +02:00
8d9504239b Fix comparisons operators with const JsonDocument& 2022-04-05 10:12:17 +02:00
bf5d0c790c Add implicit conversion from JsonDocument to JsonVariant 2022-03-23 17:17:35 +01:00
f4379f97ae Format code with clang-format 2022-03-23 17:17:35 +01:00
3dc67c5663 Add memoryUsage() to ElementProxy and MemberProxy (fixes #1730) 2022-03-19 12:11:40 +01:00
47f90b02c3 CI: run apt-get update before installing g++-multilib 2022-03-09 08:33:26 +01:00
27c924746b CI: run apt-get update before installing valgrind 2022-03-08 19:09:56 +01:00
7abf875071 Set version to 6.19.3 2022-03-08 17:24:14 +01:00
e3e375f5cd MessagePack: serialize round floats as integers (fixes #1718) 2022-02-28 19:38:26 +01:00
ff06292d74 Fix -Wsign-conversion -funsigned-char (fixes #1715) 2022-02-28 10:00:12 +01:00
c1278797f2 CI: use -funsigned-char in one GCC build (issue #1715) 2022-02-28 09:50:32 +01:00
421ecec0dd Tests: trim trailing white spaces 2022-02-25 10:28:42 +01:00
89ed54362b Fix -Wsign-conversion on GCC 8 (fixes #1715) 2022-02-25 10:28:42 +01:00
986f77fa15 Tests: link with -static on MinGW 2022-02-25 10:28:22 +01:00
f831ed395d Fix JsonString operator == and != for non-zero-terminated string 2022-02-17 17:33:16 +01:00
a880614a75 Fix call of overloaded 'String(const char*, int)' is ambiguous 2022-02-17 17:33:16 +01:00
ef8379df1b Set version to 6.19.2 2022-02-14 09:06:06 +01:00
702f8c2e2f Fix cannot convert 'pgm_p' to 'const void*' (fixes #1707) 2022-02-06 11:14:23 +01:00
6806393285 Wandbox: update compiler version 2022-01-14 09:23:12 +01:00
dea8387586 Publish script: don't stop if wandbox fails 2022-01-14 09:22:55 +01:00
55 changed files with 427 additions and 189 deletions

View File

@ -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

View File

@ -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)
-------

View File

@ -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)

View File

@ -7,8 +7,8 @@
[![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)
[![LGTM Grade](https://img.shields.io/lgtm/grade/cpp/github/bblanchon/ArduinoJson?label=quality&logo=lgtm)](https://lgtm.com/projects/g/bblanchon/ArduinoJson/)
[![Coveralls branch](https://img.shields.io/coveralls/github/bblanchon/ArduinoJson/6.x?logo=coveralls)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
[![Arduino Library Manager](https://img.shields.io/static/v1?label=Arduino&message=v6.19.1&logo=arduino&logoColor=white&color=blue)](https://www.ardu-badge.com/ArduinoJson/6.19.1)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/bblanchon/library/ArduinoJson.svg?version=6.19.1)](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.19.1)
[![Arduino Library Manager](https://img.shields.io/static/v1?label=Arduino&message=v6.19.4&logo=arduino&logoColor=white&color=blue)](https://www.ardu-badge.com/ArduinoJson/6.19.4)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/bblanchon/library/ArduinoJson.svg?version=6.19.4)](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.19.4)
[![GitHub stars](https://img.shields.io/github/stars/bblanchon/ArduinoJson?style=flat&logo=github)](https://github.com/bblanchon/ArduinoJson/stargazers)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/bblanchon?logo=github)](https://github.com/sponsors/bblanchon)

View File

@ -1,4 +1,4 @@
version: 6.19.1.{build}
version: 6.19.4.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022

View File

@ -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()

View File

@ -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"

View File

@ -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"

View File

@ -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");

View File

@ -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");

View File

@ -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));

View File

@ -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}");

View File

@ -5,6 +5,7 @@
add_executable(JsonDocumentTests
add.cpp
BasicJsonDocument.cpp
cast.cpp
compare.cpp
containsKey.cpp
createNested.cpp

View File

@ -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);
}
}

View File

@ -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\"]");
}

View File

@ -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\"}");
}

View 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\"}");
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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);

View File

@ -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");

View File

@ -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\")") {

View File

@ -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);

View File

@ -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");

View File

@ -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");
}
}

View File

@ -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
)

View 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);
}

View File

@ -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));

View File

@ -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);

View File

@ -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");
}
}

View File

@ -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"

View File

@ -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++.

View File

@ -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);

View File

@ -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);

View File

@ -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:

View File

@ -481,7 +481,7 @@ class MsgPackDeserializer {
T size;
if (!readInteger(size))
return false;
return skipBytes(size + 1);
return skipBytes(size + 1U);
}
MemoryPool *_pool;

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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());
}
}

View File

@ -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

View File

@ -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:

View File

@ -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 {

View File

@ -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));
}

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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>

View File

@ -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;

View File

@ -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