Compare commits

...

31 Commits

Author SHA1 Message Date
219475630a Set version to 6.18.1 2021-07-03 16:03:01 +02:00
52e856fa6f CI: added ESP-IDF component build (closes #1599) 2021-06-30 13:34:59 +02:00
cb2c029e57 Added support for ESP-IDF component build (closes #1562) 2021-06-30 10:29:28 +02:00
ef7579394b Fixed JsonVariant::as<unsigned>() (fixes #1601) 2021-06-30 09:58:03 +02:00
fc4f175300 CI: fixed ARM compiler installation 2021-06-28 09:10:15 +02:00
a6fc9311b4 Added JsonArray::clear() (fixes #1597) 2021-06-26 11:29:15 +02:00
14639f129e CMake: added empty line at end of each file 2021-06-26 11:29:15 +02:00
9182c2068d Fixed build-single-header.sh (fixes #1592) 2021-06-21 16:11:02 +02:00
cb1b3be723 CI: build single headers 2021-06-21 16:11:02 +02:00
5ccd62a789 Updated the readme 2021-06-18 11:39:00 +02:00
145d45c746 Fixed warning on Clang 10 2021-06-17 20:41:04 +02:00
f235157466 Added support for std::string_view (closes #1578, closes #1554) 2021-06-17 20:41:04 +02:00
ba5cdab619 Test: extracted executable Cpp11Tests 2021-06-17 20:28:09 +02:00
eab5ae2f07 Simplified string adapters 2021-06-16 21:08:05 +02:00
2f0b3c0e63 VSCode: added devcontainer configuration 2021-06-16 21:08:05 +02:00
4e261068a1 clang-format: set IndentPPDirectives to AfterHash 2021-06-16 21:08:01 +02:00
1d24caf066 Added InvalidConversion to identify invalid conversions (closes #1585) 2021-06-11 11:54:52 +02:00
dc76c5165f Fixed clang-tidy warnings (fixes #1574) 2021-06-04 12:00:33 +02:00
de11b36a98 clang-tidy: muted "uninitialized pointer/field" in StringCopier 2021-06-04 11:38:21 +02:00
c4a4ed5272 clang-tidy: muted "uninitialized field" in Latch 2021-06-04 11:37:07 +02:00
a24edac5a9 clang-tidy: muted "use of memory after it is freed" in MemoryPool 2021-06-04 11:37:07 +02:00
9dbf44388d clang-tidy: muted "call to function is insecure" in tests 2021-06-04 11:37:07 +02:00
6b8e93e05e clang-tidy: fixed "uninitialized field" in VariantData 2021-06-04 11:36:20 +02:00
6b5239b9d5 clang-tidy: removed unused field 2021-06-04 11:16:24 +02:00
214c06b771 clang-tidy: fixed clang-analyzer-optin.cplusplus.UninitializedObject 2021-06-04 11:16:17 +02:00
e32a8552be CI: added clang-tidy (closes #1577) 2021-06-04 11:00:16 +02:00
9bcb409648 Fixed serializeJson(doc, String) when allocation fails (fixes #1572) 2021-05-30 21:34:07 +02:00
3b10afd2ab CI: test more platforms on PlatformIO 2021-05-30 18:45:40 +02:00
af3bb131c8 Fixed error Pe070 "incomplete type is not allowed" on IAR (fixes #1560) 2021-05-19 15:07:59 +02:00
622e7dd287 Fixed support for volatile float and double (fixes #1557) 2021-05-19 15:01:51 +02:00
68082e6fc1 CI: use libc++ for Clang 3.5 to 4.0
The fixes the error: "__STRICT_ANSI__ seems to have been undefined; this is not supported" with Clang 3.9
2021-05-17 09:06:28 +02:00
100 changed files with 1406 additions and 611 deletions

View File

@ -4,6 +4,7 @@ BasedOnStyle: Google
Standard: Cpp03
AllowShortFunctionsOnASingleLine: Empty
IncludeBlocks: Preserve
IndentPPDirectives: AfterHash
# Always break after if to get accurate coverage
AllowShortIfStatementsOnASingleLine: false

43
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,43 @@
FROM ubuntu:20.04
RUN apt-get update && \
apt-get install -y software-properties-common curl && \
apt-get upgrade -y
RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 15CF4D18AF4F7421
RUN add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty main' && \
add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ trusty universe' && \
add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial main' && \
add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ xenial universe' && \
add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic main' && \
add-apt-repository -yn 'deb http://archive.ubuntu.com/ubuntu/ bionic universe' && \
add-apt-repository -yn 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-6.0 main' && \
add-apt-repository -yn 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-7 main' && \
add-apt-repository -yn 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main' && \
add-apt-repository -yn 'deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main'
RUN apt-get update && apt-get -y install \
cmake \
ninja-build \
git \
clang-format \
g++-4.4 \
g++-4.6 \
g++-4.7 \
g++-4.8 \
g++-4.9 \
g++-5 \
g++-7 \
g++-8 \
g++-9 \
g++-10 \
clang-3.5 \
clang-3.6 \
clang-3.7 \
clang-3.8 \
clang-3.9 \
clang-6.0 \
clang-7 \
clang-8 \
clang-9 \
clang-10 \
clang-11

View File

@ -0,0 +1,23 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/ubuntu
{
"name": "Ubuntu",
"build": {
"dockerfile": "Dockerfile"
},
// Set *default* container specific settings.json values on container create.
"settings": {},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-vscode.cmake-tools",
"ms-vscode.cpptools"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "uname -a",
}

View File

@ -73,11 +73,17 @@ jobs:
matrix:
include:
- clang: "3.5"
cxxflags: "-stdlib=libc++"
- clang: "3.6"
cxxflags: "-stdlib=libc++"
- clang: "3.7"
cxxflags: "-stdlib=libc++"
- clang: "3.8"
cxxflags: "-stdlib=libc++"
- clang: "3.9"
cxxflags: "-stdlib=libc++"
- clang: "4.0"
cxxflags: "-stdlib=libc++"
- clang: "5.0"
- clang: "6.0"
- clang: "7"
@ -105,7 +111,9 @@ jobs:
env:
CC: clang-${{ matrix.clang }}
CXX: clang++-${{ matrix.clang }}
CXXFLAGS: ${{ matrix.cxxflags }}
CXXFLAGS: >-
${{ matrix.cxxflags }}
${{ contains(matrix.cxxflags, 'libc++') && '-I/usr/lib/llvm-10/include/c++/v1/' || '' }}
- name: Build
run: cmake --build .
- name: Test
@ -186,19 +194,85 @@ jobs:
fail-fast: false
matrix:
include:
- board: uno
- board: esp01
- platform: atmelavr
board: leonardo
libraries:
- SD
- Ethernet
- platform: espressif8266
board: huzzah
- platform: espressif32
board: esp32dev
libraries:
- Ethernet
- platform: atmelsam
board: mkr1000USB
libraries:
- SD
- Ethernet
- platform: teensy
board: teensy31
- platform: ststm32
board: adafruit_feather_f405
libraries:
- SD
- Ethernet
- platform: nordicnrf52
board: adafruit_feather_nrf52840
libraries:
- SD
- Ethernet
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Set up cache for pip
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip
- name: Set up Python 3.x
uses: actions/setup-python@v2
with:
python-version: "3.x"
- name: Install PlatformIO
run: pip install platformio
- name: Build
run: extras/ci/platformio.sh ${{ matrix.board }}
- name: Install adafruit-nrfutil
if: ${{ matrix.platform == 'nordicnrf52' }}
run: pip install adafruit-nrfutil
- name: Set up cache for platformio
uses: actions/cache@v2
with:
path: ~/.platformio
key: ${{ runner.os }}-platformio-${{ matrix.platform }}
- name: Install platform "${{ matrix.platform }}"
run: platformio platform install ${{ matrix.platform }}
- name: Install libraries
if: ${{ matrix.libraries }}
run: platformio lib install arduino-libraries/${{ join(matrix.libraries, ' arduino-libraries/') }}
- name: Build JsonConfigFile
run: platformio ci "examples/JsonConfigFile/JsonConfigFile.ino" -l '.' -b ${{ matrix.board }}
- name: Build JsonFilterExample
run: platformio ci "examples/JsonFilterExample/JsonFilterExample.ino" -l '.' -b ${{ matrix.board }}
- name: Build JsonGeneratorExample
run: platformio ci "examples/JsonGeneratorExample/JsonGeneratorExample.ino" -l '.' -b ${{ matrix.board }}
- name: Build JsonHttpClient
run: platformio ci "examples/JsonHttpClient/JsonHttpClient.ino" -l '.' -b ${{ matrix.board }}
- name: Build JsonParserExample
run: platformio ci "examples/JsonParserExample/JsonParserExample.ino" -l '.' -b ${{ matrix.board }}
- name: Build JsonServer
if: ${{ matrix.platform != 'espressif32' }}
run: platformio ci "examples/JsonServer/JsonServer.ino" -l '.' -b ${{ matrix.board }}
- name: Build JsonUdpBeacon
run: platformio ci "examples/JsonUdpBeacon/JsonUdpBeacon.ino" -l '.' -b ${{ matrix.board }}
- name: Build MsgPackParser
run: platformio ci "examples/MsgPackParser/MsgPackParser.ino" -l '.' -b ${{ matrix.board }}
- name: Build ProgmemExample
run: platformio ci "examples/ProgmemExample/ProgmemExample.ino" -l '.' -b ${{ matrix.board }}
- name: Build StringExample
run: platformio ci "examples/StringExample/StringExample.ino" -l '.' -b ${{ matrix.board }}
- name: PlatformIO prune
if: ${{ always() }}
run: platformio system prune -f
particle:
name: Particle
@ -226,7 +300,9 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Install
run: sudo apt-get install -y g++-arm-linux-gnueabihf
run: |
sudo apt-get update
sudo apt-get install -y g++-arm-linux-gnueabihf
- name: Checkout
uses: actions/checkout@v2
- name: Configure
@ -261,7 +337,7 @@ jobs:
- name: Upload HTML report
uses: actions/upload-artifact@v2
with:
name: coverage
name: Coverage report
path: coverage
- name: Upload to Coveralls
uses: coverallsapp/github-action@master
@ -288,3 +364,114 @@ jobs:
- name: MemoryChecker.*.log
run: cat Testing/Temporary/MemoryChecker.*.log
if: failure()
clang-tidy:
needs: clang
name: Clang-Tidy
runs-on: ubuntu-20.04
steps:
- name: Install
run: sudo apt-get install -y clang-tidy cmake ninja-build
- name: Checkout
uses: actions/checkout@v2
- name: Configure
run: cmake -G Ninja -DCMAKE_CXX_CLANG_TIDY="clang-tidy-10;--warnings-as-errors=*" -DCMAKE_BUILD_TYPE=Debug .
env:
CC: clang-10
CXX: clang++-10
- name: Check
run: cmake --build . -- -k 0
amalgamate-h:
needs: gcc
name: Amalgamate ArduinoJson.h
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Amalgamate
id: amalgamate
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
else
VERSION=${GITHUB_SHA::7}
fi
INPUT=src/ArduinoJson.h
OUTPUT=ArduinoJson-$VERSION.h
extras/scripts/build-single-header.sh "$INPUT" "$OUTPUT"
echo ::set-output name=filename::${OUTPUT}
- name: Smoke test
run: |
g++ -x c++ - <<END
#include "${{ steps.amalgamate.outputs.filename }}"
int main() {
StaticJsonDocument<300> doc;
deserializeJson(doc, "{}");
}
END
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: Single headers
path: ${{ steps.amalgamate.outputs.filename }}
amalgamate-hpp:
needs: gcc
name: Amalgamate ArduinoJson.hpp
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Amalgamate
id: amalgamate
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/}
else
VERSION=${GITHUB_SHA::7}
fi
INPUT=src/ArduinoJson.hpp
OUTPUT=ArduinoJson-$VERSION.hpp
extras/scripts/build-single-header.sh "$INPUT" "$OUTPUT"
echo ::set-output name=filename::${OUTPUT}
- name: Smoke test
run: |
g++ -x c++ - <<END
#include "${{ steps.amalgamate.outputs.filename }}"
int main() {
ArduinoJson::StaticJsonDocument<300> doc;
deserializeJson(doc, "{}");
}
END
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: Single headers
path: ${{ steps.amalgamate.outputs.filename }}
esp-idf:
needs: gcc
name: ESP-IDF
runs-on: ubuntu-latest
steps:
- name: Setup cache
uses: actions/cache@v2
with:
path: ~/.espressif
key: ${{ runner.os }}-esp-idf
- name: Checkout ArduinoJson
uses: actions/checkout@v2
- name: Checkout ESP-IDF
uses: actions/checkout@v2
with:
repository: espressif/esp-idf
path: esp-idf
submodules: true
- name: Install ESP-IDF
run: ./esp-idf/install.sh
- name: Build example
run: |
source esp-idf/export.sh
cd extras/ci/espidf
idf.py build

View File

@ -1,6 +1,20 @@
ArduinoJson: change log
=======================
v6.18.1 (2021-07-03)
-------
* Fixed support for `volatile float` and `volatile double` (issue #1557)
* Fixed error `[Pe070]: incomplete type is not allowed` on IAR (issue #1560)
* Fixed `serializeJson(doc, String)` when allocation fails (issue #1572)
* Fixed clang-tidy warnings (issue #1574, PR #1577 by @armandas)
* Added fake class `InvalidConversion<T1,T2>` to easily identify invalid conversions (issue #1585)
* Added support for `std::string_view` (issue #1578, PR #1554 by @0xFEEDC0DE64)
* Fixed warning `definition of implicit copy constructor for 'MsgPackDeserializer' is deprecated because it has a user-declared copy assignment operator`
* Added `JsonArray::clear()` (issue #1597)
* Fixed `JsonVariant::as<unsigned>()` (issue #1601)
* Added support for ESP-IDF component build (PR #1562 by @qt1, PR #1599 by @andreaskuster)
v6.18.0 (2021-05-05)
-------

View File

@ -2,9 +2,16 @@
# Copyright Benoit Blanchon 2014-2021
# MIT License
cmake_minimum_required(VERSION 3.0)
cmake_minimum_required(VERSION 3.3)
project(ArduinoJson VERSION 6.18.0)
if(ESP_PLATFORM)
# Build ArduinoJson as an ESP-IDF component
idf_component_register(INCLUDE_DIRS src)
target_compile_definitions(${COMPONENT_LIB} INTERFACE ARDUINOJSON_EMBEDDED_MODE=1)
return()
endif()
project(ArduinoJson VERSION 6.18.1)
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest)

View File

@ -2,7 +2,7 @@
---
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.18.0)](https://www.ardu-badge.com/ArduinoJson/6.18.0)
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.18.1)](https://www.ardu-badge.com/ArduinoJson/6.18.1)
[![Continuous Integration](https://github.com/bblanchon/ArduinoJson/workflows/Continuous%20Integration/badge.svg?branch=6.x)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x)
[![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
[![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)
@ -33,15 +33,15 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/?utm_source=github&utm_medium=readme)
* Deduplicates strings
* Versatile
* [Supports custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
* Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/?utm_source=github&utm_medium=readme) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme)
* Supports [Arduino's `Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/?utm_source=github&utm_medium=readme) and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
* Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
* Supports [`String`](https://arduinojson.org/v6/api/config/enable_arduino_string/?utm_source=github&utm_medium=readme), [`std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme) and [`std::string_view`](https://arduinojson.org/v6/api/config/enable_string_view/?utm_source=github&utm_medium=readme)
* Supports [`Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/?utm_source=github&utm_medium=readme) and [`std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
* Supports [Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer)
* Supports custom converters
* Supports [custom converters](https://arduinojson.org/news/2021/05/04/version-6-18-0/?utm_source=github&utm_medium=readme)
* Portable
* Usable on any C++ project (not limited to Arduino)
* Compatible with C++98
* Compatible with C++98, C++11, C++14 and C++17
* Zero warnings with `-Wall -Wextra -pedantic` and `/W4`
* [Header-only library](https://en.wikipedia.org/wiki/Header-only)
* Works with virtually any board
@ -81,15 +81,17 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
* [GCC 4.4, 4.6, 4.7, 4.8, 4.9, 5, 6, 7, 8, 9, 10](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
* [Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7, 8, 9, 10](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
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/?utm_source=github&utm_medium=readme)
* [Examples](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
* [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
* [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme)
* [Troubleshooter](https://arduinojson.org/v6/troubleshooter/?utm_source=github&utm_medium=readme)
* [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme)
* [Changelog](CHANGELOG.md)
* Vibrant user community
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories) and [PlatformIO](https://platformio.org/lib/search)
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories)
* [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson)
* [Responsive support](https://github.com/bblanchon/ArduinoJson/issues?q=is%3Aissue+is%3Aclosed)
@ -132,9 +134,11 @@ serializeJson(doc, Serial);
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=github&utm_medium=readme)
## Support the project
## Support the project ❤️
Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)!
Do you like this library?
Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)!
What? You don't like it but you *love* it?
We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time.
You can support the project by [purchasing my book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme).
Alternatively, you can make a recurring donation via [GitHub Sponsors](https://github.com/sponsors/bblanchon).

View File

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

View File

@ -23,12 +23,6 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
-Wundef
)
if(NOT MINGW)
add_compile_options(
-std=c++98
)
endif()
if(${COVERAGE})
set(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage")
endif()

View File

@ -0,0 +1,8 @@
# ArduinoJson - https://arduinojson.org
# Copyright Benoit Blanchon 2014-2021
# MIT License
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(example)

View File

@ -0,0 +1 @@
../../../..

View File

@ -0,0 +1,6 @@
# ArduinoJson - https://arduinojson.org
# Copyright Benoit Blanchon 2014-2021
# MIT License
idf_component_register(SRCS "main.cpp"
INCLUDE_DIRS "")

View File

@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View File

@ -0,0 +1,16 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#include <ArduinoJson.h>
extern "C" void app_main() {
char buffer[256];
StaticJsonDocument<200> doc;
doc["hello"] = "world";
serializeJson(doc, buffer);
deserializeJson(doc, buffer);
serializeMsgPack(doc, buffer);
deserializeMsgPack(doc, buffer);
}

View File

@ -1,20 +0,0 @@
#!/bin/sh -eux
BOARD=$1
case $BOARD in
uno)
platformio lib install 868 # SD library
platformio lib install 872 # Ethernet library
;;
esp01)
platformio lib uninstall 161 || true
platformio lib uninstall 868 || true
platformio lib uninstall 872 || true
;;
esac
for EXAMPLE in $PWD/examples/*/*.ino;
do
platformio ci $EXAMPLE -l '.' -b $BOARD
done

View File

@ -2,11 +2,10 @@
set -e
TAG=$(git describe)
RE_RELATIVE_INCLUDE='^#include[[:space:]]*"(.*)"'
RE_ABSOLUTE_INCLUDE='^#include[[:space:]]*<(ArduinoJson/.*)>'
RE_SYSTEM_INCLUDE='^#include[[:space:]]*<(.*)>'
RE_EMPTY='^(#pragma[[:space:]]+once)?[[:space:]]*(//.*)?$'
RE_RELATIVE_INCLUDE='^#[[:space:]]*include[[:space:]]*"(.*)"'
RE_ABSOLUTE_INCLUDE='^#[[:space:]]*include[[:space:]]*<(ArduinoJson/.*)>'
RE_SYSTEM_INCLUDE='^#[[:space:]]*include[[:space:]]*<(.*)>'
RE_EMPTY='^(#[[:space:]]*pragma[[:space:]]+once)?[[:space:]]*(//.*)?$'
SRC_DIRECTORY="$(realpath "$(dirname $0)/../../src")"
@ -58,25 +57,8 @@ simplify_namespaces() {
rm -f "$1.bak"
}
cd $(dirname $0)/../..
INCLUDED=()
process src/ArduinoJson.h true > ../ArduinoJson-$TAG.h
simplify_namespaces ../ArduinoJson-$TAG.h
g++ -x c++ -c -o ../smoketest.o - <<END
#include "../ArduinoJson-$TAG.h"
int main() {
StaticJsonDocument<300> doc;
deserializeJson(doc, "{}");
}
END
INCLUDED=()
process src/ArduinoJson.hpp true > ../ArduinoJson-$TAG.hpp
simplify_namespaces ../ArduinoJson-$TAG.hpp
g++ -x c++ -c -o ../smoketest.o - <<END
#include "../ArduinoJson-$TAG.hpp"
int main() {
ArduinoJson::StaticJsonDocument<300> doc;
ArduinoJson::deserializeJson(doc, "{}");
}
END
INPUT=$1
OUTPUT=$2
process "$INPUT" true > "$OUTPUT"
simplify_namespaces "$OUTPUT"

1
extras/tests/.clang-tidy Normal file
View File

@ -0,0 +1 @@
Checks: '-clang-analyzer-security.insecureAPI.*'

View File

@ -2,11 +2,16 @@
# Copyright Benoit Blanchon 2014-2021
# MIT License
set(CMAKE_CXX_STANDARD 98)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(catch)
link_libraries(ArduinoJson catch)
include_directories(Helpers)
add_subdirectory(Cpp11)
add_subdirectory(Cpp17)
add_subdirectory(FailingBuilds)
add_subdirectory(IntegrationTests)
add_subdirectory(JsonArray)

View File

@ -0,0 +1,32 @@
# ArduinoJson - https://arduinojson.org
# Copyright Benoit Blanchon 2014-2021
# MIT License
if("cxx_nullptr" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
list(APPEND SOURCES nullptr.cpp)
add_definitions(-DARDUINOJSON_HAS_NULLPTR=1)
endif()
if("cxx_auto_type" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND "cxx_constexpr" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
list(APPEND SOURCES issue1120.cpp)
endif()
if("cxx_long_long_type" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
list(APPEND SOURCES use_long_long_0.cpp use_long_long_1.cpp)
endif()
if(NOT SOURCES)
return()
endif()
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(Cpp11Tests ${SOURCES})
add_test(Cpp11 Cpp11Tests)
set_tests_properties(Cpp11
PROPERTIES
LABELS "Catch"
)

View File

@ -2,40 +2,6 @@
#include <catch.hpp>
#if __cplusplus >= 201103L
TEST_CASE("nullptr") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("JsonVariant == nullptr") {
REQUIRE((variant == nullptr));
REQUIRE_FALSE((variant != nullptr));
}
SECTION("JsonVariant != nullptr") {
variant.set(42);
REQUIRE_FALSE((variant == nullptr));
REQUIRE((variant != nullptr));
}
SECTION("JsonVariant.set(nullptr)") {
variant.set(42);
variant.set(nullptr);
REQUIRE(variant.isNull());
}
SECTION("JsonVariant.is<nullptr_t>()") {
variant.set(42);
REQUIRE(variant.is<std::nullptr_t>() == false);
variant.clear();
REQUIRE(variant.is<std::nullptr_t>() == true);
}
}
TEST_CASE("Issue #1120") {
StaticJsonDocument<500> doc;
constexpr char str[] =
@ -90,5 +56,3 @@ TEST_CASE("Issue #1120") {
}
}
}
#endif

View File

@ -0,0 +1,39 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#if !ARDUINOJSON_HAS_NULLPTR
# error ARDUINOJSON_HAS_NULLPTR must be set to 1
#endif
TEST_CASE("nullptr") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("JsonVariant == nullptr") {
REQUIRE((variant == nullptr));
REQUIRE_FALSE((variant != nullptr));
}
SECTION("JsonVariant != nullptr") {
variant.set(42);
REQUIRE_FALSE((variant == nullptr));
REQUIRE((variant != nullptr));
}
SECTION("JsonVariant.set(nullptr)") {
variant.set(42);
variant.set(nullptr);
REQUIRE(variant.isNull());
}
SECTION("JsonVariant.is<nullptr_t>()") {
variant.set(42);
REQUIRE(variant.is<std::nullptr_t>() == false);
variant.clear();
REQUIRE(variant.is<std::nullptr_t>() == true);
}
}

View File

@ -0,0 +1,29 @@
# ArduinoJson - https://arduinojson.org
# Copyright Benoit Blanchon 2014-2021
# MIT License
if(MSVC_VERSION LESS 1910)
return()
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5)
return()
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7)
return()
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_executable(Cpp17Tests
string_view.cpp
)
add_test(Cpp17 Cpp17Tests)
set_tests_properties(Cpp17
PROPERTIES
LABELS "Catch"
)

View File

@ -0,0 +1,79 @@
#include <ArduinoJson.h>
#include <catch.hpp>
#include <string_view>
#if !ARDUINOJSON_ENABLE_STRING_VIEW
# error ARDUINOJSON_ENABLE_STRING_VIEW must be set to 1
#endif
TEST_CASE("string_view") {
StaticJsonDocument<128> doc;
JsonVariant variant = doc.to<JsonVariant>();
SECTION("deserializeJson()") {
auto err = deserializeJson(doc, std::string_view("123", 2));
REQUIRE(err == DeserializationError::Ok);
REQUIRE(doc.as<int>() == 12);
}
SECTION("JsonDocument::set()") {
doc.set(std::string_view("123", 2));
REQUIRE(doc.as<std::string>() == "12");
}
SECTION("JsonDocument::operator[]() const") {
doc["ab"] = "Yes";
doc["abc"] = "No";
REQUIRE(doc[std::string_view("abc", 2)] == "Yes");
}
SECTION("JsonDocument::operator[]()") {
doc[std::string_view("abc", 2)] = "Yes";
REQUIRE(doc["ab"] == "Yes");
}
SECTION("JsonVariant::operator==()") {
variant.set("A");
REQUIRE(variant == std::string_view("AX", 1));
REQUIRE_FALSE(variant == std::string_view("BX", 1));
}
SECTION("JsonVariant::operator>()") {
variant.set("B");
REQUIRE(variant > std::string_view("AX", 1));
REQUIRE_FALSE(variant > std::string_view("CX", 1));
}
SECTION("JsonVariant::operator<()") {
variant.set("B");
REQUIRE(variant < std::string_view("CX", 1));
REQUIRE_FALSE(variant < std::string_view("AX", 1));
}
SECTION("String deduplication") {
doc.add(std::string_view("example one", 7));
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(1) + 8);
doc.add(std::string_view("example two", 7));
REQUIRE(doc.memoryUsage() == JSON_ARRAY_SIZE(2) + 8);
}
}
using ARDUINOJSON_NAMESPACE::adaptString;
TEST_CASE("StringViewAdapter") {
std::string_view str("bravoXXX", 5);
auto adapter = adaptString(str);
CHECK(adapter.compare(NULL) > 0);
CHECK(adapter.compare("alpha") > 0);
CHECK(adapter.compare("bravo") == 0);
CHECK(adapter.compare("charlie") < 0);
CHECK(adapter.equals("bravo"));
CHECK_FALSE(adapter.equals("charlie"));
CHECK_FALSE(adapter.equals(NULL));
CHECK(adapter.size() == 5);
}

View File

@ -6,11 +6,11 @@
#include <ArduinoJson.h>
#if defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ >= 8
#error This test requires sizeof(long) < 8
# error This test requires sizeof(long) < 8
#endif
#if !ARDUINOJSON_HAS_LONG_LONG
#error This test requires C++11
# error This test requires C++11
#endif
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(long long)

View File

@ -6,11 +6,11 @@
#include <ArduinoJson.h>
#if defined(__SIZEOF_LONG__) && __SIZEOF_LONG__ >= 8
#error This test requires sizeof(long) < 8
# error This test requires sizeof(long) < 8
#endif
#if !ARDUINOJSON_HAS_LONG_LONG
#error This test requires C++11
# error This test requires C++11
#endif
int main() {

View File

@ -9,12 +9,15 @@
// Reproduces Arduino's String class
class String {
public:
String() {}
explicit String(const char* s) : _str(s) {}
String() : _maxCapacity(1024) {}
explicit String(const char* s) : _str(s), _maxCapacity(1024) {}
String& operator+=(const char* rhs) {
_str += rhs;
return *this;
void limitCapacityTo(size_t maxCapacity) {
_maxCapacity = maxCapacity;
}
unsigned char concat(const char* s) {
return concat(s, strlen(s));
}
size_t length() const {
@ -34,8 +37,18 @@ class String {
return lhs;
}
protected:
// This function is protected in most Arduino cores
unsigned char concat(const char* s, size_t n) {
if (_str.size() + n > _maxCapacity)
return 0;
_str.append(s, n);
return 1;
}
private:
std::string _str;
size_t _maxCapacity;
};
class StringSumHelper;

View File

@ -21,4 +21,4 @@ add_test(IntegrationTests IntegrationTests)
set_tests_properties(IntegrationTests
PROPERTIES
LABELS "Catch"
)
)

View File

@ -4,6 +4,7 @@
add_executable(JsonArrayTests
add.cpp
clear.cpp
copyArray.cpp
createNested.cpp
equals.cpp
@ -24,4 +25,4 @@ add_test(JsonArray JsonArrayTests)
set_tests_properties(JsonArray
PROPERTIES
LABELS "Catch"
)
)

View File

@ -0,0 +1,25 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonArray::clear()") {
SECTION("No-op on null JsonArray") {
JsonArray array;
array.clear();
REQUIRE(array.isNull() == true);
REQUIRE(array.size() == 0);
}
SECTION("Removes all elements") {
StaticJsonDocument<64> doc;
JsonArray array = doc.to<JsonArray>();
array.add(1);
array.add(2);
array.clear();
REQUIRE(array.size() == 0);
REQUIRE(array.isNull() == false);
}
}

View File

@ -25,4 +25,4 @@ add_test(JsonDeserializer JsonDeserializerTests)
set_tests_properties(JsonDeserializer
PROPERTIES
LABELS "Catch"
)
)

View File

@ -26,4 +26,4 @@ add_test(JsonDocument JsonDocumentTests)
set_tests_properties(JsonDocument
PROPERTIES
LABELS "Catch"
)
)

View File

@ -3,6 +3,7 @@
# MIT License
add_executable(JsonObjectTests
clear.cpp
containsKey.cpp
copy.cpp
createNestedArray.cpp
@ -24,4 +25,4 @@ add_test(JsonObject JsonObjectTests)
set_tests_properties(JsonObject
PROPERTIES
LABELS "Catch"
)
)

View File

@ -0,0 +1,25 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#include <ArduinoJson.h>
#include <catch.hpp>
TEST_CASE("JsonObject::clear()") {
SECTION("No-op on null JsonObject") {
JsonObject obj;
obj.clear();
REQUIRE(obj.isNull() == true);
REQUIRE(obj.size() == 0);
}
SECTION("Removes all elements") {
StaticJsonDocument<64> doc;
JsonObject obj = doc.to<JsonObject>();
obj["hello"] = 1;
obj["world"] = 2;
obj.clear();
REQUIRE(obj.size() == 0);
REQUIRE(obj.isNull() == false);
}
}

View File

@ -19,4 +19,4 @@ add_test(JsonSerializer JsonSerializerTests)
set_tests_properties(JsonSerializer
PROPERTIES
LABELS "Catch"
)
)

View File

@ -30,4 +30,4 @@ add_test(JsonVariant JsonVariantTests)
set_tests_properties(JsonVariant
PROPERTIES
LABELS "Catch"
)
)

View File

@ -61,6 +61,16 @@ TEST_CASE("JsonVariant::as()") {
REQUIRE(variant.as<std::string>() == "true");
}
SECTION("set(42)") {
variant.set(42);
REQUIRE(variant.as<bool>() == true);
REQUIRE(variant.as<double>() == 42.0);
REQUIRE(variant.as<int>() == 42);
REQUIRE(variant.as<unsigned int>() == 42U); // issue #1601
REQUIRE(variant.as<std::string>() == "42");
}
SECTION("set(42L)") {
variant.set(42L);

View File

@ -135,3 +135,29 @@ TEST_CASE("JsonVariant set()/get()") {
checkValue<JsonObject>(object);
}
}
TEST_CASE("volatile") {
DynamicJsonDocument doc(4096);
JsonVariant variant = doc.to<JsonVariant>();
SECTION("volatile int") {
volatile int f = 42;
variant.set(f);
CHECK(variant.is<int>() == true);
CHECK(variant.as<int>() == 42);
}
SECTION("volatile float") { // issue #1557
volatile float f = 3.14f;
variant.set(f);
CHECK(variant.is<float>() == true);
CHECK(variant.as<float>() == 3.14f);
}
SECTION("volatile double") {
volatile double f = 3.14;
variant.set(f);
CHECK(variant.is<double>() == true);
CHECK(variant.as<double>() == 3.14);
}
}

View File

@ -15,4 +15,4 @@ add_test(MemoryPool MemoryPoolTests)
set_tests_properties(MemoryPool
PROPERTIES
LABELS "Catch"
)
)

View File

@ -11,95 +11,121 @@
using namespace ARDUINOJSON_NAMESPACE;
template <typename StringWriter>
static size_t print(StringWriter& sb, const char* s) {
return sb.write(reinterpret_cast<const uint8_t*>(s), strlen(s));
static size_t print(StringWriter& writer, const char* s) {
return writer.write(reinterpret_cast<const uint8_t*>(s), strlen(s));
}
template <typename StringWriter, typename String>
void common_tests(StringWriter& sb, const String& output) {
void common_tests(StringWriter& writer, const String& output) {
SECTION("InitialState") {
REQUIRE(std::string("") == output);
}
SECTION("EmptyString") {
REQUIRE(0 == print(sb, ""));
REQUIRE(0 == print(writer, ""));
REQUIRE(std::string("") == output);
}
SECTION("OneString") {
REQUIRE(4 == print(sb, "ABCD"));
REQUIRE(4 == print(writer, "ABCD"));
REQUIRE(std::string("ABCD") == output);
}
SECTION("TwoStrings") {
REQUIRE(4 == print(sb, "ABCD"));
REQUIRE(4 == print(sb, "EFGH"));
REQUIRE(4 == print(writer, "ABCD"));
REQUIRE(4 == print(writer, "EFGH"));
REQUIRE(std::string("ABCDEFGH") == output);
}
}
TEST_CASE("StaticStringWriter") {
char output[20] = {0};
StaticStringWriter sb(output, sizeof(output));
StaticStringWriter writer(output, sizeof(output));
common_tests(sb, static_cast<const char*>(output));
common_tests(writer, static_cast<const char*>(output));
SECTION("OverCapacity") {
REQUIRE(20 == print(sb, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
REQUIRE(0 == print(sb, "ABC"));
REQUIRE(20 == print(writer, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
REQUIRE(0 == print(writer, "ABC"));
REQUIRE("ABCDEFGHIJKLMNOPQRST" == std::string(output, 20));
}
}
TEST_CASE("Writer<std::string>") {
std::string output;
Writer<std::string> sb(output);
common_tests(sb, output);
Writer<std::string> writer(output);
common_tests(writer, output);
}
TEST_CASE("Writer<String>") {
::String output;
Writer< ::String> sb(output);
Writer< ::String> writer(output);
common_tests(sb, output);
SECTION("write(char)") {
SECTION("writes to temporary buffer") {
// accumulate in buffer
writer.write('a');
writer.write('b');
writer.write('c');
writer.write('d');
REQUIRE(output == "");
SECTION("Writes characters to temporary buffer") {
// accumulate in buffer
sb.write('a');
sb.write('b');
sb.write('c');
REQUIRE(output == "");
// flush when full
writer.write('e');
REQUIRE(output == "abcd");
// flush when full
sb.write('d');
REQUIRE(output == "abcd");
// flush on destruction
writer.write('f');
writer.~Writer();
REQUIRE(output == "abcdef");
}
// flush on destruction
sb.write('e');
sb.~Writer();
REQUIRE(output == "abcde");
SECTION("returns 1 on success") {
for (int i = 0; i < ARDUINOJSON_STRING_BUFFER_SIZE; i++) {
REQUIRE(writer.write('x') == 1);
}
}
SECTION("returns 0 on error") {
output.limitCapacityTo(1);
REQUIRE(writer.write('a') == 1);
REQUIRE(writer.write('b') == 1);
REQUIRE(writer.write('c') == 1);
REQUIRE(writer.write('d') == 1);
REQUIRE(writer.write('e') == 0);
REQUIRE(writer.write('f') == 0);
}
}
SECTION("Writes strings to temporary buffer") {
// accumulate in buffer
print(sb, "abc");
REQUIRE(output == "");
SECTION("write(char*, size_t)") {
SECTION("empty string") {
REQUIRE(0 == print(writer, ""));
writer.flush();
REQUIRE(output == "");
}
// flush when full, and continue to accumulate
print(sb, "de");
REQUIRE(output == "abcd");
SECTION("writes to temporary buffer") {
// accumulate in buffer
print(writer, "abc");
REQUIRE(output == "");
// flush on destruction
sb.~Writer();
REQUIRE(output == "abcde");
// flush when full, and continue to accumulate
print(writer, "de");
REQUIRE(output == "abcd");
// flush on destruction
writer.~Writer();
REQUIRE(output == "abcde");
}
}
}
TEST_CASE("Writer<custom_string>") {
custom_string output;
Writer<custom_string> sb(output);
Writer<custom_string> writer(output);
REQUIRE(4 == print(sb, "ABCD"));
REQUIRE(4 == print(writer, "ABCD"));
REQUIRE("ABCD" == output);
}
@ -116,3 +142,20 @@ TEST_CASE("IsWriteableString") {
REQUIRE(IsWriteableString<std::basic_string<wchar_t> >::value == false);
}
}
TEST_CASE("serializeJson(doc, String)") {
StaticJsonDocument<1024> doc;
doc["hello"] = "world";
::String output;
SECTION("sufficient capacity") {
serializeJson(doc, output);
REQUIRE(output == "{\"hello\":\"world\"}");
}
SECTION("unsufficient capacity") { // issue #1561
output.limitCapacityTo(10);
serializeJson(doc, output);
REQUIRE(output == "{\"hello\"");
}
}

View File

@ -32,6 +32,12 @@ TEST_CASE("Polyfills/type_traits") {
SECTION("is_integral") {
CHECK(is_integral<double>::value == false);
CHECK(is_integral<float>::value == false);
CHECK(is_integral<const double>::value == false);
CHECK(is_integral<const float>::value == false);
CHECK(is_integral<volatile double>::value == false);
CHECK(is_integral<volatile float>::value == false);
CHECK(is_integral<const volatile double>::value == false);
CHECK(is_integral<const volatile float>::value == false);
CHECK(is_integral<bool>::value == true);
CHECK(is_integral<char>::value == true);
@ -43,6 +49,36 @@ TEST_CASE("Polyfills/type_traits") {
CHECK(is_integral<unsigned int>::value == true);
CHECK(is_integral<unsigned long>::value == true);
CHECK(is_integral<unsigned short>::value == true);
CHECK(is_integral<const bool>::value == true);
CHECK(is_integral<const char>::value == true);
CHECK(is_integral<const signed char>::value == true);
CHECK(is_integral<const signed int>::value == true);
CHECK(is_integral<const signed long>::value == true);
CHECK(is_integral<const signed short>::value == true);
CHECK(is_integral<const unsigned char>::value == true);
CHECK(is_integral<const unsigned int>::value == true);
CHECK(is_integral<const unsigned long>::value == true);
CHECK(is_integral<const unsigned short>::value == true);
CHECK(is_integral<volatile bool>::value == true);
CHECK(is_integral<volatile char>::value == true);
CHECK(is_integral<volatile signed char>::value == true);
CHECK(is_integral<volatile signed int>::value == true);
CHECK(is_integral<volatile signed long>::value == true);
CHECK(is_integral<volatile signed short>::value == true);
CHECK(is_integral<volatile unsigned char>::value == true);
CHECK(is_integral<volatile unsigned int>::value == true);
CHECK(is_integral<volatile unsigned long>::value == true);
CHECK(is_integral<volatile unsigned short>::value == true);
CHECK(is_integral<const volatile bool>::value == true);
CHECK(is_integral<const volatile char>::value == true);
CHECK(is_integral<const volatile signed char>::value == true);
CHECK(is_integral<const volatile signed int>::value == true);
CHECK(is_integral<const volatile signed long>::value == true);
CHECK(is_integral<const volatile signed short>::value == true);
CHECK(is_integral<const volatile unsigned char>::value == true);
CHECK(is_integral<const volatile unsigned int>::value == true);
CHECK(is_integral<const volatile unsigned long>::value == true);
CHECK(is_integral<const volatile unsigned short>::value == true);
CHECK(is_integral<UInt>::value == true);
}
@ -56,6 +92,33 @@ TEST_CASE("Polyfills/type_traits") {
CHECK(is_signed<float>::value == true);
CHECK(is_signed<double>::value == true);
CHECK(is_signed<bool>::value == false);
CHECK(is_signed<const char>::value == true);
CHECK(is_signed<const signed char>::value == true);
CHECK(is_signed<const signed int>::value == true);
CHECK(is_signed<const signed short>::value == true);
CHECK(is_signed<const signed long>::value == true);
CHECK(is_signed<const float>::value == true);
CHECK(is_signed<const double>::value == true);
CHECK(is_signed<const bool>::value == false);
CHECK(is_signed<volatile char>::value == true);
CHECK(is_signed<volatile signed char>::value == true);
CHECK(is_signed<volatile signed int>::value == true);
CHECK(is_signed<volatile signed short>::value == true);
CHECK(is_signed<volatile signed long>::value == true);
CHECK(is_signed<volatile float>::value == true);
CHECK(is_signed<volatile double>::value == true);
CHECK(is_signed<volatile bool>::value == false);
CHECK(is_signed<const volatile char>::value == true);
CHECK(is_signed<const volatile signed char>::value == true);
CHECK(is_signed<const volatile signed int>::value == true);
CHECK(is_signed<const volatile signed short>::value == true);
CHECK(is_signed<const volatile signed long>::value == true);
CHECK(is_signed<const volatile float>::value == true);
CHECK(is_signed<const volatile double>::value == true);
CHECK(is_signed<const volatile bool>::value == false);
}
SECTION("is_unsigned") {
@ -67,6 +130,45 @@ TEST_CASE("Polyfills/type_traits") {
CHECK(is_unsigned<char>::value == false);
CHECK(is_unsigned<float>::value == false);
CHECK(is_unsigned<double>::value == false);
CHECK(is_unsigned<const unsigned char>::value == true);
CHECK(is_unsigned<const unsigned int>::value == true);
CHECK(is_unsigned<const unsigned short>::value == true);
CHECK(is_unsigned<const unsigned long>::value == true);
CHECK(is_unsigned<const bool>::value == true);
CHECK(is_unsigned<const char>::value == false);
CHECK(is_unsigned<const float>::value == false);
CHECK(is_unsigned<const double>::value == false);
CHECK(is_unsigned<volatile unsigned char>::value == true);
CHECK(is_unsigned<volatile unsigned int>::value == true);
CHECK(is_unsigned<volatile unsigned short>::value == true);
CHECK(is_unsigned<volatile unsigned long>::value == true);
CHECK(is_unsigned<volatile bool>::value == true);
CHECK(is_unsigned<volatile char>::value == false);
CHECK(is_unsigned<volatile float>::value == false);
CHECK(is_unsigned<volatile double>::value == false);
CHECK(is_unsigned<const volatile unsigned char>::value == true);
CHECK(is_unsigned<const volatile unsigned int>::value == true);
CHECK(is_unsigned<const volatile unsigned short>::value == true);
CHECK(is_unsigned<const volatile unsigned long>::value == true);
CHECK(is_unsigned<const volatile bool>::value == true);
CHECK(is_unsigned<const volatile char>::value == false);
CHECK(is_unsigned<const volatile float>::value == false);
CHECK(is_unsigned<const volatile double>::value == false);
}
SECTION("is_floating_point") {
CHECK(is_floating_point<int>::value == false);
CHECK(is_floating_point<float>::value == true);
CHECK(is_floating_point<double>::value == true);
CHECK(is_floating_point<const float>::value == true);
CHECK(is_floating_point<const double>::value == true);
CHECK(is_floating_point<volatile float>::value == true);
CHECK(is_floating_point<volatile double>::value == true);
CHECK(is_floating_point<const volatile float>::value == true);
CHECK(is_floating_point<const volatile double>::value == true);
}
SECTION("is_convertible") {

View File

@ -6,7 +6,7 @@
#include <catch.hpp>
#if defined(__clang__)
#define CONFLICTS_WITH_BUILTIN_OPERATOR
# define CONFLICTS_WITH_BUILTIN_OPERATOR
#endif
TEST_CASE("unsigned char[]") {

View File

@ -2,11 +2,7 @@
# Copyright Benoit Blanchon 2014-2021
# MIT License
# we need C++11 for 'long long'
set(CMAKE_CXX_STANDARD 11)
add_executable(MixedConfigurationTests
cpp11.cpp
decode_unicode_0.cpp
decode_unicode_1.cpp
enable_alignment_0.cpp
@ -22,8 +18,6 @@ add_executable(MixedConfigurationTests
enable_string_deduplication_1.cpp
use_double_0.cpp
use_double_1.cpp
use_long_long_0.cpp
use_long_long_1.cpp
)
set_target_properties(MixedConfigurationTests PROPERTIES UNITY_BUILD OFF)
@ -33,4 +27,4 @@ add_test(MixedConfiguration MixedConfigurationTests)
set_tests_properties(MixedConfiguration
PROPERTIES
LABELS "Catch"
)
)

View File

@ -6,7 +6,7 @@
static void assertParseFails(const char* json) {
DynamicJsonDocument doc(4096);
auto err = deserializeJson(doc, json);
DeserializationError err = deserializeJson(doc, json);
REQUIRE(err == DeserializationError::InvalidInput);
}

View File

@ -22,7 +22,8 @@ TEST_CASE("ARDUINOJSON_ENABLE_INFINITY == 1") {
}
SECTION("deserializeJson()") {
auto err = deserializeJson(doc, "[Infinity,-Infinity,+Infinity]");
DeserializationError err =
deserializeJson(doc, "[Infinity,-Infinity,+Infinity]");
float a = doc[0];
float b = doc[1];
float c = doc[2];

View File

@ -18,7 +18,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_NAN == 0") {
}
SECTION("deserializeJson()") {
auto err = deserializeJson(doc, "{\"X\":NaN}");
DeserializationError err = deserializeJson(doc, "{\"X\":NaN}");
REQUIRE(err == DeserializationError::InvalidInput);
}

View File

@ -22,7 +22,7 @@ TEST_CASE("ARDUINOJSON_ENABLE_NAN == 1") {
}
SECTION("deserializeJson()") {
auto err = deserializeJson(doc, "{\"X\":NaN}");
DeserializationError err = deserializeJson(doc, "{\"X\":NaN}");
float x = doc["X"];
REQUIRE(err == DeserializationError::Ok);

View File

@ -21,4 +21,4 @@ add_test(MsgPackDeserializer MsgPackDeserializerTests)
set_tests_properties(MsgPackDeserializer
PROPERTIES
LABELS "Catch"
)
)

View File

@ -16,4 +16,4 @@ add_test(MsgPackSerializer MsgPackSerializerTests)
set_tests_properties(MsgPackSerializer
PROPERTIES
LABELS "Catch"
)
)

View File

@ -3,6 +3,7 @@
# MIT License
add_executable(NumbersTests
convertNumber.cpp
parseFloat.cpp
parseDouble.cpp
parseInteger.cpp
@ -15,4 +16,4 @@ add_test(Numbers NumbersTests)
set_tests_properties(Numbers
PROPERTIES
LABELS "Catch"
)
)

View File

@ -0,0 +1,78 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#include <stdint.h>
#include <ArduinoJson.hpp>
#include <catch.hpp>
using namespace ARDUINOJSON_NAMESPACE;
TEST_CASE("canConvertNumber<TOut, TIn>()") {
SECTION("int8_t -> int8_t") {
CHECK((canConvertNumber<int8_t, int8_t>(0)) == true);
CHECK((canConvertNumber<int8_t, int8_t>(127)) == true);
CHECK((canConvertNumber<int8_t, int8_t>(-128)) == true);
}
SECTION("int8_t -> int16_t") {
CHECK((canConvertNumber<int16_t, int8_t>(0)) == true);
CHECK((canConvertNumber<int16_t, int8_t>(127)) == true);
CHECK((canConvertNumber<int16_t, int8_t>(-128)) == true);
}
SECTION("int8_t -> uint8_t") {
CHECK((canConvertNumber<uint8_t, int8_t>(0)) == true);
CHECK((canConvertNumber<uint8_t, int8_t>(127)) == true);
CHECK((canConvertNumber<uint8_t, int8_t>(-128)) == false);
}
SECTION("int8_t -> uint16_t") {
CHECK((canConvertNumber<uint16_t, int8_t>(0)) == true);
CHECK((canConvertNumber<uint16_t, int8_t>(127)) == true);
CHECK((canConvertNumber<uint16_t, int8_t>(-128)) == false);
}
SECTION("int16_t -> int8_t") {
CHECK((canConvertNumber<int8_t, int16_t>(0)) == true);
CHECK((canConvertNumber<int8_t, int16_t>(127)) == true);
CHECK((canConvertNumber<int8_t, int16_t>(128)) == false);
CHECK((canConvertNumber<int8_t, int16_t>(-128)) == true);
CHECK((canConvertNumber<int8_t, int16_t>(-129)) == false);
}
SECTION("int16_t -> uint8_t") {
CHECK((canConvertNumber<uint8_t, int16_t>(0)) == true);
CHECK((canConvertNumber<uint8_t, int16_t>(255)) == true);
CHECK((canConvertNumber<uint8_t, int16_t>(256)) == false);
CHECK((canConvertNumber<uint8_t, int16_t>(-1)) == false);
}
SECTION("uint8_t -> int8_t") {
CHECK((canConvertNumber<int8_t, uint8_t>(0)) == true);
CHECK((canConvertNumber<int8_t, uint8_t>(127)) == true);
CHECK((canConvertNumber<int8_t, uint8_t>(128)) == false);
CHECK((canConvertNumber<int8_t, uint8_t>(255)) == false);
}
SECTION("uint8_t -> int16_t") {
CHECK((canConvertNumber<int16_t, uint8_t>(0)) == true);
CHECK((canConvertNumber<int16_t, uint8_t>(127)) == true);
CHECK((canConvertNumber<int16_t, uint8_t>(128)) == true);
CHECK((canConvertNumber<int16_t, uint8_t>(255)) == true);
}
SECTION("uint8_t -> uint8_t") {
CHECK((canConvertNumber<uint8_t, uint8_t>(0)) == true);
CHECK((canConvertNumber<uint8_t, uint8_t>(127)) == true);
CHECK((canConvertNumber<uint8_t, uint8_t>(128)) == true);
CHECK((canConvertNumber<uint8_t, uint8_t>(255)) == true);
}
SECTION("uint8_t -> uint16_t") {
CHECK((canConvertNumber<uint16_t, uint8_t>(0)) == true);
CHECK((canConvertNumber<uint16_t, uint8_t>(127)) == true);
CHECK((canConvertNumber<uint16_t, uint8_t>(128)) == true);
CHECK((canConvertNumber<uint16_t, uint8_t>(255)) == true);
}
}

View File

@ -15,4 +15,4 @@ add_test(TextFormatter TextFormatterTests)
set_tests_properties(TextFormatter
PROPERTIES
LABELS "Catch"
)
)

View File

@ -7,7 +7,7 @@
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "6.18.0",
"version": "6.18.1",
"authors": {
"name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr"

View File

@ -1,5 +1,5 @@
name=ArduinoJson
version=6.18.0
version=6.18.1
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=A simple and efficient JSON library for embedded C++.

View File

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

View File

@ -161,6 +161,12 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
_data->removeElement(index);
}
void clear() const {
if (!_data)
return;
_data->clear();
}
private:
MemoryPool* _pool;
};
@ -193,6 +199,8 @@ struct Converter<ArrayRef> {
return ArrayRef(pool, data != 0 ? data->asArray() : 0);
}
static InvalidConversion<VariantConstRef, ArrayRef> fromJson(VariantConstRef);
static bool checkJson(VariantConstRef) {
return false;
}

View File

@ -10,8 +10,8 @@
#include <ArduinoJson/Variant/VariantTo.hpp>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4522)
# pragma warning(push)
# pragma warning(disable : 4522)
#endif
namespace ARDUINOJSON_NAMESPACE {
@ -189,5 +189,5 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
} // namespace ARDUINOJSON_NAMESPACE
#ifdef _MSC_VER
#pragma warning(pop)
# pragma warning(pop)
#endif

View File

@ -5,251 +5,269 @@
#pragma once
#if __cplusplus >= 201103L
#define ARDUINOJSON_HAS_LONG_LONG 1
#define ARDUINOJSON_HAS_NULLPTR 1
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
# define ARDUINOJSON_HAS_LONG_LONG 1
# define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
#else
#define ARDUINOJSON_HAS_LONG_LONG 0
#define ARDUINOJSON_HAS_NULLPTR 0
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
# define ARDUINOJSON_HAS_LONG_LONG 0
# define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
#endif
#ifndef ARDUINOJSON_HAS_NULLPTR
# if __cplusplus >= 201103L
# define ARDUINOJSON_HAS_NULLPTR 1
# else
# define ARDUINOJSON_HAS_NULLPTR 0
# endif
#endif
#if defined(_MSC_VER) && !ARDUINOJSON_HAS_LONG_LONG
#define ARDUINOJSON_HAS_INT64 1
# define ARDUINOJSON_HAS_INT64 1
#else
#define ARDUINOJSON_HAS_INT64 0
# define ARDUINOJSON_HAS_INT64 0
#endif
// Small or big machine?
#ifndef ARDUINOJSON_EMBEDDED_MODE
#if defined(ARDUINO) /* Arduino*/ \
|| defined(__IAR_SYSTEMS_ICC__) /* IAR Embedded Workbench */ \
|| defined(__XC) /* MPLAB XC compiler */ \
|| defined(__ARMCC_VERSION) /* Keil ARM Compiler */ \
|| defined(__AVR) /* Atmel AVR8/GNU C Compiler */
#define ARDUINOJSON_EMBEDDED_MODE 1
#else
#define ARDUINOJSON_EMBEDDED_MODE 0
#endif
# if defined(ARDUINO) /* Arduino*/ \
|| defined(__IAR_SYSTEMS_ICC__) /* IAR Embedded Workbench */ \
|| defined(__XC) /* MPLAB XC compiler */ \
|| defined(__ARMCC_VERSION) /* Keil ARM Compiler */ \
|| defined(__AVR) /* Atmel AVR8/GNU C Compiler */
# define ARDUINOJSON_EMBEDDED_MODE 1
# else
# define ARDUINOJSON_EMBEDDED_MODE 0
# endif
#endif
// Auto enable std::stream if the right headers are here and no conflicting
// macro is defined
#if !defined(ARDUINOJSON_ENABLE_STD_STREAM) && defined(__has_include)
#if __has_include(<istream>) && \
# if __has_include(<istream>) && \
__has_include(<ostream>) && \
!defined(min) && \
!defined(max)
#define ARDUINOJSON_ENABLE_STD_STREAM 1
#else
#define ARDUINOJSON_ENABLE_STD_STREAM 0
#endif
# define ARDUINOJSON_ENABLE_STD_STREAM 1
# else
# define ARDUINOJSON_ENABLE_STD_STREAM 0
# endif
#endif
// Auto enable std::string if the right header is here and no conflicting
// macro is defined
#if !defined(ARDUINOJSON_ENABLE_STD_STRING) && defined(__has_include)
#if __has_include(<string>) && !defined(min) && !defined(max)
#define ARDUINOJSON_ENABLE_STD_STRING 1
#else
#define ARDUINOJSON_ENABLE_STD_STRING 0
# if __has_include(<string>) && !defined(min) && !defined(max)
# define ARDUINOJSON_ENABLE_STD_STRING 1
# else
# define ARDUINOJSON_ENABLE_STD_STRING 0
# endif
#endif
#ifndef ARDUINOJSON_ENABLE_STRING_VIEW
# ifdef __has_include
# if __has_include(<string_view>) && __cplusplus >= 201703L
# define ARDUINOJSON_ENABLE_STRING_VIEW 1
# endif
# endif
#endif
#ifndef ARDUINOJSON_ENABLE_STRING_VIEW
# define ARDUINOJSON_ENABLE_STRING_VIEW 0
#endif
#if ARDUINOJSON_EMBEDDED_MODE
// Store floats by default to reduce the memory usage (issue #134)
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 0
#endif
# ifndef ARDUINOJSON_USE_DOUBLE
# define ARDUINOJSON_USE_DOUBLE 0
# endif
// Store longs by default, because they usually match the size of a float.
#ifndef ARDUINOJSON_USE_LONG_LONG
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
# ifndef ARDUINOJSON_USE_LONG_LONG
# define ARDUINOJSON_USE_LONG_LONG 0
# endif
// Embedded systems usually don't have std::string
#ifndef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 0
#endif
# ifndef ARDUINOJSON_ENABLE_STD_STRING
# define ARDUINOJSON_ENABLE_STD_STRING 0
# endif
// Embedded systems usually don't have std::stream
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 0
#endif
# ifndef ARDUINOJSON_ENABLE_STD_STREAM
# define ARDUINOJSON_ENABLE_STD_STREAM 0
# endif
// Limit nesting as the stack is likely to be small
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
#endif
# ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
# define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
# endif
// Number of bits to store the pointer to next node
// (saves RAM but limits the number of values in a document)
#ifndef ARDUINOJSON_SLOT_OFFSET_SIZE
#if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 2
# ifndef ARDUINOJSON_SLOT_OFFSET_SIZE
# if defined(__SIZEOF_POINTER__) && __SIZEOF_POINTER__ == 2
// Address space == 16-bit => max 127 values
#define ARDUINOJSON_SLOT_OFFSET_SIZE 1
#else
# define ARDUINOJSON_SLOT_OFFSET_SIZE 1
# else
// Address space > 16-bit => max 32767 values
#define ARDUINOJSON_SLOT_OFFSET_SIZE 2
#endif
#endif
# define ARDUINOJSON_SLOT_OFFSET_SIZE 2
# endif
# endif
#else // ARDUINOJSON_EMBEDDED_MODE
// On a computer we have plenty of memory so we can use doubles
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 1
#endif
# ifndef ARDUINOJSON_USE_DOUBLE
# define ARDUINOJSON_USE_DOUBLE 1
# endif
// Use long long when available
#ifndef ARDUINOJSON_USE_LONG_LONG
#if ARDUINOJSON_HAS_LONG_LONG || ARDUINOJSON_HAS_INT64
#define ARDUINOJSON_USE_LONG_LONG 1
#else
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#endif
# ifndef ARDUINOJSON_USE_LONG_LONG
# if ARDUINOJSON_HAS_LONG_LONG || ARDUINOJSON_HAS_INT64
# define ARDUINOJSON_USE_LONG_LONG 1
# else
# define ARDUINOJSON_USE_LONG_LONG 0
# endif
# endif
// On a computer, we can use std::string
#ifndef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 1
#endif
# ifndef ARDUINOJSON_ENABLE_STD_STRING
# define ARDUINOJSON_ENABLE_STD_STRING 1
# endif
// On a computer, we can assume std::stream
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 1
#endif
# ifndef ARDUINOJSON_ENABLE_STD_STREAM
# define ARDUINOJSON_ENABLE_STD_STREAM 1
# endif
// On a computer, the stack is large so we can increase nesting limit
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
#endif
# ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
# define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
# endif
// Number of bits to store the pointer to next node
#ifndef ARDUINOJSON_SLOT_OFFSET_SIZE
#define ARDUINOJSON_SLOT_OFFSET_SIZE 4
#endif
# ifndef ARDUINOJSON_SLOT_OFFSET_SIZE
# define ARDUINOJSON_SLOT_OFFSET_SIZE 4
# endif
#endif // ARDUINOJSON_EMBEDDED_MODE
#ifdef ARDUINO
#include <Arduino.h>
# include <Arduino.h>
// Enable support for Arduino's String class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#endif
# ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
# define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
# endif
// Enable support for Arduino's Stream class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
#endif
# ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
# define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
# endif
// Enable support for Arduino's Print class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
#endif
# ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
# define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
# endif
#else // ARDUINO
// Disable support for Arduino's String class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#endif
# ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
# define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
# endif
// Disable support for Arduino's Stream class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
#endif
# ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
# define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
# endif
// Disable support for Arduino's Print class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
#endif
# ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
# define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
# endif
#endif // ARDUINO
#ifndef ARDUINOJSON_ENABLE_PROGMEM
#if defined(PROGMEM) && defined(pgm_read_byte) && defined(pgm_read_dword) && \
defined(pgm_read_ptr) && defined(pgm_read_float)
#define ARDUINOJSON_ENABLE_PROGMEM 1
#else
#define ARDUINOJSON_ENABLE_PROGMEM 0
#endif
# if defined(PROGMEM) && defined(pgm_read_byte) && defined(pgm_read_dword) && \
defined(pgm_read_ptr) && defined(pgm_read_float)
# define ARDUINOJSON_ENABLE_PROGMEM 1
# else
# define ARDUINOJSON_ENABLE_PROGMEM 0
# endif
#endif
// Convert unicode escape sequence (\u0123) to UTF-8
#ifndef ARDUINOJSON_DECODE_UNICODE
#define ARDUINOJSON_DECODE_UNICODE 1
# define ARDUINOJSON_DECODE_UNICODE 1
#endif
// Ignore comments in input
#ifndef ARDUINOJSON_ENABLE_COMMENTS
#define ARDUINOJSON_ENABLE_COMMENTS 0
# define ARDUINOJSON_ENABLE_COMMENTS 0
#endif
// Support NaN in JSON
#ifndef ARDUINOJSON_ENABLE_NAN
#define ARDUINOJSON_ENABLE_NAN 0
# define ARDUINOJSON_ENABLE_NAN 0
#endif
// Support Infinity in JSON
#ifndef ARDUINOJSON_ENABLE_INFINITY
#define ARDUINOJSON_ENABLE_INFINITY 0
# define ARDUINOJSON_ENABLE_INFINITY 0
#endif
// Control the exponentiation threshold for big numbers
// CAUTION: cannot be more that 1e9 !!!!
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
# define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
#endif
// Control the exponentiation threshold for small numbers
#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
# define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
#endif
#ifndef ARDUINOJSON_LITTLE_ENDIAN
#if defined(_MSC_VER) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
#define ARDUINOJSON_LITTLE_ENDIAN 1
#else
#define ARDUINOJSON_LITTLE_ENDIAN 0
#endif
# if defined(_MSC_VER) || \
(defined(__BYTE_ORDER__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
# define ARDUINOJSON_LITTLE_ENDIAN 1
# else
# define ARDUINOJSON_LITTLE_ENDIAN 0
# endif
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
#if defined(__AVR)
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#else
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
# if defined(__AVR)
# define ARDUINOJSON_ENABLE_ALIGNMENT 0
# else
# define ARDUINOJSON_ENABLE_ALIGNMENT 1
# endif
#endif
#ifndef ARDUINOJSON_TAB
#define ARDUINOJSON_TAB " "
# define ARDUINOJSON_TAB " "
#endif
#ifndef ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1
# define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1
#endif
#ifndef ARDUINOJSON_STRING_BUFFER_SIZE
#define ARDUINOJSON_STRING_BUFFER_SIZE 32
# define ARDUINOJSON_STRING_BUFFER_SIZE 32
#endif
#ifndef ARDUINOJSON_DEBUG
#ifdef __PLATFORMIO_BUILD_DEBUG__
#define ARDUINOJSON_DEBUG 1
#else
#define ARDUINOJSON_DEBUG 0
#endif
# ifdef __PLATFORMIO_BUILD_DEBUG__
# define ARDUINOJSON_DEBUG 1
# else
# define ARDUINOJSON_DEBUG 0
# endif
#endif
#if ARDUINOJSON_HAS_NULLPTR && defined(nullptr)
#error nullptr is defined as a macro. Remove the faulty #define or #undef nullptr
# error nullptr is defined as a macro. Remove the faulty #define or #undef nullptr
// See https://github.com/bblanchon/ArduinoJson/issues/1355
#endif

View File

@ -9,7 +9,7 @@
#include <ArduinoJson/Polyfills/static_array.hpp>
#if ARDUINOJSON_ENABLE_STD_STREAM
#include <ostream>
# include <ostream>
#endif
namespace ARDUINOJSON_NAMESPACE {

View File

@ -40,17 +40,17 @@ struct BoundedReader {
#include <ArduinoJson/Deserialization/Readers/VariantReader.hpp>
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
#include <ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp>
# include <ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp>
#endif
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
#include <ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp>
# include <ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp>
#endif
#if ARDUINOJSON_ENABLE_PROGMEM
#include <ArduinoJson/Deserialization/Readers/FlashReader.hpp>
# include <ArduinoJson/Deserialization/Readers/FlashReader.hpp>
#endif
#if ARDUINOJSON_ENABLE_STD_STREAM
#include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp>
# include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp>
#endif

View File

@ -32,7 +32,7 @@ class JsonDocument : public Visitable {
void clear() {
_pool.clear();
_data.setNull();
_data.init();
}
template <typename T>
@ -304,15 +304,15 @@ class JsonDocument : public Visitable {
protected:
JsonDocument() : _pool(0, 0) {
_data.setNull();
_data.init();
}
JsonDocument(MemoryPool pool) : _pool(pool) {
_data.setNull();
_data.init();
}
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
_data.setNull();
_data.init();
}
~JsonDocument() {}

View File

@ -45,7 +45,8 @@ class Latch {
}
TReader _reader;
char _current;
char _current; // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
// Not initialized in constructor (+10 bytes on AVR)
bool _loaded;
#if ARDUINOJSON_DEBUG
bool _ended;

View File

@ -155,7 +155,6 @@ class TextFormatter {
protected:
CountingDecorator<TWriter> _writer;
size_t _length;
private:
TextFormatter &operator=(const TextFormatter &); // cannot be assigned

View File

@ -12,10 +12,10 @@
// we choose to ignore the problem to reduce the size of the code
// Garbage in => Garbage out
#if defined(__GNUC__)
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif
# if __GNUC__ >= 7
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
# endif
#endif
namespace ARDUINOJSON_NAMESPACE {
@ -31,7 +31,7 @@ inline bool isLowSurrogate(uint16_t codeunit) {
class Codepoint {
public:
Codepoint() : _highSurrogate(0) {}
Codepoint() : _highSurrogate(0), _codepoint(0) {}
bool append(uint16_t codeunit) {
if (isHighSurrogate(codeunit)) {
@ -61,7 +61,7 @@ class Codepoint {
} // namespace ARDUINOJSON_NAMESPACE
#if defined(__GNUC__)
#if __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
# if __GNUC__ >= 8
# pragma GCC diagnostic pop
# endif
#endif

View File

@ -7,6 +7,7 @@
#include <ArduinoJson/Memory/Alignment.hpp>
#include <ArduinoJson/Polyfills/assert.hpp>
#include <ArduinoJson/Polyfills/mpl/max.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp>
#include <ArduinoJson/Variant/VariantSlot.hpp>
#include <string.h> // memmove
@ -37,7 +38,8 @@ class MemoryPool {
}
void* buffer() {
return _begin;
return _begin; // NOLINT(clang-analyzer-unix.Malloc)
// movePointers() alters this pointer
}
// Gets the capacity of the memoryPool in bytes
@ -63,7 +65,7 @@ class MemoryPool {
return 0;
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
const char* existingCopy = findString(str.begin());
const char* existingCopy = findString(str);
if (existingCopy)
return existingCopy;
#endif
@ -85,7 +87,7 @@ class MemoryPool {
const char* saveStringFromFreeZone(size_t len) {
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
const char* dup = findString(_left);
const char* dup = findString(adaptString(_left));
if (dup)
return dup;
#endif
@ -162,16 +164,11 @@ class MemoryPool {
}
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
template <typename TIterator>
const char* findString(TIterator str) {
template <typename TAdaptedString>
const char* findString(const TAdaptedString& str) {
for (char* next = _begin; next < _left; ++next) {
char* begin = next;
// try to match
for (TIterator it = str; *it == *next; ++it) {
if (*next++ == 0)
return begin;
}
if (str.equals(next))
return next;
// jump to next terminator
while (*next) ++next;

View File

@ -32,9 +32,6 @@ class MsgPackDeserializer {
}
private:
// Prevent VS warning "assignment operator could not be generated"
MsgPackDeserializer &operator=(const MsgPackDeserializer &);
bool invalidInput() {
_error = DeserializationError::InvalidInput;
return false;

View File

@ -10,17 +10,17 @@
#ifndef ARDUINOJSON_NAMESPACE
#define ARDUINOJSON_NAMESPACE \
ARDUINOJSON_CONCAT4( \
ARDUINOJSON_CONCAT4(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
ARDUINOJSON_VERSION_MINOR, \
ARDUINOJSON_VERSION_REVISION), \
_, \
ARDUINOJSON_HEX_DIGIT(ARDUINOJSON_ENABLE_PROGMEM, \
ARDUINOJSON_USE_LONG_LONG, ARDUINOJSON_USE_DOUBLE, \
ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \
ARDUINOJSON_HEX_DIGIT( \
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE))
# define ARDUINOJSON_NAMESPACE \
ARDUINOJSON_CONCAT4( \
ARDUINOJSON_CONCAT4(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
ARDUINOJSON_VERSION_MINOR, \
ARDUINOJSON_VERSION_REVISION), \
_, \
ARDUINOJSON_HEX_DIGIT( \
ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_USE_LONG_LONG, \
ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \
ARDUINOJSON_HEX_DIGIT( \
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE))
#endif

View File

@ -22,11 +22,11 @@ typedef unsigned long UInt;
} // namespace ARDUINOJSON_NAMESPACE
#if ARDUINOJSON_HAS_LONG_LONG && !ARDUINOJSON_USE_LONG_LONG
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
static_assert(sizeof(T) <= sizeof(ARDUINOJSON_NAMESPACE::Integer), \
"To use 64-bit integers with ArduinoJson, you must set " \
"ARDUINOJSON_USE_LONG_LONG to 1. See " \
"https://arduinojson.org/v6/api/config/use_long_long/");
# define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
static_assert(sizeof(T) <= sizeof(ARDUINOJSON_NAMESPACE::Integer), \
"To use 64-bit integers with ArduinoJson, you must set " \
"ARDUINOJSON_USE_LONG_LONG to 1. See " \
"https://arduinojson.org/v6/api/config/use_long_long/");
#else
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T)
# define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T)
#endif

View File

@ -5,13 +5,13 @@
#pragma once
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wconversion"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wconversion"
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
# pragma GCC diagnostic push
# endif
# pragma GCC diagnostic ignored "-Wconversion"
#endif
#include <ArduinoJson/Numbers/Float.hpp>
@ -71,9 +71,23 @@ canConvertNumber(TIn) {
}
// int32 -> uint32
// int32 -> uint64
template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
is_integral<TOut>::value && is_unsigned<TOut>::value,
is_integral<TOut>::value && is_unsigned<TOut>::value &&
sizeof(TOut) >= sizeof(TIn),
bool>::type
canConvertNumber(TIn value) {
if (value < 0)
return false;
return TOut(value) <= numeric_limits<TOut>::highest();
}
// int32 -> uint16
template <typename TOut, typename TIn>
typename enable_if<is_integral<TIn>::value && is_signed<TIn>::value &&
is_integral<TOut>::value && is_unsigned<TOut>::value &&
sizeof(TOut) < sizeof(TIn),
bool>::type
canConvertNumber(TIn value) {
if (value < 0)
@ -99,9 +113,9 @@ TOut convertNumber(TIn value) {
} // namespace ARDUINOJSON_NAMESPACE
#if defined(__clang__)
#pragma clang diagnostic pop
# pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
# pragma GCC diagnostic pop
# endif
#endif

View File

@ -12,8 +12,8 @@
#include <ArduinoJson/Variant/VariantTo.hpp>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4522)
# pragma warning(push)
# pragma warning(disable : 4522)
#endif
namespace ARDUINOJSON_NAMESPACE {
@ -198,5 +198,5 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
} // namespace ARDUINOJSON_NAMESPACE
#ifdef _MSC_VER
#pragma warning(pop)
# pragma warning(pop)
#endif

View File

@ -265,6 +265,9 @@ struct Converter<ObjectRef> {
return ObjectRef(pool, data != 0 ? data->asObject() : 0);
}
static InvalidConversion<VariantConstRef, ObjectRef> fromJson(
VariantConstRef);
static bool checkJson(VariantConstRef) {
return false;
}

View File

@ -7,8 +7,8 @@
#include <ArduinoJson/Configuration.hpp>
#if ARDUINOJSON_DEBUG
#include <assert.h>
#define ARDUINOJSON_ASSERT(X) assert(X)
# include <assert.h>
# define ARDUINOJSON_ASSERT(X) assert(X)
#else
#define ARDUINOJSON_ASSERT(X) ((void)0)
# define ARDUINOJSON_ASSERT(X) ((void)0)
#endif

View File

@ -6,49 +6,49 @@
#ifdef _MSC_VER // Visual Studio
#define FORCE_INLINE // __forceinline causes C4714 when returning std::string
#define NO_INLINE __declspec(noinline)
# define FORCE_INLINE // __forceinline causes C4714 when returning std::string
# define NO_INLINE __declspec(noinline)
#ifndef ARDUINOJSON_DEPRECATED
#define ARDUINOJSON_DEPRECATED(msg) __declspec(deprecated(msg))
#endif
# ifndef ARDUINOJSON_DEPRECATED
# define ARDUINOJSON_DEPRECATED(msg) __declspec(deprecated(msg))
# endif
#elif defined(__GNUC__) // GCC or Clang
#define FORCE_INLINE __attribute__((always_inline))
#define NO_INLINE __attribute__((noinline))
# define FORCE_INLINE __attribute__((always_inline))
# define NO_INLINE __attribute__((noinline))
#ifndef ARDUINOJSON_DEPRECATED
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
#define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated(msg)))
#else
#define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated))
#endif
#endif
# ifndef ARDUINOJSON_DEPRECATED
# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
# define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated(msg)))
# else
# define ARDUINOJSON_DEPRECATED(msg) __attribute__((deprecated))
# endif
# endif
#else // Other compilers
#define FORCE_INLINE
#define NO_INLINE
# define FORCE_INLINE
# define NO_INLINE
#ifndef ARDUINOJSON_DEPRECATED
#define ARDUINOJSON_DEPRECATED(msg)
#endif
# ifndef ARDUINOJSON_DEPRECATED
# define ARDUINOJSON_DEPRECATED(msg)
# endif
#endif
#if __cplusplus >= 201103L
#define NOEXCEPT noexcept
# define NOEXCEPT noexcept
#else
#define NOEXCEPT throw()
# define NOEXCEPT throw()
#endif
#if defined(__has_attribute)
#if __has_attribute(no_sanitize)
#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
# if __has_attribute(no_sanitize)
# define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
# else
# define ARDUINOJSON_NO_SANITIZE(check)
# endif
#else
#define ARDUINOJSON_NO_SANITIZE(check)
#endif
#else
#define ARDUINOJSON_NO_SANITIZE(check)
# define ARDUINOJSON_NO_SANITIZE(check)
#endif

View File

@ -7,8 +7,8 @@
#include "type_traits.hpp"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4310)
# pragma warning(push)
# pragma warning(disable : 4310)
#endif
namespace ARDUINOJSON_NAMESPACE {
@ -41,5 +41,5 @@ struct numeric_limits<
} // namespace ARDUINOJSON_NAMESPACE
#ifdef _MSC_VER
#pragma warning(pop)
# pragma warning(pop)
#endif

View File

@ -8,27 +8,27 @@
#if ARDUINOJSON_ENABLE_PROGMEM
#include <ArduinoJson/Polyfills/pgmspace_generic.hpp>
# include <ArduinoJson/Polyfills/pgmspace_generic.hpp>
#ifndef ARDUINOJSON_DEFINE_STATIC_ARRAY
#define ARDUINOJSON_DEFINE_STATIC_ARRAY(type, name, value) \
static type const name[] PROGMEM = value;
#endif
# ifndef ARDUINOJSON_DEFINE_STATIC_ARRAY
# define ARDUINOJSON_DEFINE_STATIC_ARRAY(type, name, value) \
static type const name[] PROGMEM = value;
# endif
#ifndef ARDUINOJSON_READ_STATIC_ARRAY
#define ARDUINOJSON_READ_STATIC_ARRAY(type, name, index) \
pgm_read<type>(name + index)
#endif
# ifndef ARDUINOJSON_READ_STATIC_ARRAY
# define ARDUINOJSON_READ_STATIC_ARRAY(type, name, index) \
pgm_read<type>(name + index)
# endif
#else // i.e. ARDUINOJSON_ENABLE_PROGMEM == 0
#ifndef ARDUINOJSON_DEFINE_STATIC_ARRAY
#define ARDUINOJSON_DEFINE_STATIC_ARRAY(type, name, value) \
static type const name[] = value;
#endif
# ifndef ARDUINOJSON_DEFINE_STATIC_ARRAY
# define ARDUINOJSON_DEFINE_STATIC_ARRAY(type, name, value) \
static type const name[] = value;
# endif
#ifndef ARDUINOJSON_READ_STATIC_ARRAY
#define ARDUINOJSON_READ_STATIC_ARRAY(type, name, index) name[index]
#endif
# ifndef ARDUINOJSON_READ_STATIC_ARRAY
# define ARDUINOJSON_READ_STATIC_ARRAY(type, name, index) name[index]
# endif
#endif

View File

@ -7,9 +7,9 @@
#include "declval.hpp"
#ifdef _MSC_VER
#pragma warning(push)
# pragma warning(push)
// conversion from 'T' to 'To', possible loss of data
#pragma warning(disable : 4244)
# pragma warning(disable : 4244)
#endif
// clang-format off
@ -37,7 +37,7 @@ struct is_convertible {
} // namespace ARDUINOJSON_NAMESPACE
#ifdef _MSC_VER
#pragma warning(pop)
# pragma warning(pop)
#endif
// clang-format off

View File

@ -5,15 +5,16 @@
#pragma once
#include "integral_constant.hpp"
#include "is_same.hpp"
#include "remove_cv.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename>
struct is_floating_point : false_type {};
template <class T>
struct is_floating_point
: integral_constant<
bool, //
is_same<float, typename remove_cv<T>::type>::value ||
is_same<double, typename remove_cv<T>::type>::value> {};
template <>
struct is_floating_point<float> : true_type {};
template <>
struct is_floating_point<double> : true_type {};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -5,29 +5,33 @@
#pragma once
#include <ArduinoJson/Configuration.hpp>
#include "integral_constant.hpp"
#include "is_same.hpp"
#include "remove_cv.hpp"
namespace ARDUINOJSON_NAMESPACE {
// A meta-function that returns true if T is an integral type.
// clang-format off
template <typename T>
struct is_integral {
static const bool value =
is_same<T, signed char>::value || is_same<T, unsigned char>::value ||
is_same<T, signed short>::value || is_same<T, unsigned short>::value ||
is_same<T, signed int>::value || is_same<T, unsigned int>::value ||
is_same<T, signed long>::value || is_same<T, unsigned long>::value ||
struct is_integral : integral_constant<bool,
is_same<typename remove_cv<T>::type, signed char>::value ||
is_same<typename remove_cv<T>::type, unsigned char>::value ||
is_same<typename remove_cv<T>::type, signed short>::value ||
is_same<typename remove_cv<T>::type, unsigned short>::value ||
is_same<typename remove_cv<T>::type, signed int>::value ||
is_same<typename remove_cv<T>::type, unsigned int>::value ||
is_same<typename remove_cv<T>::type, signed long>::value ||
is_same<typename remove_cv<T>::type, unsigned long>::value ||
#if ARDUINOJSON_HAS_LONG_LONG
is_same<T, signed long long>::value ||
is_same<T, unsigned long long>::value ||
is_same<typename remove_cv<T>::type, signed long long>::value ||
is_same<typename remove_cv<T>::type, unsigned long long>::value ||
#endif
#if ARDUINOJSON_HAS_INT64
is_same<T, signed __int64>::value ||
is_same<T, unsigned __int64>::value ||
is_same<typename remove_cv<T>::type, signed __int64>::value ||
is_same<typename remove_cv<T>::type, unsigned __int64>::value ||
#endif
is_same<T, char>::value || is_same<T, bool>::value;
};
template <typename T>
struct is_integral<const T> : is_integral<T> {};
is_same<typename remove_cv<T>::type, char>::value ||
is_same<typename remove_cv<T>::type, bool>::value> {};
// clang-format on
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -5,39 +5,26 @@
#pragma once
#include "integral_constant.hpp"
#include "is_same.hpp"
#include "remove_cv.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename>
struct is_signed : false_type {};
template <>
struct is_signed<char> : true_type {};
template <>
struct is_signed<signed char> : true_type {};
template <>
struct is_signed<signed short> : true_type {};
template <>
struct is_signed<signed int> : true_type {};
template <>
struct is_signed<signed long> : true_type {};
template <>
struct is_signed<float> : true_type {};
template <>
struct is_signed<double> : true_type {};
// clang-format off
template <typename T>
struct is_signed : integral_constant<bool,
is_same<typename remove_cv<T>::type, char>::value ||
is_same<typename remove_cv<T>::type, signed char>::value ||
is_same<typename remove_cv<T>::type, signed short>::value ||
is_same<typename remove_cv<T>::type, signed int>::value ||
is_same<typename remove_cv<T>::type, signed long>::value ||
#if ARDUINOJSON_HAS_LONG_LONG
template <>
struct is_signed<signed long long> : true_type {};
is_same<typename remove_cv<T>::type, signed long long>::value ||
#endif
#if ARDUINOJSON_HAS_INT64
template <>
struct is_signed<signed __int64> : true_type {};
is_same<typename remove_cv<T>::type, signed __int64>::value ||
#endif
is_same<typename remove_cv<T>::type, float>::value ||
is_same<typename remove_cv<T>::type, double>::value> {};
// clang-format on
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -5,33 +5,24 @@
#pragma once
#include "integral_constant.hpp"
#include "is_same.hpp"
#include "remove_cv.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename>
struct is_unsigned : false_type {};
template <>
struct is_unsigned<bool> : true_type {};
template <>
struct is_unsigned<unsigned char> : true_type {};
template <>
struct is_unsigned<unsigned short> : true_type {};
template <>
struct is_unsigned<unsigned int> : true_type {};
template <>
struct is_unsigned<unsigned long> : true_type {};
// clang-format off
template <typename T>
struct is_unsigned : integral_constant<bool,
is_same<typename remove_cv<T>::type, unsigned char>::value ||
is_same<typename remove_cv<T>::type, unsigned short>::value ||
is_same<typename remove_cv<T>::type, unsigned int>::value ||
is_same<typename remove_cv<T>::type, unsigned long>::value ||
#if ARDUINOJSON_HAS_INT64
template <>
struct is_unsigned<unsigned __int64> : true_type {};
is_same<typename remove_cv<T>::type, unsigned __int64>::value ||
#endif
#if ARDUINOJSON_HAS_LONG_LONG
template <>
struct is_unsigned<unsigned long long> : true_type {};
is_same<typename remove_cv<T>::type, unsigned long long>::value ||
#endif
is_same<typename remove_cv<T>::type, bool>::value> {};
// clang-format on
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -0,0 +1,27 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Namespace.hpp>
namespace ARDUINOJSON_NAMESPACE {
template <typename T>
struct remove_cv {
typedef T type;
};
template <typename T>
struct remove_cv<const T> {
typedef T type;
};
template <typename T>
struct remove_cv<volatile T> {
typedef T type;
};
template <typename T>
struct remove_cv<const volatile T> {
typedef T type;
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -31,17 +31,17 @@ class Writer {
#include <ArduinoJson/Serialization/Writers/StaticStringWriter.hpp>
#if ARDUINOJSON_ENABLE_STD_STRING
#include <ArduinoJson/Serialization/Writers/StdStringWriter.hpp>
# include <ArduinoJson/Serialization/Writers/StdStringWriter.hpp>
#endif
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
#include <ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp>
# include <ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp>
#endif
#if ARDUINOJSON_ENABLE_STD_STREAM
#include <ArduinoJson/Serialization/Writers/StdStreamWriter.hpp>
# include <ArduinoJson/Serialization/Writers/StdStreamWriter.hpp>
#endif
#if ARDUINOJSON_ENABLE_ARDUINO_PRINT
#include <ArduinoJson/Serialization/Writers/PrintWriter.hpp>
# include <ArduinoJson/Serialization/Writers/PrintWriter.hpp>
#endif

View File

@ -22,10 +22,10 @@ class Writer< ::String, void> {
}
size_t write(uint8_t c) {
ARDUINOJSON_ASSERT(_size < bufferCapacity);
_buffer[_size++] = static_cast<char>(c);
if (_size + 1 >= bufferCapacity)
flush();
if (flush() != 0)
return 0;
_buffer[_size++] = static_cast<char>(c);
return 1;
}
@ -36,14 +36,15 @@ class Writer< ::String, void> {
return n;
}
private:
void flush() {
size_t flush() {
ARDUINOJSON_ASSERT(_size < bufferCapacity);
_buffer[_size] = 0;
*_destination += _buffer;
_size = 0;
if (_destination->concat(_buffer))
_size = 0;
return _size;
}
private:
::String *_destination;
char _buffer[bufferCapacity];
size_t _size;

View File

@ -55,8 +55,12 @@ class StringCopier {
private:
MemoryPool* _pool;
// These fields aren't initialized by the constructor but startString()
//
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
char* _ptr;
size_t _size;
size_t _capacity;
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
size_t _size, _capacity;
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -39,10 +39,6 @@ class ArduinoStringAdapter {
return _str->length();
}
const char* begin() const {
return _str->c_str();
}
typedef storage_policies::store_by_copy storage_policy;
private:

View File

@ -39,10 +39,6 @@ class ConstRamStringAdapter {
return _str;
}
const char* begin() const {
return _str;
}
typedef storage_policies::store_by_address storage_policy;
protected:

View File

@ -5,7 +5,6 @@
#pragma once
#include <ArduinoJson/Polyfills/pgmspace.hpp>
#include <ArduinoJson/Strings/FlashStringIterator.hpp>
#include <ArduinoJson/Strings/IsString.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
@ -43,10 +42,6 @@ class FlashStringAdapter {
return strlen_P(reinterpret_cast<const char*>(_str));
}
FlashStringIterator begin() const {
return FlashStringIterator(_str);
}
typedef storage_policies::store_by_copy storage_policy;
private:

View File

@ -1,44 +0,0 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
namespace ARDUINOJSON_NAMESPACE {
class FlashStringIterator {
public:
explicit FlashStringIterator(const __FlashStringHelper* ptr)
: _ptr(reinterpret_cast<const char*>(ptr)) {}
explicit FlashStringIterator(const char* ptr) : _ptr(ptr) {}
FlashStringIterator operator+(ptrdiff_t d) const {
return FlashStringIterator(_ptr + d);
}
ptrdiff_t operator-(FlashStringIterator other) const {
return _ptr - other._ptr;
}
FlashStringIterator operator++(int) {
return FlashStringIterator(_ptr++);
}
FlashStringIterator operator++() {
return FlashStringIterator(++_ptr);
}
bool operator!=(FlashStringIterator other) const {
return _ptr != other._ptr;
}
char operator*() const {
return char(pgm_read_byte(_ptr));
}
private:
const char* _ptr;
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -8,11 +8,11 @@
#include <ArduinoJson/Polyfills/type_traits.hpp>
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
#include <Arduino.h>
# include <Arduino.h>
#endif
#if ARDUINOJSON_ENABLE_STD_STRING
#include <string>
# include <string>
#endif
namespace ARDUINOJSON_NAMESPACE {

View File

@ -5,7 +5,6 @@
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Strings/FlashStringIterator.hpp>
#include <ArduinoJson/Strings/IsString.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
@ -42,10 +41,6 @@ class SizedFlashStringAdapter {
return _size;
}
FlashStringIterator begin() const {
return FlashStringIterator(_str);
}
typedef storage_policies::store_by_copy storage_policy;
private:

View File

@ -36,10 +36,6 @@ class SizedRamStringAdapter {
return _size;
}
const char* begin() const {
return _str;
}
typedef storage_policies::store_by_copy storage_policy;
private:

View File

@ -41,10 +41,6 @@ class StdStringAdapter {
return _str->size();
}
const char* begin() const {
return _str->c_str();
}
typedef storage_policies::store_by_copy storage_policy;
private:

View File

@ -9,14 +9,18 @@
#include <ArduinoJson/Strings/SizedRamStringAdapter.hpp>
#if ARDUINOJSON_ENABLE_STD_STRING
#include <ArduinoJson/Strings/StdStringAdapter.hpp>
# include <ArduinoJson/Strings/StdStringAdapter.hpp>
#endif
#if ARDUINOJSON_ENABLE_STRING_VIEW
# include <ArduinoJson/Strings/StringViewAdapter.hpp>
#endif
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
#include <ArduinoJson/Strings/ArduinoStringAdapter.hpp>
# include <ArduinoJson/Strings/ArduinoStringAdapter.hpp>
#endif
#if ARDUINOJSON_ENABLE_PROGMEM
#include <ArduinoJson/Strings/FlashStringAdapter.hpp>
#include <ArduinoJson/Strings/SizedFlashStringAdapter.hpp>
# include <ArduinoJson/Strings/FlashStringAdapter.hpp>
# include <ArduinoJson/Strings/SizedFlashStringAdapter.hpp>
#endif

View File

@ -0,0 +1,56 @@
// ArduinoJson - https://arduinojson.org
// Copyright Benoit Blanchon 2014-2021
// MIT License
#pragma once
#include <ArduinoJson/Namespace.hpp>
#include <ArduinoJson/Strings/IsString.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <string_view>
namespace ARDUINOJSON_NAMESPACE {
class StringViewAdapter {
public:
StringViewAdapter(std::string_view str) : _str(str) {}
void copyTo(char* p, size_t n) const {
memcpy(p, _str.data(), n);
}
bool isNull() const {
return false;
}
int compare(const char* other) const {
if (!other)
return 1;
return _str.compare(other);
}
bool equals(const char* expected) const {
if (!expected)
return false;
return _str == expected;
}
size_t size() const {
return _str.size();
}
typedef storage_policies::store_by_copy storage_policy;
private:
std::string_view _str;
};
template <>
struct IsString<std::string_view> : true_type {};
inline StringViewAdapter adaptString(const std::string_view& str) {
return StringViewAdapter(str);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -9,4 +9,9 @@ namespace ARDUINOJSON_NAMESPACE {
template <typename T, typename Enable = void>
struct Converter;
// clang-format off
template <typename T1, typename T2>
class InvalidConversion; // Error here? See https://arduinojson.org/v6/invalid-conversion/
// clang-format on
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -13,11 +13,11 @@
// VariantData can't have a constructor (to be a POD), so we have no way to fix
// this warning
#if defined(__GNUC__)
#if __GNUC__ >= 7
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#pragma GCC diagnostic ignored "-Wuninitialized"
#endif
# if __GNUC__ >= 7
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
# pragma GCC diagnostic ignored "-Wuninitialized"
# endif
#endif
namespace ARDUINOJSON_NAMESPACE {
@ -33,7 +33,7 @@ class VariantData {
// - no virtual
// - no inheritance
void init() {
_flags = 0;
_flags = VALUE_IS_NULL;
}
template <typename TVisitor>
@ -362,7 +362,7 @@ class VariantData {
} // namespace ARDUINOJSON_NAMESPACE
#if defined(__GNUC__)
#if __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
# if __GNUC__ >= 8
# pragma GCC diagnostic pop
# endif
#endif

View File

@ -140,4 +140,9 @@ inline VariantConstRef operator|(VariantConstRef preferedValue,
VariantConstRef defaultValue) {
return preferedValue ? preferedValue : defaultValue;
}
// Out of class definition to avoid #1560
inline bool VariantRef::set(char value) const {
return set<signed char>(value);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -88,11 +88,9 @@ class VariantRef : public VariantRefBase<VariantData>,
return Converter<T>::toJson(value, *this);
}
FORCE_INLINE bool ARDUINOJSON_DEPRECATED(
bool ARDUINOJSON_DEPRECATED(
"Support for char is deprecated, use int8_t or uint8_t instead")
set(char value) const {
return set<signed char>(value);
}
set(char value) const;
template <typename T>
FORCE_INLINE bool set(T *value) const {
@ -344,13 +342,19 @@ struct Converter<VariantRef> {
static bool toJson(VariantRef src, VariantRef dst) {
return variantCopyFrom(getData(dst), getData(src), getPool(dst));
}
static VariantRef fromJson(VariantRef src) {
return src;
}
static InvalidConversion<VariantConstRef, VariantRef> fromJson(
VariantConstRef);
static bool checkJson(VariantRef src) {
VariantData *data = getData(src);
return !!data;
}
static bool checkJson(VariantConstRef) {
return false;
}

View File

@ -4,7 +4,7 @@
#pragma once
#define ARDUINOJSON_VERSION "6.18.0"
#define ARDUINOJSON_VERSION "6.18.1"
#define ARDUINOJSON_VERSION_MAJOR 6
#define ARDUINOJSON_VERSION_MINOR 18
#define ARDUINOJSON_VERSION_REVISION 0
#define ARDUINOJSON_VERSION_REVISION 1