Compare commits

..

96 Commits

Author SHA1 Message Date
53f858f55c Remove SlotData 2025-06-02 15:57:34 +02:00
6cdd59034d Clang-format 2025-05-31 18:35:36 +02:00
6ccac18fd4 Fix comments 2025-05-31 18:34:07 +02:00
3f6fff7d0c Fix JsonVariantTests 2025-05-31 16:29:46 +00:00
cc2fea45cd All tests pass 2025-05-31 16:47:03 +02:00
4159af66eb JsonDeserializerTests pass 2025-05-31 16:41:09 +02:00
05942b620a JsonVariantTests pass 2025-05-31 16:38:36 +02:00
23c73b061e JsonArrayTests pass 2025-05-31 16:37:08 +02:00
c2e756d942 ResourceManagerTests pass 2025-05-31 16:31:31 +02:00
94aacf873e Replace extension with eight-byte values 2025-05-31 16:20:08 +02:00
bd2dccda0e Store static strings in a dedicated pool
Because a slot id is smaller than a pointer, this change will ultimately allow reducing the slot size.
2025-05-21 11:09:44 +02:00
411424b74e CI: upgrade clang-tidy 2025-05-20 20:55:01 +02:00
5e5c287978 CI: upgrade Clang versions 2025-05-20 18:24:46 +02:00
377cf63075 CI: upgrade runner to ubuntu-22.04 2025-05-20 14:48:42 +02:00
3252013509 Set version to 7.4.1 2025-04-11 15:43:42 +02:00
deab127a2f Fix crash with tiny Flash strings (issue #2170) 2025-04-11 10:23:43 +02:00
96281de682 Set version to 7.4.0 2025-04-09 14:49:13 +02:00
f0e84e4933 Fix support for const char[]
Fixes #2166
2025-04-09 08:55:09 +02:00
91397f9f06 Optimize storage of tiny strings (up to 3 characters) 2025-04-09 08:55:08 +02:00
7f75985e47 Change StringBuffer::save() to take a VariantData* 2025-02-28 10:05:50 +01:00
05b68fc7cc Change StringBuilder::save() to take a VariantData* 2025-02-28 09:59:46 +01:00
b06cee8f4d Remove the overload of setString() for StringNode 2025-02-28 09:23:56 +01:00
e03d8ae885 Set version to 7.3.1 2025-02-27 19:35:14 +01:00
cb1dcfa5e4 Reduce code size 2025-02-27 11:13:50 +01:00
67dd3120e6 Fix conversion from static string to number 2025-02-27 11:01:51 +01:00
9f3cf04415 Remove useless null check 2025-02-24 16:40:42 +01:00
01e49b33b7 Update copyright year 2025-02-24 15:18:26 +01:00
8f7e793f37 Set version to 7.3.0 2024-12-29 17:15:57 +01:00
254fa5712a Update the release scripts to include the breaking changes section 2024-12-29 16:38:41 +01:00
de05814294 Move public facing SFINAEs to template declarations 2024-12-23 17:44:52 +01:00
e33e78d202 Rename undocumented JsonString::isLinked() to isStatic() 2024-11-26 14:32:50 +01:00
ed5f890d28 Replace JsonString::Ownership with bool 2024-11-26 14:32:36 +01:00
8931651317 JsonString: change default ownership to Copied 2024-11-26 10:10:52 +01:00
c078957282 Remove unnecessary universal references 2024-11-25 12:25:59 +01:00
cf084ae6b4 JsonString: move adapter class in the same file 2024-11-25 12:25:59 +01:00
f02fcc96a2 JsonArray: remove redundant tests 2024-11-25 12:25:59 +01:00
594dc707cb Change string copy policy: only string literal are stored by pointer 2024-11-25 12:25:59 +01:00
5f8e3c0f0f Polyfills: test remove_cv 2024-11-25 12:25:59 +01:00
afc0a29c2c Polyfills: add decay 2024-11-25 12:25:59 +01:00
a256ec7fff RamString: use a bitfield to reduce size 2024-11-25 12:25:59 +01:00
019e8326b7 Implement JsonString from RamString 2024-11-25 11:13:39 +01:00
bee1095042 Merge all RAM string adapters 2024-11-25 10:46:35 +01:00
de59dce527 Fix typo in comments 2024-11-25 10:46:34 +01:00
57a9c50b38 Make ElementProxy and MemberProxy non-copyable 2024-11-25 10:46:21 +01:00
5e7653b36a Store adapted string in MemberProxy 2024-11-17 15:46:46 +01:00
8110058729 Fix support for NUL characters in deserializeJson() 2024-11-17 15:40:21 +01:00
7946ebe1a3 Wandbox: compile with gcc-head 2024-11-15 09:13:00 +01:00
f9fe8557f1 Set version to 7.2.1 2024-11-15 09:05:29 +01:00
e007d71b4f Fix operator[](variant) ignoring NUL characters 2024-11-14 14:56:47 +01:00
67a512a923 Clean up tests of adaptString() 2024-11-14 14:22:51 +01:00
9cf4f3871d Remove unused overload of stringCompare() and stringEquals() 2024-11-14 14:17:13 +01:00
31253dbe13 Add more tests with VLAs 2024-11-08 09:37:49 +01:00
1110d62128 Fix VLA support in JsonDocument::set() 2024-11-08 09:37:23 +01:00
c6c0649d70 Replace typedef with using 2024-10-23 15:54:08 +02:00
61ec2c4f95 Reduce boilerplate for failing build tests 2024-10-23 15:47:59 +02:00
0dd6231b3f Forbid deserializeJson(JsonArray|JsonObject, ...)
Closes #2135
2024-10-23 15:41:34 +02:00
20219d74f0 Tests: don't link FailingBuilds with catch 2024-10-23 15:04:52 +02:00
64cbaa6ff7 Remove the workaround for particle-iot/particle-cli#716
This reverts commit 1404b1ef70.
2024-09-28 09:58:48 +02:00
2512993617 Replace problematic symbol in idf_component.yml
Fixes #2131
2024-09-26 09:18:23 +02:00
48ee4a178b Use a const reference in is_convertible() 2024-09-21 09:22:12 +02:00
cd4b2b2463 Set version to 7.2.0 2024-09-18 10:48:50 +02:00
f806a42cc2 Add support for escape sequence \'
Fixes #2124
2024-09-17 10:33:47 +02:00
c1a507c158 Set ARDUINOJSON_POOL_CAPACITY from ARDUINOJSON_SLOT_ID_SIZE
This avoids the integer overflow when `ARDUINOJSON_SLOT_ID_SIZE=1` on 64-bit architectures.
2024-09-11 21:08:51 +02:00
a1809d0f31 Replace sizeof(VariantData) with sizeof(SlotData) 2024-09-10 18:26:58 +02:00
d92eee8736 Deprecate containsKey() in favor of doc["key"].is<T>()
See #2121
2024-09-06 17:32:09 +02:00
dd1d96e28f Group calls to getExtension()
This slightly reduces the code size.
2024-09-05 12:15:10 +02:00
3b64197869 MsgPackDeserializer: check extension allocation result 2024-09-04 14:34:02 +02:00
1f7a3f3174 JsonDeserializer: use float when the value has few digits 2024-09-04 14:33:14 +02:00
fd6314e132 Move some numbers tests to use_double_0.cpp 2024-09-04 14:29:19 +02:00
e4e2557b76 Move test of decomposeFloat() 2024-09-03 13:27:39 +02:00
3b6bf45b8a Serialize float with less decimal places than double 2024-09-03 11:44:35 +02:00
65ba36622c Add VariantType 2024-09-02 17:56:19 +02:00
33452c1f37 Test JsonVariant::as<T>() with extension slots 2024-08-27 16:08:47 +02:00
ee02c0d573 Test extension slot allocation failure 2024-08-27 16:08:47 +02:00
0278e94fce Set ARDUINOJSON_USE_DOUBLE to 0 by default on 8-bit architectures 2024-08-27 15:46:12 +02:00
7643dadaec WIP 2024-08-27 14:40:24 +02:00
c0bebe35f1 Improve message when user forgets third arg of serializeJson() et al.
See #1449, #1491, #1543, #1665, and #2122
2024-08-27 12:22:53 +02:00
b5bcb37657 Use enable_if_t instead of enable_if 2024-08-27 10:00:09 +02:00
b4a5b053ca Merge conf_test for linux and windows
This reverts commit 83516e1740.
2024-08-27 08:03:55 +02:00
e297932a98 Store 64-bit numbers (double and long long) in an additional slot
This change allows slots to be twices maller on 32-bit architectures.
See #1650 and #2103
2024-08-27 08:02:09 +02:00
e682337655 Release VariantData resources explicitly before setting value 2024-08-26 15:09:56 +02:00
4ada3f849c Decouple parseNumber() from VariantData 2024-08-25 16:46:55 +02:00
5dd203bca4 Rename SlotWithId to Slot 2024-08-25 15:04:39 +02:00
362201241f Make MemoryPool generic 2024-08-25 14:58:23 +02:00
2be24eded8 Rename SlotWithId::slot() and VariantWithId::data() to ptr() 2024-08-25 14:54:45 +02:00
4327f72140 Remove VariantSlot 2024-08-25 14:45:59 +02:00
f7f1b9745d Hide FreeSlot in MemoryPoolList 2024-08-25 14:39:18 +02:00
cec18177b0 Move sizeofArray() and sizeofObject() 2024-08-25 14:36:38 +02:00
f2894552f2 Rename VariantPool to MemoryPool 2024-08-25 14:36:38 +02:00
d3721cb122 Make VariantSlot a union. Include next slot id in VariantData 2024-08-24 19:20:39 +02:00
ab72bb8601 Rename flags_ to type_ 2024-08-24 11:18:21 +02:00
09c89dcacf Store object members with two slots: one for the key and one for the value 2024-08-24 10:45:51 +02:00
a2b09bfbd2 Remove unused code 2024-08-23 15:28:44 +02:00
386105be90 Allocate slot before key 2024-08-23 15:27:46 +02:00
83516e1740 Split conf_test between linux and windows 2024-08-23 15:24:45 +02:00
bf99aeedb1 Add @LArkema to the list of sponsors 💖 2024-07-02 10:27:36 +02:00
392 changed files with 4699 additions and 2731 deletions

View File

@ -93,44 +93,40 @@ jobs:
fail-fast: false
matrix:
include:
- clang: "3.9"
runner: ubuntu-20.04
archive: bionic
- clang: "4.0"
runner: ubuntu-20.04
archive: bionic
- clang: "5.0"
runner: ubuntu-20.04
archive: bionic
- clang: "6.0"
runner: ubuntu-20.04
archive: bionic
- clang: "7"
runner: ubuntu-20.04
runner: ubuntu-22.04
archive: focal
- clang: "8"
cxxflags: -fsanitize=leak -fno-sanitize-recover=all
runner: ubuntu-20.04
runner: ubuntu-22.04
archive: focal
- clang: "9"
cxxflags: -fsanitize=undefined -fno-sanitize-recover=all
runner: ubuntu-20.04
runner: ubuntu-22.04
archive: focal
- clang: "10"
cxxflags: -fsanitize=address -fno-sanitize-recover=all
runner: ubuntu-20.04
runner: ubuntu-22.04
archive: focal
- clang: "11"
runner: ubuntu-22.04
- clang: "12"
runner: ubuntu-22.04
- clang: "13"
runner: ubuntu-22.04
- clang: "14"
runner: ubuntu-22.04
- clang: "15"
runner: ubuntu-22.04
runs-on: ${{ matrix.runner }}
- clang: 14
- clang: 15
- clang: 16
- clang: 17
- clang: 18
- clang: 19
runs-on: ${{ matrix.runner || 'ubuntu-latest' }}
steps:
- name: Add archive repositories
if: matrix.archive
run: |
sudo gpg --keyserver keyserver.ubuntu.com --recv-keys 3B4FE6ACC0B21F32
sudo gpg --export 3B4FE6ACC0B21F32 | sudo tee /etc/apt/trusted.gpg.d/ubuntu-keyring.gpg > /dev/null
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ ${{ matrix.archive }} main'
sudo add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ ${{ matrix.archive }} universe'
- name: Install Clang ${{ matrix.clang }}
@ -138,10 +134,9 @@ jobs:
sudo apt-get update
sudo apt-get install -y clang-${{ matrix.clang }}
- name: Install libc++ ${{ matrix.clang }}
if: matrix.clang >= 11
run: sudo apt-get install -y libc++-${{ matrix.clang }}-dev libc++abi-${{ matrix.clang }}-dev
- name: Install libunwind ${{ matrix.clang }}
if: matrix.clang == 12 # dependency is missing in Ubuntu 22.04
if: matrix.clang == 12 # dependency is missing in Ubuntu 22.04
run: sudo apt-get install -y libunwind-${{ matrix.clang }}-dev
- name: Checkout
uses: actions/checkout@v4
@ -163,7 +158,7 @@ jobs:
conf_test:
name: Test configuration on Linux
needs: [gcc, clang]
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Install
run: |
@ -257,7 +252,7 @@ jobs:
board: arduino:avr:uno
- core: arduino:samd
board: arduino:samd:mkr1000
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
@ -403,7 +398,7 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Install Particle CLI
run: sudo npm install -g particle-cli particle-usb
run: sudo npm install -g particle-cli
- name: Login to Particle
run: particle login -t "${{ secrets.PARTICLE_TOKEN }}"
- name: Compile
@ -412,7 +407,7 @@ jobs:
arm:
name: GCC for ARM processor
needs: gcc
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Install
run: |
@ -431,7 +426,7 @@ jobs:
coverage:
needs: gcc
name: Coverage
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Install
run: sudo apt-get install -y lcov ninja-build
@ -463,7 +458,7 @@ jobs:
valgrind:
needs: gcc
name: Valgrind
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Install
run: |
@ -485,24 +480,24 @@ jobs:
clang-tidy:
needs: clang
name: Clang-Tidy
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- name: Install
run: sudo apt-get install -y clang-tidy cmake ninja-build
run: sudo apt-get install -y clang-tidy libc++-dev libc++abi-dev
- name: Checkout
uses: actions/checkout@v4
- name: Configure
run: cmake -G Ninja -DCMAKE_CXX_CLANG_TIDY="clang-tidy-10;--warnings-as-errors=*" -DCMAKE_BUILD_TYPE=Debug .
run: cmake -G Ninja -DCMAKE_CXX_CLANG_TIDY="clang-tidy;--warnings-as-errors=*" -DCMAKE_BUILD_TYPE=Debug .
env:
CC: clang-10
CXX: clang++-10
CC: clang
CXX: clang++
- name: Check
run: cmake --build . -- -k 0
amalgamate:
needs: gcc
name: Amalgamate ArduinoJson.h
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4
@ -578,7 +573,7 @@ jobs:
codeql:
name: CodeQL
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
needs: gcc
permissions:
@ -587,20 +582,20 @@ jobs:
security-events: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: cpp
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: cpp
- name: Build
run: |
cmake -DCMAKE_BUILD_TYPE=Debug .
cmake --build .
- name: Build
run: |
cmake -DCMAKE_BUILD_TYPE=Debug .
cmake --build .
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:cpp"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:cpp"

View File

@ -8,7 +8,7 @@ on:
jobs:
release:
name: Create release
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- name: Set variables
id: init
@ -21,7 +21,13 @@ jobs:
id: body
run: |
FILENAME=RELEASE.md
extras/scripts/get-release-body.sh ${{ steps.init.outputs.tag }} CHANGELOG.md | tee $FILENAME
tee $FILENAME <<END
## Changes
$(extras/scripts/extract_changes.awk CHANGELOG.md)
[View version history](https://github.com/bblanchon/ArduinoJson/blob/${{ steps.init.outputs.tag }}/CHANGELOG.md)
END
echo "filename=$FILENAME" >> $GITHUB_OUTPUT
- name: Amalgamate ArduinoJson.h
id: amalgamate_h
@ -61,7 +67,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Install
run: npm install -g particle-cli particle-usb
run: npm install -g particle-cli
- name: Checkout
uses: actions/checkout@v4
- name: Login

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include "src/ArduinoJson.h"

View File

@ -1,6 +1,143 @@
ArduinoJson: change log
=======================
HEAD
----
* Optimize storage of static strings
> ### BREAKING CHANGES
>
> Static string cannot contain NUL characters anymore (they could since 7.3.0).
> This is an extremely rare case, so you probably won't be affected.
>
> For example, the following code produces different output in 7.3 and 7.4:
>
> ```cpp
> JsonDocument doc;
> doc["a\0b"] = "c\0d";
> serializeJson(doc, Serial);
> // With Arduino 7.3 -> {"a\u0000b":"c\u0000d"}
> // With Arduino 7.4 -> {"a":"c"}
> ```
>
> `JsonString` contructor now only accepts two arguments, not three.
> If your code uses `JsonString` to store a string as a pointer, you must remove the size argument.
>
> For example, if you have something like this:
>
> ```cpp
> doc["key"] = JsonString(str.c_str(), str.size(), true);
> ```
>
> You must replace with either:
>
> ```cpp
> doc["key"] = JsonString(str.c_str(), true); // store as pointer, cannot contain NUL characters
> doc["key"] = JsonString(str.c_str(), str.size()); // store by copy, NUL characters allowed
> doc["key"] = str; // same as previous line for supported string classes (`String`, `std::string`, etc.)
> ```
v7.4.1 (2025-04-11)
------
* Fix crash with tiny Flash strings (issue #2170)
v7.4.0 (2025-04-09)
------
* Optimize storage of tiny strings (up to 3 characters)
* Fix support for `const char[]` (issue #2166)
v7.3.1 (2025-02-27)
------
* Fix conversion from static string to number
* Slightly reduce code size
v7.3.0 (2024-12-29)
------
* Fix support for NUL characters in `deserializeJson()`
* Make `ElementProxy` and `MemberProxy` non-copyable
* Change string copy policy: only string literal are stored by pointer
* `JsonString` is now stored by copy, unless specified otherwise
* Replace undocumented `JsonString::Ownership` with `bool`
* Rename undocumented `JsonString::isLinked()` to `isStatic()`
* Move public facing SFINAEs to template declarations
> ### BREAKING CHANGES
>
> In previous versions, `MemberProxy` (the class returned by `operator[]`) could lead to dangling pointers when used with a temporary string.
> To prevent this issue, `MemberProxy` and `ElementProxy` are now non-copyable.
>
> Your code is likely to be affected if you use `auto` to store the result of `operator[]`. For example, the following line won't compile anymore:
>
> ```cpp
> auto value = doc["key"];
> ```
>
> To fix the issue, you must append either `.as<T>()` or `.to<T>()`, depending on the situation.
>
> For example, if you are extracting values from a JSON document, you should update like this:
>
> ```diff
> - auto config = doc["config"];
> + auto config = doc["config"].as<JsonObject>();
> const char* name = config["name"];
> ```
>
> However, if you are building a JSON document, you should update like this:
>
> ```diff
> - auto config = doc["config"];
> + auto config = doc["config"].to<JsonObject>();
> config["name"] = "ArduinoJson";
> ```
v7.2.1 (2024-11-15)
------
* Forbid `deserializeJson(JsonArray|JsonObject, ...)` (issue #2135)
* Fix VLA support in `JsonDocument::set()`
* Fix `operator[](variant)` ignoring NUL characters
v7.2.0 (2024-09-18)
------
* Store object members with two slots: one for the key and one for the value
* Store 64-bit numbers (`double` and `long long`) in an additional slot
* Reduce the slot size (see table below)
* Improve message when user forgets third arg of `serializeJson()` et al.
* Set `ARDUINOJSON_USE_DOUBLE` to `0` by default on 8-bit architectures
* Deprecate `containsKey()` in favor of `doc["key"].is<T>()`
* Add support for escape sequence `\'` (issue #2124)
| Architecture | before | after |
|--------------|----------|----------|
| 8-bit | 8 bytes | 6 bytes |
| 32-bit | 16 bytes | 8 bytes |
| 64-bit | 24 bytes | 16 bytes |
> ### BREAKING CHANGES
>
> After being on the death row for years, the `containsKey()` method has finally been deprecated.
> You should replace `doc.containsKey("key")` with `doc["key"].is<T>()`, which not only checks that the key exists but also that the value is of the expected type.
>
> ```cpp
> // Before
> if (doc.containsKey("value")) {
> int value = doc["value"];
> // ...
> }
>
> // After
> if (doc["value"].is<int>()) {
> int value = doc["value"];
> // ...
> }
> ```
v7.1.0 (2024-06-27)
------

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
cmake_minimum_required(VERSION 3.15)
@ -10,7 +10,7 @@ if(ESP_PLATFORM)
return()
endif()
project(ArduinoJson VERSION 7.1.0)
project(ArduinoJson VERSION 7.4.1)
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)

View File

@ -1,7 +1,7 @@
The MIT License (MIT)
---------------------
Copyright © 2014-2024, Benoit BLANCHON
Copyright © 2014-2025, Benoit BLANCHON
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -80,7 +80,7 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
* Continuously tested on
* [Visual Studio 2017, 2019, 2022](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/7.x)
* [GCC 4.8, 5, 6, 7, 8, 9, 10, 11, 12](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
* [Clang 3.9, 4.0, 5.0, 6.0, 7, 8, 9, 10, 11, 12, 13, 14, 15](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
* [Clang 7 to 19](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
* Passes all default checks of [clang-tidy](https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/)
* Well documented
@ -148,6 +148,9 @@ ArduinoJson is thankful to its sponsors. Please give them a visit; they deserve
<a href="https://github.com/1technophile" rel="sponsored">
<img alt="1technophile" src="https://avatars.githubusercontent.com/u/12672732?s=40&v=4">
</a>
<a href="https://github.com/LArkema" rel="sponsored">
<img alt="LArkema" src="https://avatars.githubusercontent.com/u/38381313?s=40&v=4">
</a>
</p>
If you run a commercial project that embeds ArduinoJson, think about [sponsoring the library's development](https://github.com/sponsors/bblanchon): it ensures the code that your products rely on stays actively maintained. It can also give your project some exposure to the makers' community.

View File

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

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to store your project configuration in a file.

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to use DeserializationOption::Filter

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to generate a JSON document with ArduinoJson.

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to parse a JSON document in an HTTP response.

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to deserialize a JSON document with ArduinoJson.

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to implement an HTTP server that sends a JSON document

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to send a JSON document to a UDP socket.

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to deserialize a MessagePack document with

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows the different ways you can use Flash strings with

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows the different ways you can use String with ArduinoJson.

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
cmake_minimum_required(VERSION 3.5)

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
idf_component_register(

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -6,12 +6,13 @@ static_assert(ARDUINOJSON_USE_LONG_LONG == 0, "ARDUINOJSON_USE_LONG_LONG");
static_assert(ARDUINOJSON_SLOT_ID_SIZE == 1, "ARDUINOJSON_SLOT_ID_SIZE");
static_assert(ARDUINOJSON_POOL_CAPACITY == 16, "ARDUINOJSON_POOL_CAPACITY");
static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(ARDUINOJSON_USE_DOUBLE == 0, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 8,
"sizeof(VariantSlot)");
static_assert(sizeof(ArduinoJson::detail::VariantData) == 6, "slot size");
void setup() {}
void loop() {}

View File

@ -4,12 +4,13 @@ static_assert(ARDUINOJSON_USE_LONG_LONG == 1, "ARDUINOJSON_USE_LONG_LONG");
static_assert(ARDUINOJSON_SLOT_ID_SIZE == 2, "ARDUINOJSON_SLOT_ID_SIZE");
static_assert(ARDUINOJSON_POOL_CAPACITY == 128, "ARDUINOJSON_POOL_CAPACITY");
static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 16,
"sizeof(VariantSlot)");
static_assert(sizeof(VariantData) == 8, "slot size");
void setup() {}
void loop() {}

View File

@ -4,11 +4,12 @@ static_assert(ARDUINOJSON_USE_LONG_LONG == 1, "ARDUINOJSON_USE_LONG_LONG");
static_assert(ARDUINOJSON_SLOT_ID_SIZE == 4, "ARDUINOJSON_SLOT_ID_SIZE");
static_assert(ARDUINOJSON_POOL_CAPACITY == 256, "ARDUINOJSON_POOL_CAPACITY");
static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 24,
"sizeof(VariantSlot)");
static_assert(sizeof(ArduinoJson::detail::VariantData) == 16, "slot size");
int main() {}

View File

@ -4,11 +4,12 @@ static_assert(ARDUINOJSON_USE_LONG_LONG == 1, "ARDUINOJSON_USE_LONG_LONG");
static_assert(ARDUINOJSON_SLOT_ID_SIZE == 2, "ARDUINOJSON_SLOT_ID_SIZE");
static_assert(ARDUINOJSON_POOL_CAPACITY == 128, "ARDUINOJSON_POOL_CAPACITY");
static_assert(ARDUINOJSON_LITTLE_ENDIAN == 1, "ARDUINOJSON_LITTLE_ENDIAN");
static_assert(ARDUINOJSON_USE_DOUBLE == 1, "ARDUINOJSON_USE_DOUBLE");
static_assert(sizeof(ArduinoJson::detail::VariantSlot) == 16,
"sizeof(VariantSlot)");
static_assert(sizeof(ArduinoJson::detail::VariantData) == 8, "slot size");
int main() {}

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
set(CMAKE_CXX_STANDARD 11)

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
// This file is NOT use by Google's OSS fuzz

View File

@ -0,0 +1,29 @@
#!/usr/bin/awk -f
# Start echoing after the first list item
/\* / {
STARTED=1
EMPTY_LINE=0
}
# Remember if we have seen an empty line
/^[[:space:]]*$/ {
EMPTY_LINE=1
}
# Exit when seeing a new version number
/^v[[:digit:]]/ {
if (STARTED) exit
}
# Print if the line is not empty
# and restore the empty line we have skipped
!/^[[:space:]]*$/ {
if (STARTED) {
if (EMPTY_LINE) {
print ""
EMPTY_LINE=0
}
print
}
}

View File

@ -1,14 +0,0 @@
#!/bin/bash
set -eu
TAG="$1"
CHANGELOG="$2"
cat << END
## Changes
$(awk '/\* /{ FOUND=1 } /^[[:space:]]*$/ { if(FOUND) exit } { if(FOUND) print }' "$CHANGELOG")
[View version history](https://github.com/bblanchon/ArduinoJson/blob/$TAG/CHANGELOG.md)
END

View File

@ -14,5 +14,5 @@ date: '$(date +'%Y-%m-%d')'
$(extras/scripts/wandbox/publish.sh "$ARDUINOJSON_H")
---
$(awk '/\* /{ FOUND=1; print; next } { if (FOUND) exit}' "$CHANGELOG")
$(extras/scripts/extract_changes.awk "$CHANGELOG")
END

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to generate a JSON document with ArduinoJson.

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to deserialize a JSON document with ArduinoJson.

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
//
// This example shows how to generate a JSON document with ArduinoJson.

View File

@ -15,7 +15,7 @@ compile() {
"code":$(read_string "$FILE_PATH"),
"codes": [{"file":"ArduinoJson.h","code":$(read_string "$ARDUINOJSON_H")}],
"options": "warning,c++11",
"compiler": "gcc-5.5.0",
"compiler": "gcc-head",
"save": true
}
END

View File

@ -1,19 +1,22 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(catch)
link_libraries(ArduinoJson)
link_libraries(ArduinoJson catch)
# Failing builds should only link with ArduinoJson, not catch
add_subdirectory(FailingBuilds)
add_subdirectory(catch)
link_libraries(catch)
include_directories(Helpers)
add_subdirectory(Cpp17)
add_subdirectory(Cpp20)
add_subdirectory(Deprecated)
add_subdirectory(FailingBuilds)
add_subdirectory(IntegrationTests)
add_subdirectory(JsonArray)
add_subdirectory(JsonArrayConst)

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
if(MSVC_VERSION LESS 1910)

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
// we expect ArduinoJson.h to include <string_view>

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
if(MSVC_VERSION LESS 1910)

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
@ -46,7 +46,7 @@ TEST_CASE("BasicJsonDocument") {
deserializeJson(doc, "{\"hello\":\"world\"}");
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\"}");
doc.clear();
REQUIRE(allocatorLog == "ARAARDDD");
REQUIRE(allocatorLog == "AARARDDD");
}
SECTION("copy") {
@ -54,7 +54,7 @@ TEST_CASE("BasicJsonDocument") {
doc["hello"] = "world";
auto copy = doc;
REQUIRE(copy.as<std::string>() == "{\"hello\":\"world\"}");
REQUIRE(allocatorLog == "AA");
REQUIRE(allocatorLog == "AAAA");
}
SECTION("capacity") {

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
@ -16,9 +16,10 @@ endif()
add_executable(DeprecatedTests
add.cpp
BasicJsonDocument.cpp
containsKey.cpp
createNestedArray.cpp
createNestedObject.cpp
BasicJsonDocument.cpp
DynamicJsonDocument.cpp
macros.cpp
memoryUsage.cpp

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -0,0 +1,246 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Literals.hpp"
TEST_CASE("JsonDocument::containsKey()") {
JsonDocument doc;
SECTION("returns true on object") {
doc["hello"] = "world";
REQUIRE(doc.containsKey("hello") == true);
}
SECTION("returns true when value is null") {
doc["hello"] = static_cast<const char*>(0);
REQUIRE(doc.containsKey("hello") == true);
}
SECTION("returns true when key is a std::string") {
doc["hello"] = "world";
REQUIRE(doc.containsKey("hello"_s) == true);
}
SECTION("returns false on object") {
doc["world"] = "hello";
REQUIRE(doc.containsKey("hello") == false);
}
SECTION("returns false on array") {
doc.add("hello");
REQUIRE(doc.containsKey("hello") == false);
}
SECTION("returns false on null") {
REQUIRE(doc.containsKey("hello") == false);
}
SECTION("supports JsonVariant") {
doc["hello"] = "world";
doc["key"] = "hello";
REQUIRE(doc.containsKey(doc["key"]) == true);
REQUIRE(doc.containsKey(doc["foo"]) == false);
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
doc["hello"] = "world";
REQUIRE(doc.containsKey(vla) == true);
}
#endif
}
TEST_CASE("MemberProxy::containsKey()") {
JsonDocument doc;
const auto& mp = doc["hello"];
SECTION("containsKey(const char*)") {
mp["key"] = "value";
REQUIRE(mp.containsKey("key") == true);
REQUIRE(mp.containsKey("key") == true);
}
SECTION("containsKey(std::string)") {
mp["key"] = "value";
REQUIRE(mp.containsKey("key"_s) == true);
REQUIRE(mp.containsKey("key"_s) == true);
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
mp["hello"] = "world";
REQUIRE(mp.containsKey(vla) == true);
}
#endif
}
TEST_CASE("JsonObject::containsKey()") {
JsonDocument doc;
JsonObject obj = doc.to<JsonObject>();
obj["hello"] = 42;
SECTION("returns true only if key is present") {
REQUIRE(false == obj.containsKey("world"));
REQUIRE(true == obj.containsKey("hello"));
}
SECTION("returns false after remove()") {
obj.remove("hello");
REQUIRE(false == obj.containsKey("hello"));
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("key is a VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
REQUIRE(true == obj.containsKey(vla));
}
#endif
SECTION("key is a JsonVariant") {
doc["key"] = "hello";
REQUIRE(true == obj.containsKey(obj["key"]));
REQUIRE(false == obj.containsKey(obj["hello"]));
}
SECTION("std::string") {
REQUIRE(true == obj.containsKey("hello"_s));
}
SECTION("unsigned char[]") {
unsigned char key[] = "hello";
REQUIRE(true == obj.containsKey(key));
}
}
TEST_CASE("JsonObjectConst::containsKey()") {
JsonDocument doc;
doc["hello"] = 42;
auto obj = doc.as<JsonObjectConst>();
SECTION("supports const char*") {
REQUIRE(false == obj.containsKey("world"));
REQUIRE(true == obj.containsKey("hello"));
}
SECTION("supports std::string") {
REQUIRE(false == obj.containsKey("world"_s));
REQUIRE(true == obj.containsKey("hello"_s));
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
REQUIRE(true == obj.containsKey(vla));
}
#endif
SECTION("supports JsonVariant") {
doc["key"] = "hello";
REQUIRE(true == obj.containsKey(obj["key"]));
REQUIRE(false == obj.containsKey(obj["hello"]));
}
}
TEST_CASE("JsonVariant::containsKey()") {
JsonDocument doc;
JsonVariant var = doc.to<JsonVariant>();
SECTION("returns false is unbound") {
CHECK_FALSE(JsonVariant().containsKey("hello"));
}
SECTION("containsKey(const char*)") {
var["hello"] = "world";
REQUIRE(var.containsKey("hello") == true);
REQUIRE(var.containsKey("world") == false);
}
SECTION("containsKey(std::string)") {
var["hello"] = "world";
REQUIRE(var.containsKey("hello"_s) == true);
REQUIRE(var.containsKey("world"_s) == false);
}
SECTION("containsKey(JsonVariant)") {
var["hello"] = "world";
var["key"] = "hello";
REQUIRE(var.containsKey(doc["key"]) == true);
REQUIRE(var.containsKey(doc["foo"]) == false);
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLAs") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
var["hello"] = "world";
REQUIRE(var.containsKey(vla) == true);
}
#endif
}
TEST_CASE("JsonVariantConst::containsKey()") {
JsonDocument doc;
doc["hello"] = "world";
JsonVariantConst var = doc.as<JsonVariant>();
SECTION("support const char*") {
REQUIRE(var.containsKey("hello") == true);
REQUIRE(var.containsKey("world") == false);
}
SECTION("support std::string") {
REQUIRE(var.containsKey("hello"_s) == true);
REQUIRE(var.containsKey("world"_s) == false);
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("supports VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "hello");
REQUIRE(true == var.containsKey(vla));
}
#endif
SECTION("support JsonVariant") {
doc["key"] = "hello";
REQUIRE(var.containsKey(var["key"]) == true);
REQUIRE(var.containsKey(var["foo"]) == false);
}
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,8 +1,12 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
macro(build_should_fail target)
macro(add_failing_build source_file)
get_filename_component(target ${source_file} NAME_WE)
add_executable(${target} ${source_file})
set_target_properties(${target}
PROPERTIES
EXCLUDE_FROM_ALL TRUE
@ -16,21 +20,13 @@ macro(build_should_fail target)
set_tests_properties(${target}
PROPERTIES
WILL_FAIL TRUE
LABELS "WillFail;Catch"
LABELS "WillFail"
)
endmacro()
add_executable(Issue978 Issue978.cpp)
build_should_fail(Issue978)
add_executable(read_long_long read_long_long.cpp)
build_should_fail(read_long_long)
add_executable(write_long_long write_long_long.cpp)
build_should_fail(write_long_long)
add_executable(variant_as_char variant_as_char.cpp)
build_should_fail(variant_as_char)
add_executable(assign_char assign_char.cpp)
build_should_fail(assign_char)
add_failing_build(Issue978.cpp)
add_failing_build(read_long_long.cpp)
add_failing_build(write_long_long.cpp)
add_failing_build(variant_as_char.cpp)
add_failing_build(assign_char.cpp)
add_failing_build(deserialize_object.cpp)

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -0,0 +1,12 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
// See issue #2135
int main() {
JsonObject obj;
deserializeJson(obj, "");
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#define ARDUINOJSON_USE_LONG_LONG 0

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#define ARDUINOJSON_USE_LONG_LONG 0

View File

@ -1,12 +1,12 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once
#include <ArduinoJson/Memory/Allocator.hpp>
#include <ArduinoJson/Memory/MemoryPool.hpp>
#include <ArduinoJson/Memory/StringBuilder.hpp>
#include <ArduinoJson/Memory/VariantPool.hpp>
#include <sstream>
@ -265,12 +265,20 @@ class TimebombAllocator : public ArduinoJson::Allocator {
} // namespace
inline size_t sizeofPoolList(size_t n = ARDUINOJSON_INITIAL_POOL_COUNT) {
return sizeof(ArduinoJson::detail::VariantPool) * n;
using namespace ArduinoJson::detail;
return sizeof(MemoryPool<VariantData>) * n;
}
template <typename T = ArduinoJson::detail::VariantData>
inline size_t sizeofPool(
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
return ArduinoJson::detail::VariantPool::slotsToBytes(n);
return ArduinoJson::detail::MemoryPool<T>::slotsToBytes(n);
}
inline size_t sizeofStaticStringPool(
ArduinoJson::detail::SlotCount n = ARDUINOJSON_POOL_CAPACITY) {
using namespace ArduinoJson::detail;
return MemoryPool<const char*>::slotsToBytes(n);
}
inline size_t sizeofStringBuffer(size_t iteration = 1) {

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once
@ -13,21 +13,21 @@ class Print {
virtual ~Print() {}
virtual size_t write(uint8_t) = 0;
virtual size_t write(const uint8_t *buffer, size_t size) = 0;
virtual size_t write(const uint8_t* buffer, size_t size) = 0;
size_t write(const char *str) {
size_t write(const char* str) {
if (!str)
return 0;
return write(reinterpret_cast<const uint8_t *>(str), strlen(str));
return write(reinterpret_cast<const uint8_t*>(str), strlen(str));
}
size_t write(const char *buffer, size_t size) {
return write(reinterpret_cast<const uint8_t *>(buffer), size);
size_t write(const char* buffer, size_t size) {
return write(reinterpret_cast<const uint8_t*>(buffer), size);
}
};
class Printable {
public:
virtual ~Printable() {}
virtual size_t printTo(Print &p) const = 0;
virtual size_t printTo(Print& p) const = 0;
};

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once
@ -10,5 +10,5 @@ class Stream // : public Print
public:
virtual ~Stream() {}
virtual int read() = 0;
virtual size_t readBytes(char *buffer, size_t length) = 0;
virtual size_t readBytes(char* buffer, size_t length) = 0;
};

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
add_executable(IntegrationTests

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
add_executable(JsonArrayTests
@ -13,7 +13,6 @@ add_executable(JsonArrayTests
nesting.cpp
remove.cpp
size.cpp
std_string.cpp
subscript.cpp
unbound.cpp
)

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
@ -8,7 +8,7 @@
#include "Allocators.hpp"
#include "Literals.hpp"
using ArduinoJson::detail::sizeofArray;
using namespace ArduinoJson::detail;
TEST_CASE("JsonArray::add(T)") {
SpyingAllocator spy;
@ -17,31 +17,114 @@ TEST_CASE("JsonArray::add(T)") {
SECTION("int") {
array.add(123);
REQUIRE(123 == array[0].as<int>());
REQUIRE(array[0].is<int>());
REQUIRE(array[0].is<double>());
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("double") {
array.add(123.45);
REQUIRE(123.45 == array[0].as<double>());
REQUIRE(array[0].is<double>());
REQUIRE_FALSE(array[0].is<bool>());
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool<VariantData>()),
Allocate(sizeofPool<EightByteValue>()),
});
}
SECTION("bool") {
array.add(true);
REQUIRE(true == array[0].as<bool>());
REQUIRE(array[0].as<bool>() == true);
REQUIRE(array[0].is<bool>());
REQUIRE_FALSE(array[0].is<int>());
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("string literal") {
array.add("hello");
REQUIRE(array[0].as<std::string>() == "hello");
REQUIRE(array[0].is<const char*>());
REQUIRE(array[0].is<int>() == false);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofStaticStringPool()),
});
}
SECTION("std::string") {
array.add("hello"_s);
REQUIRE(array[0].as<std::string>() == "hello");
REQUIRE(array[0].is<const char*>() == true);
REQUIRE(array[0].is<int>() == false);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
SECTION("const char*") {
const char* str = "hello";
array.add(str);
REQUIRE(str == array[0].as<std::string>());
REQUIRE(array[0].is<const char*>());
REQUIRE_FALSE(array[0].is<int>());
REQUIRE(array[0].as<std::string>() == "hello");
REQUIRE(array[0].as<const char*>() != str);
REQUIRE(array[0].is<const char*>() == true);
REQUIRE(array[0].is<int>() == false);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
SECTION("serialized(const char*)") {
array.add(serialized("{}"));
REQUIRE(doc.as<std::string>() == "[{}]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("{}")),
});
}
SECTION("serialized(char*)") {
array.add(serialized(const_cast<char*>("{}")));
REQUIRE(doc.as<std::string>() == "[{}]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("{}")),
});
}
SECTION("serialized(std::string)") {
array.add(serialized("{}"_s));
REQUIRE(doc.as<std::string>() == "[{}]");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("{}")),
});
}
SECTION("serialized(std::string)") {
array.add(serialized("\0XX"_s));
REQUIRE(doc.as<std::string>() == "[\0XX]"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString(" XX")),
});
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
@ -52,7 +135,12 @@ TEST_CASE("JsonArray::add(T)") {
array.add(vla);
REQUIRE("world"_s == array[0]);
strcpy(vla, "hello");
REQUIRE(array[0] == "world"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("hello")),
});
}
#endif
@ -99,61 +187,6 @@ TEST_CASE("JsonArray::add(T)") {
REQUIRE(str == array[0]);
}
SECTION("should not duplicate const char*") {
array.add("world");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("should duplicate char*") {
array.add(const_cast<char*>("world"));
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("should duplicate std::string") {
array.add("world"_s);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("should duplicate serialized(const char*)") {
array.add(serialized("{}"));
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("{}")),
});
}
SECTION("should duplicate serialized(char*)") {
array.add(serialized(const_cast<char*>("{}")));
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("{}")),
});
}
SECTION("should duplicate serialized(std::string)") {
array.add(serialized("{}"_s));
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("{}")),
});
}
SECTION("should duplicate serialized(std::string)") {
array.add(serialized("\0XX"_s));
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString(" XX")),
});
}
}
TEST_CASE("JsonArray::add<T>()") {

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
@ -68,6 +68,12 @@ TEST_CASE("JsonArray::remove()") {
REQUIRE(array[1] == 2);
}
SECTION("remove end()") {
array.remove(array.end());
REQUIRE(3 == array.size());
}
SECTION("In a loop") {
for (JsonArray::iterator it = array.begin(); it != array.end(); ++it) {
if (*it == 2)

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,34 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Literals.hpp"
static void eraseString(std::string& str) {
char* p = const_cast<char*>(str.c_str());
while (*p)
*p++ = '*';
}
TEST_CASE("std::string") {
JsonDocument doc;
JsonArray array = doc.to<JsonArray>();
SECTION("add()") {
std::string value("hello");
array.add(value);
eraseString(value);
REQUIRE("hello"_s == array[0]);
}
SECTION("operator[]") {
std::string value("world");
array.add("hello");
array[0] = value;
eraseString(value);
REQUIRE("world"_s == array[0]);
}
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
@ -59,15 +59,56 @@ TEST_CASE("JsonArray::operator[]") {
REQUIRE(false == array[0].is<int>());
}
SECTION("const char*") {
const char* str = "hello";
SECTION("string literal") {
array[0] = "hello";
array[0] = str;
REQUIRE(str == array[0].as<const char*>());
REQUIRE(array[0].as<std::string>() == "hello");
REQUIRE(true == array[0].is<const char*>());
REQUIRE(false == array[0].is<int>());
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("const char*") {
const char* str = "hello";
array[0] = str;
REQUIRE(array[0].as<std::string>() == "hello");
REQUIRE(true == array[0].is<const char*>());
REQUIRE(false == array[0].is<int>());
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("std::string") {
array[0] = "hello"_s;
REQUIRE(array[0].as<std::string>() == "hello");
REQUIRE(true == array[0].is<const char*>());
REQUIRE(false == array[0].is<int>());
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("VLA") {
size_t i = 16;
char vla[i];
strcpy(vla, "world");
array.add("hello");
array[0] = vla;
REQUIRE(array[0] == "world"_s);
}
#endif
SECTION("nested array") {
JsonDocument doc2;
JsonArray arr2 = doc2.to<JsonArray>();
@ -114,58 +155,11 @@ TEST_CASE("JsonArray::operator[]") {
REQUIRE(str == array[0]);
}
SECTION("should not duplicate const char*") {
array[0] = "world";
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
});
}
SECTION("should duplicate char*") {
array[0] = const_cast<char*>("world");
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("should duplicate std::string") {
array[0] = "world"_s;
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Allocate(sizeofString("world")),
});
}
SECTION("array[0].to<JsonObject>()") {
JsonObject obj = array[0].to<JsonObject>();
REQUIRE(obj.isNull() == false);
}
#ifdef HAS_VARIABLE_LENGTH_ARRAY
SECTION("set(VLA)") {
size_t i = 16;
char vla[i];
strcpy(vla, "world");
array.add("hello");
array[0].set(vla);
REQUIRE("world"_s == array[0]);
}
SECTION("operator=(VLA)") {
size_t i = 16;
char vla[i];
strcpy(vla, "world");
array.add("hello");
array[0] = vla;
REQUIRE("world"_s == array[0]);
}
#endif
SECTION("Use a JsonVariant as index") {
array[0] = 1;
array[1] = 2;

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
add_executable(JsonArrayConstTests

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2024, Benoit BLANCHON
# Copyright © 2014-2025, Benoit BLANCHON
# MIT License
add_executable(JsonDeserializerTests

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
@ -7,7 +7,7 @@
#include "Allocators.hpp"
using ArduinoJson::detail::sizeofArray;
using namespace ArduinoJson::detail;
TEST_CASE("deserialize JSON array") {
SpyingAllocator spy;
@ -69,14 +69,36 @@ TEST_CASE("deserialize JSON array") {
REQUIRE(arr[1] == 84);
}
SECTION("Double") {
SECTION("Float") {
DeserializationError err = deserializeJson(doc, "[4.2,1e2]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0] == 4.2);
REQUIRE(arr[1] == 1e2);
REQUIRE(arr[0].as<float>() == Approx(4.2f));
REQUIRE(arr[1] == 1e2f);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool()),
Reallocate(sizeofPool(), sizeofPool(2)),
});
}
SECTION("Double") {
DeserializationError err = deserializeJson(doc, "[4.2123456,-7E89]");
JsonArray arr = doc.as<JsonArray>();
REQUIRE(err == DeserializationError::Ok);
REQUIRE(2 == arr.size());
REQUIRE(arr[0].as<double>() == Approx(4.2123456));
REQUIRE(arr[1] == -7E89);
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofPool<VariantData>()),
Allocate(sizeofPool<EightByteValue>()),
Reallocate(sizeofPool<VariantData>(),
sizeofPool<VariantData>(2)),
Reallocate(sizeofPool<EightByteValue>(),
sizeofPool<EightByteValue>(2)),
});
}
SECTION("Unsigned long") {

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
@ -104,6 +104,8 @@ TEST_CASE("deserializeJson(MemberProxy)") {
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<std::string>() == "{\"hello\":\"world\",\"value\":[42]}");
REQUIRE(spy.log() == AllocatorLog{});
REQUIRE(spy.log() == AllocatorLog{
Allocate(sizeofStaticStringPool()),
});
}
}

View File

@ -1,11 +1,13 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#define ARDUINOJSON_DECODE_UNICODE 1
#include <ArduinoJson.h>
#include <catch.hpp>
#include "Allocators.hpp"
TEST_CASE("deserializeJson() returns IncompleteInput") {
const char* testCases[] = {
// strings
@ -118,3 +120,43 @@ TEST_CASE("deserializeJson() returns NoMemory if string length overflows") {
REQUIRE(err == DeserializationError::NoMemory);
}
}
TEST_CASE("deserializeJson() returns NoMemory if 8-bit slot allocation fails") {
JsonDocument doc(FailingAllocator::instance());
SECTION("uint32_t should pass") {
auto err = deserializeJson(doc, "4294967295");
REQUIRE(err == DeserializationError::Ok);
}
SECTION("uint64_t should fail") {
auto err = deserializeJson(doc, "18446744073709551615");
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("int32_t should pass") {
auto err = deserializeJson(doc, "-2147483648");
REQUIRE(err == DeserializationError::Ok);
}
SECTION("int64_t should fail") {
auto err = deserializeJson(doc, "-9223372036854775808");
REQUIRE(err == DeserializationError::NoMemory);
}
SECTION("float should pass") {
auto err = deserializeJson(doc, "3.402823e38");
REQUIRE(err == DeserializationError::Ok);
}
SECTION("double should fail") {
auto err = deserializeJson(doc, "1.7976931348623157e308");
REQUIRE(err == DeserializationError::NoMemory);
}
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#define ARDUINOJSON_ENABLE_COMMENTS 1
@ -693,6 +693,15 @@ TEST_CASE("Filtering") {
"null",
0,
},
{
"NUL character in key",
"{\"x\":0,\"x\\u0000a\":1,\"x\\u0000b\":2}",
"{\"x\\u0000a\":true}",
10,
DeserializationError::Ok,
"{\"x\\u0000a\":1}",
sizeofObject(1) + sizeofString("x?a"),
},
};
for (auto& tc : testCases) {
@ -816,7 +825,9 @@ TEST_CASE("shrink filter") {
deserializeJson(doc, "{}", DeserializationOption::Filter(filter));
REQUIRE(spy.log() == AllocatorLog{
Reallocate(sizeofPool(), sizeofObject(1)),
});
REQUIRE(spy.log() ==
AllocatorLog{
Reallocate(sizeofPool(), sizeofObject(1)),
Reallocate(sizeofStaticStringPool(), sizeofStaticStringPool(1)),
});
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>
@ -26,8 +26,8 @@ TEST_CASE("deserializeJson(char*)") {
REQUIRE(spy.log() ==
AllocatorLog{
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
Allocate(sizeofPool()),
Reallocate(sizeofStringBuffer(), sizeofString("hello")),
Allocate(sizeofStringBuffer()),
Reallocate(sizeofStringBuffer(), sizeofString("world")),
Reallocate(sizeofPool(), sizeofObject(1)),

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#include <ArduinoJson.h>

View File

@ -1,5 +1,5 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2024, Benoit BLANCHON
// Copyright © 2014-2025, Benoit BLANCHON
// MIT License
#define ARDUINOJSON_USE_LONG_LONG 0

Some files were not shown because too many files have changed in this diff Show More