Newer libraries added.

dev
Holger Wirtz 1 year ago
parent 7b601dc00b
commit c8a8959419
  1. 2
      config.h
  2. 22
      third-party/ArduinoJson/CHANGELOG.md
  3. 2
      third-party/ArduinoJson/CMakeLists.txt
  4. 8
      third-party/ArduinoJson/README.md
  5. 2
      third-party/ArduinoJson/appveyor.yml
  6. 2
      third-party/ArduinoJson/examples/JsonFilterExample/JsonFilterExample.ino
  7. 2
      third-party/ArduinoJson/extras/conf_test/avr.cpp
  8. 4
      third-party/ArduinoJson/extras/scripts/get-release-page.sh
  9. 4
      third-party/ArduinoJson/extras/scripts/publish-particle-library.sh
  10. 4
      third-party/ArduinoJson/extras/scripts/publish.sh
  11. 4
      third-party/ArduinoJson/extras/scripts/wandbox/publish.sh
  12. 2
      third-party/ArduinoJson/extras/tests/Helpers/Arduino.h
  13. 10
      third-party/ArduinoJson/extras/tests/Helpers/CustomReader.hpp
  14. 31
      third-party/ArduinoJson/extras/tests/Helpers/avr/pgmspace.h
  15. 2
      third-party/ArduinoJson/extras/tests/IntegrationTests/CMakeLists.txt
  16. 24
      third-party/ArduinoJson/extras/tests/JsonDeserializer/input_types.cpp
  17. 18
      third-party/ArduinoJson/extras/tests/JsonDocument/BasicJsonDocument.cpp
  18. 28
      third-party/ArduinoJson/extras/tests/JsonDocument/shrinkToFit.cpp
  19. 8
      third-party/ArduinoJson/extras/tests/JsonSerializer/CustomWriter.cpp
  20. 21
      third-party/ArduinoJson/extras/tests/JsonVariant/converters.cpp
  21. 5
      third-party/ArduinoJson/extras/tests/JsonVariant/misc.cpp
  22. 10
      third-party/ArduinoJson/extras/tests/Misc/Readers.cpp
  23. 9
      third-party/ArduinoJson/extras/tests/Misc/StringAdapters.cpp
  24. 5
      third-party/ArduinoJson/extras/tests/Misc/StringWriter.cpp
  25. 6
      third-party/ArduinoJson/extras/tests/Misc/conflicts.cpp
  26. 12
      third-party/ArduinoJson/extras/tests/Misc/printable.cpp
  27. 2
      third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_progmem_1.cpp
  28. 2
      third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_string_deduplication_0.cpp
  29. 2
      third-party/ArduinoJson/extras/tests/MixedConfiguration/enable_string_deduplication_1.cpp
  30. 2
      third-party/ArduinoJson/extras/tests/MixedConfiguration/issue1707.cpp
  31. 5
      third-party/ArduinoJson/extras/tests/Numbers/parseNumber.cpp
  32. 3
      third-party/ArduinoJson/idf_component.yml
  33. 3
      third-party/ArduinoJson/library.json
  34. 2
      third-party/ArduinoJson/library.properties
  35. 3
      third-party/ArduinoJson/src/ArduinoJson.hpp
  36. 16
      third-party/ArduinoJson/src/ArduinoJson/Array/ElementProxy.hpp
  37. 58
      third-party/ArduinoJson/src/ArduinoJson/Array/JsonArray.hpp
  38. 30
      third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayConst.hpp
  39. 54
      third-party/ArduinoJson/src/ArduinoJson/Array/JsonArrayIterator.hpp
  40. 6
      third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionData.hpp
  41. 42
      third-party/ArduinoJson/src/ArduinoJson/Collection/CollectionImpl.hpp
  42. 6
      third-party/ArduinoJson/src/ArduinoJson/Configuration.hpp
  43. 26
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/DeserializationError.hpp
  44. 18
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/Filter.hpp
  45. 12
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/NestingLimit.hpp
  46. 10
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/Reader.hpp
  47. 10
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp
  48. 28
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/FlashReader.hpp
  49. 12
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/IteratorReader.hpp
  50. 8
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/RamReader.hpp
  51. 10
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp
  52. 15
      third-party/ArduinoJson/src/ArduinoJson/Deserialization/deserialize.hpp
  53. 33
      third-party/ArduinoJson/src/ArduinoJson/Document/BasicJsonDocument.hpp
  54. 62
      third-party/ArduinoJson/src/ArduinoJson/Document/JsonDocument.hpp
  55. 12
      third-party/ArduinoJson/src/ArduinoJson/Document/StaticJsonDocument.hpp
  56. 60
      third-party/ArduinoJson/src/ArduinoJson/Json/JsonDeserializer.hpp
  57. 28
      third-party/ArduinoJson/src/ArduinoJson/Json/JsonSerializer.hpp
  58. 30
      third-party/ArduinoJson/src/ArduinoJson/Json/Latch.hpp
  59. 14
      third-party/ArduinoJson/src/ArduinoJson/Json/PrettyJsonSerializer.hpp
  60. 16
      third-party/ArduinoJson/src/ArduinoJson/Json/TextFormatter.hpp
  61. 16
      third-party/ArduinoJson/src/ArduinoJson/Json/Utf16.hpp
  62. 104
      third-party/ArduinoJson/src/ArduinoJson/Memory/MemoryPool.hpp
  63. 22
      third-party/ArduinoJson/src/ArduinoJson/Misc/SerializedValue.hpp
  64. 42
      third-party/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp
  65. 12
      third-party/ArduinoJson/src/ArduinoJson/MsgPack/MsgPackSerializer.hpp
  66. 9
      third-party/ArduinoJson/src/ArduinoJson/Namespace.hpp
  67. 1
      third-party/ArduinoJson/src/ArduinoJson/Numbers/parseNumber.hpp
  68. 58
      third-party/ArduinoJson/src/ArduinoJson/Object/JsonObject.hpp
  69. 32
      third-party/ArduinoJson/src/ArduinoJson/Object/JsonObjectConst.hpp
  70. 54
      third-party/ArduinoJson/src/ArduinoJson/Object/JsonObjectIterator.hpp
  71. 24
      third-party/ArduinoJson/src/ArduinoJson/Object/JsonPair.hpp
  72. 20
      third-party/ArduinoJson/src/ArduinoJson/Object/MemberProxy.hpp
  73. 8
      third-party/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace.hpp
  74. 6
      third-party/ArduinoJson/src/ArduinoJson/Polyfills/pgmspace_generic.hpp
  75. 4
      third-party/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp
  76. 4
      third-party/ArduinoJson/src/ArduinoJson/Polyfills/type_traits/is_convertible.hpp
  77. 12
      third-party/ArduinoJson/src/ArduinoJson/Serialization/CountingDecorator.hpp
  78. 8
      third-party/ArduinoJson/src/ArduinoJson/Serialization/Writer.hpp
  79. 24
      third-party/ArduinoJson/src/ArduinoJson/Serialization/Writers/ArduinoStringWriter.hpp
  80. 8
      third-party/ArduinoJson/src/ArduinoJson/Serialization/Writers/PrintWriter.hpp
  81. 8
      third-party/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStreamWriter.hpp
  82. 8
      third-party/ArduinoJson/src/ArduinoJson/Serialization/Writers/StdStringWriter.hpp
  83. 40
      third-party/ArduinoJson/src/ArduinoJson/StringStorage/StringCopier.hpp
  84. 18
      third-party/ArduinoJson/src/ArduinoJson/StringStorage/StringMover.hpp
  85. 24
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/FlashString.hpp
  86. 6
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/JsonString.hpp
  87. 32
      third-party/ArduinoJson/src/ArduinoJson/Strings/Adapters/RamString.hpp
  88. 32
      third-party/ArduinoJson/src/ArduinoJson/Strings/JsonString.hpp
  89. 30
      third-party/ArduinoJson/src/ArduinoJson/Variant/ConverterImpl.hpp
  90. 14
      third-party/ArduinoJson/src/ArduinoJson/Variant/JsonVariant.hpp
  91. 24
      third-party/ArduinoJson/src/ArduinoJson/Variant/JsonVariantConst.hpp
  92. 8
      third-party/ArduinoJson/src/ArduinoJson/Variant/SlotFunctions.hpp
  93. 22
      third-party/ArduinoJson/src/ArduinoJson/Variant/VariantCompare.hpp
  94. 137
      third-party/ArduinoJson/src/ArduinoJson/Variant/VariantData.hpp
  95. 43
      third-party/ArduinoJson/src/ArduinoJson/Variant/VariantImpl.hpp
  96. 50
      third-party/ArduinoJson/src/ArduinoJson/Variant/VariantSlot.hpp
  97. 5
      third-party/ArduinoJson/src/ArduinoJson/version.hpp
  98. 6
      third-party/Synth_Dexed/src/dexed.cpp

@ -250,7 +250,7 @@
#define VOICE_NAME_LEN 12 // 11 (plus '\0') #define VOICE_NAME_LEN 12 // 11 (plus '\0')
#define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN #define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN
#define CONFIG_FILENAME_LEN 50 #define CONFIG_FILENAME_LEN 50
#define DRUM_NAME_LEN 9 #define DRUM_NAME_LEN 10
#define PERFORMANCE_NAME_LEN 11 #define PERFORMANCE_NAME_LEN 11
#define FAV_CONFIG_PATH "FAVCFG" #define FAV_CONFIG_PATH "FAVCFG"

@ -1,6 +1,28 @@
ArduinoJson: change log ArduinoJson: change log
======================= =======================
v6.21.3 (2023-07-23)
-------
* Fix compatibility with the Blynk libary (issue #1914)
* Fix double lookup in `to<JsonVariant>()`
* Fix double call to `size()` in `serializeMsgPack()`
* Include `ARDUINOJSON_SLOT_OFFSET_SIZE` in the namespace name
* Show a link to the documentation when user passes an unsupported input type
v6.21.2 (2023-04-12)
-------
* Fix compatibility with the Zephyr Project (issue #1905)
* Allow using PROGMEM outside of Arduino (issue #1903)
* Set default for `ARDUINOJSON_ENABLE_PROGMEM` to `1` on AVR
v6.21.1 (2023-03-27)
-------
* Double speed of `DynamicJsonDocument::garbageCollect()`
* Fix compatibility with GCC 5.2 (issue #1897)
v6.21.0 (2023-03-14) v6.21.0 (2023-03-14)
------- -------

@ -10,7 +10,7 @@ if(ESP_PLATFORM)
return() return()
endif() endif()
project(ArduinoJson VERSION 6.21.0) project(ArduinoJson VERSION 6.21.3)
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(CTest) include(CTest)

@ -8,9 +8,9 @@
[![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) [![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) [![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)
[![Coveralls branch](https://img.shields.io/coveralls/github/bblanchon/ArduinoJson/6.x?logo=coveralls)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x) [![Coveralls branch](https://img.shields.io/coveralls/github/bblanchon/ArduinoJson/6.x?logo=coveralls)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
[![Arduino Library Manager](https://img.shields.io/static/v1?label=Arduino&message=v6.21.0&logo=arduino&logoColor=white&color=blue)](https://www.ardu-badge.com/ArduinoJson/6.21.0) [![Arduino Library Manager](https://img.shields.io/static/v1?label=Arduino&message=v6.21.3&logo=arduino&logoColor=white&color=blue)](https://www.ardu-badge.com/ArduinoJson/6.21.3)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/bblanchon/library/ArduinoJson.svg?version=6.21.0)](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.21.0) [![PlatformIO Registry](https://badges.registry.platformio.org/packages/bblanchon/library/ArduinoJson.svg?version=6.21.3)](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.21.3)
[![ESP IDF](https://img.shields.io/static/v1?label=ESP+IDF&message=v6.21.0&logo=cpu&logoColor=white&color=blue)](https://components.espressif.com/components/bblanchon/arduinojson) [![ESP IDF](https://img.shields.io/static/v1?label=ESP+IDF&message=v6.21.3&logo=cpu&logoColor=white&color=blue)](https://components.espressif.com/components/bblanchon/arduinojson)
[![GitHub stars](https://img.shields.io/github/stars/bblanchon/ArduinoJson?style=flat&logo=github&color=orange)](https://github.com/bblanchon/ArduinoJson/stargazers) [![GitHub stars](https://img.shields.io/github/stars/bblanchon/ArduinoJson?style=flat&logo=github&color=orange)](https://github.com/bblanchon/ArduinoJson/stargazers)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/bblanchon?logo=github&color=orange)](https://github.com/sponsors/bblanchon) [![GitHub Sponsors](https://img.shields.io/github/sponsors/bblanchon?logo=github&color=orange)](https://github.com/sponsors/bblanchon)
@ -85,7 +85,7 @@ ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x) * [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
* Continuously tested on * Continuously tested on
* [Visual Studio 2017, 2019, 2022](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x) * [Visual Studio 2017, 2019, 2022](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
* [GCC 6, 7, 8, 9, 10, 11](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22) * [GCC 5, 6, 7, 8, 9, 10, 11](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22)
* [Clang 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) * [Clang 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) * [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/) * Passes all default checks of [clang-tidy](https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/)

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

@ -14,7 +14,7 @@ void setup() {
while (!Serial) continue; while (!Serial) continue;
// The huge input: an extract from OpenWeatherMap response // The huge input: an extract from OpenWeatherMap response
const __FlashStringHelper* input_json = F( auto input_json = F(
"{\"cod\":\"200\",\"message\":0,\"list\":[{\"dt\":1581498000,\"main\":{" "{\"cod\":\"200\",\"message\":0,\"list\":[{\"dt\":1581498000,\"main\":{"
"\"temp\":3.23,\"feels_like\":-3.63,\"temp_min\":3.23,\"temp_max\":4.62," "\"temp\":3.23,\"feels_like\":-3.63,\"temp_min\":3.23,\"temp_max\":4.62,"
"\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":" "\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":"

@ -1,5 +1,7 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
static_assert(ARDUINOJSON_ENABLE_PROGMEM == 1, "ARDUINOJSON_ENABLE_PROGMEM");
static_assert(ARDUINOJSON_USE_LONG_LONG == 0, "ARDUINOJSON_USE_LONG_LONG"); static_assert(ARDUINOJSON_USE_LONG_LONG == 0, "ARDUINOJSON_USE_LONG_LONG");
static_assert(ARDUINOJSON_SLOT_OFFSET_SIZE == 1, static_assert(ARDUINOJSON_SLOT_OFFSET_SIZE == 1,

@ -4,14 +4,14 @@ set -eu
VERSION="$1" VERSION="$1"
CHANGELOG="$2" CHANGELOG="$2"
FRONTMATTER="$3" ARDUINOJSON_H="$3"
cat << END cat << END
--- ---
branch: v6 branch: v6
version: $VERSION version: $VERSION
date: '$(date +'%Y-%m-%d')' date: '$(date +'%Y-%m-%d')'
$(cat "$FRONTMATTER") $(extras/scripts/wandbox/publish.sh "$ARDUINOJSON_H")
--- ---
$(awk '/\* /{ FOUND=1; print; next } { if (FOUND) exit}' "$CHANGELOG") $(awk '/\* /{ FOUND=1; print; next } { if (FOUND) exit}' "$CHANGELOG")

@ -14,5 +14,5 @@ cp -r "$SOURCE_DIR/src" "$WORK_DIR/"
cp -r "$SOURCE_DIR/examples" "$WORK_DIR/" cp -r "$SOURCE_DIR/examples" "$WORK_DIR/"
cd "$WORK_DIR" cd "$WORK_DIR"
particle library upload particle library upload -v
particle library publish particle library publish -v

@ -46,6 +46,7 @@ update_version_in_source () {
-e "s/ARDUINOJSON_VERSION_MAJOR .*$/ARDUINOJSON_VERSION_MAJOR $MAJOR/" \ -e "s/ARDUINOJSON_VERSION_MAJOR .*$/ARDUINOJSON_VERSION_MAJOR $MAJOR/" \
-e "s/ARDUINOJSON_VERSION_MINOR .*$/ARDUINOJSON_VERSION_MINOR $MINOR/" \ -e "s/ARDUINOJSON_VERSION_MINOR .*$/ARDUINOJSON_VERSION_MINOR $MINOR/" \
-e "s/ARDUINOJSON_VERSION_REVISION .*$/ARDUINOJSON_VERSION_REVISION $REVISION/" \ -e "s/ARDUINOJSON_VERSION_REVISION .*$/ARDUINOJSON_VERSION_REVISION $REVISION/" \
-e "s/ARDUINOJSON_VERSION_MACRO .*$/ARDUINOJSON_VERSION_MACRO V$MAJOR$MINOR$REVISION/" \
src/ArduinoJson/version.hpp src/ArduinoJson/version.hpp
rm src/ArduinoJson/version.hpp*~ rm src/ArduinoJson/version.hpp*~
} }
@ -72,7 +73,6 @@ push
extras/scripts/build-arduino-package.sh . "../ArduinoJson-$TAG.zip" extras/scripts/build-arduino-package.sh . "../ArduinoJson-$TAG.zip"
extras/scripts/build-single-header.sh "src/ArduinoJson.h" "../ArduinoJson-$TAG.h" extras/scripts/build-single-header.sh "src/ArduinoJson.h" "../ArduinoJson-$TAG.h"
extras/scripts/build-single-header.sh "src/ArduinoJson.hpp" "../ArduinoJson-$TAG.hpp" extras/scripts/build-single-header.sh "src/ArduinoJson.hpp" "../ArduinoJson-$TAG.hpp"
extras/scripts/wandbox/publish.sh "../ArduinoJson-$TAG.h" > "../ArduinoJson-$TAG-wandbox.txt" || echo "Wandbox failed!" extras/scripts/get-release-page.sh "$VERSION" "CHANGELOG.md" "../ArduinoJson-$TAG.h" > "../ArduinoJson-$TAG.md"
extras/scripts/get-release-page.sh "$VERSION" "CHANGELOG.md" "../ArduinoJson-$TAG-wandbox.txt" > "../ArduinoJson-$TAG.md"
echo "You can now copy ../ArduinoJson-$TAG.md into arduinojson.org/collections/_versions/$VERSION.md" echo "You can now copy ../ArduinoJson-$TAG.md into arduinojson.org/collections/_versions/$VERSION.md"

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

@ -7,5 +7,7 @@
#include "api/Print.h" #include "api/Print.h"
#include "api/Stream.h" #include "api/Stream.h"
#include "api/String.h" #include "api/String.h"
#include "avr/pgmspace.h"
#define ARDUINO
#define ARDUINO_H_INCLUDED 1 #define ARDUINO_H_INCLUDED 1

@ -7,18 +7,18 @@
#include <sstream> #include <sstream>
class CustomReader { class CustomReader {
std::stringstream _stream; std::stringstream stream_;
public: public:
CustomReader(const char* input) : _stream(input) {} CustomReader(const char* input) : stream_(input) {}
CustomReader(const CustomReader&) = delete; CustomReader(const CustomReader&) = delete;
int read() { int read() {
return _stream.get(); return stream_.get();
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
_stream.read(buffer, static_cast<std::streamsize>(length)); stream_.read(buffer, static_cast<std::streamsize>(length));
return static_cast<size_t>(_stream.gcount()); return static_cast<size_t>(stream_.gcount());
} }
}; };

@ -0,0 +1,31 @@
// ArduinoJson - https://arduinojson.org
// Copyright © 2014-2023, Benoit BLANCHON
// MIT License
#pragma once
#include <stdint.h> // uint8_t
#define PROGMEM
class __FlashStringHelper;
inline const void* convertPtrToFlash(const void* s) {
return reinterpret_cast<const char*>(s) + 42;
}
inline const void* convertFlashToPtr(const void* s) {
return reinterpret_cast<const char*>(s) - 42;
}
#define PSTR(X) reinterpret_cast<const char*>(convertPtrToFlash(X))
#define F(X) reinterpret_cast<const __FlashStringHelper*>(PSTR(X))
inline uint8_t pgm_read_byte(const void* p) {
return *reinterpret_cast<const uint8_t*>(convertFlashToPtr(p));
}
#define ARDUINOJSON_DEFINE_PROGMEM_ARRAY(type, name, ...) \
static type const ARDUINOJSON_CONCAT2(name, _progmem)[] = __VA_ARGS__; \
static type const* name = reinterpret_cast<type const*>( \
convertPtrToFlash(ARDUINOJSON_CONCAT2(name, _progmem)));

@ -9,7 +9,7 @@ add_executable(IntegrationTests
openweathermap.cpp openweathermap.cpp
) )
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") if(CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 6)
target_compile_options(IntegrationTests target_compile_options(IntegrationTests
PUBLIC PUBLIC
-fsingle-precision-constant # issue 544 -fsingle-precision-constant # issue 544

@ -24,6 +24,30 @@ TEST_CASE("deserializeJson(char*)") {
} }
} }
TEST_CASE("deserializeJson(unsigned char*, unsigned int)") { // issue #1897
StaticJsonDocument<1024> doc;
unsigned char input[] = "{\"hello\":\"world\"}";
unsigned char* input_ptr = input;
unsigned int size = sizeof(input);
DeserializationError err = deserializeJson(doc, input_ptr, size);
REQUIRE(err == DeserializationError::Ok);
}
TEST_CASE("deserializeJson(uint8_t*, size_t)") { // issue #1898
StaticJsonDocument<1024> doc;
uint8_t input[] = "{\"hello\":\"world\"}";
uint8_t* input_ptr = input;
size_t size = sizeof(input);
DeserializationError err = deserializeJson(doc, input_ptr, size);
REQUIRE(err == DeserializationError::Ok);
}
TEST_CASE("deserializeJson(const std::string&)") { TEST_CASE("deserializeJson(const std::string&)") {
DynamicJsonDocument doc(4096); DynamicJsonDocument doc(4096);

@ -10,29 +10,29 @@
class SpyingAllocator { class SpyingAllocator {
public: public:
SpyingAllocator(const SpyingAllocator& src) : _log(src._log) {} SpyingAllocator(const SpyingAllocator& src) : log_(src.log_) {}
SpyingAllocator(std::ostream& log) : _log(log) {} SpyingAllocator(std::ostream& log) : log_(log) {}
SpyingAllocator& operator=(const SpyingAllocator& src) = delete; SpyingAllocator& operator=(const SpyingAllocator& src) = delete;
void* allocate(size_t n) { void* allocate(size_t n) {
_log << "A" << n; log_ << "A" << n;
return malloc(n); return malloc(n);
} }
void deallocate(void* p) { void deallocate(void* p) {
_log << "F"; log_ << "F";
free(p); free(p);
} }
private: private:
std::ostream& _log; std::ostream& log_;
}; };
class ControllableAllocator { class ControllableAllocator {
public: public:
ControllableAllocator() : _enabled(true) {} ControllableAllocator() : enabled_(true) {}
void* allocate(size_t n) { void* allocate(size_t n) {
return _enabled ? malloc(n) : 0; return enabled_ ? malloc(n) : 0;
} }
void deallocate(void* p) { void deallocate(void* p) {
@ -40,11 +40,11 @@ class ControllableAllocator {
} }
void disable() { void disable() {
_enabled = false; enabled_ = false;
} }
private: private:
bool _enabled; bool enabled_;
}; };
TEST_CASE("BasicJsonDocument") { TEST_CASE("BasicJsonDocument") {

@ -10,36 +10,36 @@
class ArmoredAllocator { class ArmoredAllocator {
public: public:
ArmoredAllocator() : _ptr(0), _size(0) {} ArmoredAllocator() : ptr_(0), size_(0) {}
void* allocate(size_t size) { void* allocate(size_t size) {
_ptr = malloc(size); ptr_ = malloc(size);
_size = size; size_ = size;
return _ptr; return ptr_;
} }
void deallocate(void* ptr) { void deallocate(void* ptr) {
REQUIRE(ptr == _ptr); REQUIRE(ptr == ptr_);
free(ptr); free(ptr);
_ptr = 0; ptr_ = 0;
_size = 0; size_ = 0;
} }
void* reallocate(void* ptr, size_t new_size) { void* reallocate(void* ptr, size_t new_size) {
REQUIRE(ptr == _ptr); REQUIRE(ptr == ptr_);
// don't call realloc, instead alloc a new buffer and erase the old one // don't call realloc, instead alloc a new buffer and erase the old one
// this way we make sure we support relocation // this way we make sure we support relocation
void* new_ptr = malloc(new_size); void* new_ptr = malloc(new_size);
memcpy(new_ptr, _ptr, std::min(new_size, _size)); memcpy(new_ptr, ptr_, std::min(new_size, size_));
memset(_ptr, '#', _size); // erase memset(ptr_, '#', size_); // erase
free(_ptr); free(ptr_);
_ptr = new_ptr; ptr_ = new_ptr;
return new_ptr; return new_ptr;
} }
private: private:
void* _ptr; void* ptr_;
size_t _size; size_t size_;
}; };
typedef BasicJsonDocument<ArmoredAllocator> ShrinkToFitTestDocument; typedef BasicJsonDocument<ArmoredAllocator> ShrinkToFitTestDocument;

@ -12,21 +12,21 @@ class CustomWriter {
CustomWriter& operator=(const CustomWriter&) = delete; CustomWriter& operator=(const CustomWriter&) = delete;
size_t write(uint8_t c) { size_t write(uint8_t c) {
_str.append(1, static_cast<char>(c)); str_.append(1, static_cast<char>(c));
return 1; return 1;
} }
size_t write(const uint8_t* s, size_t n) { size_t write(const uint8_t* s, size_t n) {
_str.append(reinterpret_cast<const char*>(s), n); str_.append(reinterpret_cast<const char*>(s), n);
return n; return n;
} }
const std::string& str() const { const std::string& str() const {
return _str; return str_;
} }
private: private:
std::string _str; std::string str_;
}; };
TEST_CASE("CustomWriter") { TEST_CASE("CustomWriter") {

@ -74,18 +74,18 @@ TEST_CASE("Custom converter with overloading") {
class Complex { class Complex {
public: public:
explicit Complex(double r, double i) : _real(r), _imag(i) {} explicit Complex(double r, double i) : real_(r), imag_(i) {}
double real() const { double real() const {
return _real; return real_;
} }
double imag() const { double imag() const {
return _imag; return imag_;
} }
private: private:
double _real, _imag; double real_, imag_;
}; };
namespace ArduinoJson { namespace ArduinoJson {
@ -152,3 +152,16 @@ TEST_CASE("ConverterNeedsWriteableRef") {
CHECK(ConverterNeedsWriteableRef<JsonArray>::value == true); CHECK(ConverterNeedsWriteableRef<JsonArray>::value == true);
CHECK(ConverterNeedsWriteableRef<JsonArrayConst>::value == false); CHECK(ConverterNeedsWriteableRef<JsonArrayConst>::value == false);
} }
namespace ArduinoJson {
void convertToJson(char c, JsonVariant var) {
char buf[] = {c, 0};
var.set(buf);
}
} // namespace ArduinoJson
TEST_CASE("Convert char to string") { // issue #1922
StaticJsonDocument<64> doc;
doc.set('a');
REQUIRE(doc.as<std::string>() == "a");
}

@ -5,6 +5,11 @@
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
TEST_CASE("VariantData") {
REQUIRE(std::is_standard_layout<ArduinoJson::detail::VariantData>::value ==
true);
}
TEST_CASE("JsonVariant from JsonArray") { TEST_CASE("JsonVariant from JsonArray") {
SECTION("JsonArray is null") { SECTION("JsonArray is null") {
JsonArray arr; JsonArray arr;

@ -170,19 +170,19 @@ TEST_CASE("IteratorReader") {
class StreamStub : public Stream { class StreamStub : public Stream {
public: public:
StreamStub(const char* s) : _stream(s) {} StreamStub(const char* s) : stream_(s) {}
int read() { int read() {
return _stream.get(); return stream_.get();
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
_stream.read(buffer, static_cast<std::streamsize>(length)); stream_.read(buffer, static_cast<std::streamsize>(length));
return static_cast<size_t>(_stream.gcount()); return static_cast<size_t>(stream_.gcount());
} }
private: private:
std::istringstream _stream; std::istringstream stream_;
}; };
TEST_CASE("Reader<Stream>") { TEST_CASE("Reader<Stream>") {

@ -2,17 +2,16 @@
// Copyright © 2014-2023, Benoit BLANCHON // Copyright © 2014-2023, Benoit BLANCHON
// MIT License // MIT License
#define ARDUINOJSON_ENABLE_PROGMEM 1 #include <Arduino.h>
#include "custom_string.hpp"
#include "progmem_emulation.hpp"
#include "weird_strcmp.hpp"
#include <ArduinoJson/Strings/IsString.hpp> #include <ArduinoJson/Strings/IsString.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp> #include <ArduinoJson/Strings/StringAdapters.hpp>
#include <catch.hpp> #include <catch.hpp>
#include "custom_string.hpp"
#include "weird_strcmp.hpp"
using namespace ArduinoJson::detail; using namespace ArduinoJson::detail;
TEST_CASE("ZeroTerminatedRamString") { TEST_CASE("ZeroTerminatedRamString") {

@ -2,10 +2,13 @@
// Copyright © 2014-2023, Benoit BLANCHON // Copyright © 2014-2023, Benoit BLANCHON
// MIT License // MIT License
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 #include <Arduino.h>
#define ARDUINOJSON_STRING_BUFFER_SIZE 5 #define ARDUINOJSON_STRING_BUFFER_SIZE 5
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>
#include "custom_string.hpp" #include "custom_string.hpp"
using namespace ArduinoJson::detail; using namespace ArduinoJson::detail;

@ -52,5 +52,11 @@
#define BLOCKSIZE #define BLOCKSIZE
#define CAPACITY #define CAPACITY
// issue #1905
#define _current
// issue #1914
#define V6 6
// catch.hpp mutes several warnings, this file also allows to detect them // catch.hpp mutes several warnings, this file also allows to detect them
#include "ArduinoJson.h" #include "ArduinoJson.h"

@ -29,21 +29,21 @@ struct PrintAllAtOnce {
template <typename PrintPolicy> template <typename PrintPolicy>
struct PrintableString : public Printable { struct PrintableString : public Printable {
PrintableString(const char* s) : _str(s), _total(0) {} PrintableString(const char* s) : str_(s), total_(0) {}
virtual size_t printTo(Print& p) const { virtual size_t printTo(Print& p) const {
size_t result = PrintPolicy::printStringTo(_str, p); size_t result = PrintPolicy::printStringTo(str_, p);
_total += result; total_ += result;
return result; return result;
} }
size_t totalBytesWritten() const { size_t totalBytesWritten() const {
return _total; return total_;
} }
private: private:
std::string _str; std::string str_;
mutable size_t _total; mutable size_t total_;
}; };
TEST_CASE("Printable") { TEST_CASE("Printable") {

@ -2,8 +2,6 @@
// Copyright © 2014-2023, Benoit BLANCHON // Copyright © 2014-2023, Benoit BLANCHON
// MIT License // MIT License
#include "progmem_emulation.hpp"
#define ARDUINOJSON_ENABLE_PROGMEM 1 #define ARDUINOJSON_ENABLE_PROGMEM 1
#include <ArduinoJson.h> #include <ArduinoJson.h>

@ -2,8 +2,6 @@
// Copyright © 2014-2023, Benoit BLANCHON // Copyright © 2014-2023, Benoit BLANCHON
// MIT License // MIT License
#include "progmem_emulation.hpp"
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 #define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#define ARDUINOJSON_ENABLE_PROGMEM 1 #define ARDUINOJSON_ENABLE_PROGMEM 1
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 0 #define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 0

@ -2,8 +2,6 @@
// Copyright © 2014-2023, Benoit BLANCHON // Copyright © 2014-2023, Benoit BLANCHON
// MIT License // MIT License
#include "progmem_emulation.hpp"
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 #define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#define ARDUINOJSON_ENABLE_PROGMEM 1 #define ARDUINOJSON_ENABLE_PROGMEM 1
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1 #define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1

@ -5,8 +5,6 @@
#define ARDUINO #define ARDUINO
#define memcpy_P(dest, src, n) memcpy((dest), (src), (n)) #define memcpy_P(dest, src, n) memcpy((dest), (src), (n))
#include "progmem_emulation.hpp"
#include <ArduinoJson.h> #include <ArduinoJson.h>
#include <catch.hpp> #include <catch.hpp>

@ -10,8 +10,6 @@ using namespace ArduinoJson::detail;
TEST_CASE("Test unsigned integer overflow") { TEST_CASE("Test unsigned integer overflow") {
VariantData first, second; VariantData first, second;
first.init();
second.init();
// Avoids MSVC warning C4127 (conditional expression is constant) // Avoids MSVC warning C4127 (conditional expression is constant)
size_t integerSize = sizeof(JsonInteger); size_t integerSize = sizeof(JsonInteger);
@ -30,8 +28,6 @@ TEST_CASE("Test unsigned integer overflow") {
TEST_CASE("Test signed integer overflow") { TEST_CASE("Test signed integer overflow") {
VariantData first, second; VariantData first, second;
first.init();
second.init();
// Avoids MSVC warning C4127 (conditional expression is constant) // Avoids MSVC warning C4127 (conditional expression is constant)
size_t integerSize = sizeof(JsonInteger); size_t integerSize = sizeof(JsonInteger);
@ -50,7 +46,6 @@ TEST_CASE("Test signed integer overflow") {
TEST_CASE("Invalid value") { TEST_CASE("Invalid value") {
VariantData result; VariantData result;
result.init();
parseNumber("6a3", result); parseNumber("6a3", result);

@ -1,4 +1,4 @@
version: "6.21.0" version: "6.21.3"
description: >- description: >-
A simple and efficient JSON library for embedded C++. A simple and efficient JSON library for embedded C++.
ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more. ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more.
@ -8,5 +8,6 @@ url: https://arduinojson.org/
files: files:
exclude: exclude:
- "**/.vs/**/*" - "**/.vs/**/*"
- ".devcontainer/**/*"
- "examples/**/*" - "examples/**/*"
- "extras/**/*" - "extras/**/*"

@ -7,12 +7,13 @@
"type": "git", "type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git" "url": "https://github.com/bblanchon/ArduinoJson.git"
}, },
"version": "6.21.0", "version": "6.21.3",
"authors": { "authors": {
"name": "Benoit Blanchon", "name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr" "url": "https://blog.benoitblanchon.fr"
}, },
"exclude": [ "exclude": [
".devcontainer",
".github", ".github",
"extras" "extras"
], ],

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

@ -13,7 +13,8 @@
// Include Arduino.h before stdlib.h to avoid conflict with atexit() // Include Arduino.h before stdlib.h to avoid conflict with atexit()
// https://github.com/bblanchon/ArduinoJson/pull/1693#issuecomment-1001060240 // https://github.com/bblanchon/ArduinoJson/pull/1693#issuecomment-1001060240
#if ARDUINOJSON_ENABLE_ARDUINO_STRING || ARDUINOJSON_ENABLE_ARDUINO_STREAM || \ #if ARDUINOJSON_ENABLE_ARDUINO_STRING || ARDUINOJSON_ENABLE_ARDUINO_STREAM || \
ARDUINOJSON_ENABLE_ARDUINO_PRINT || ARDUINOJSON_ENABLE_PROGMEM ARDUINOJSON_ENABLE_ARDUINO_PRINT || \
(ARDUINOJSON_ENABLE_PROGMEM && defined(ARDUINO))
# include <Arduino.h> # include <Arduino.h>
#endif #endif

@ -17,10 +17,10 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
public: public:
ElementProxy(TUpstream upstream, size_t index) ElementProxy(TUpstream upstream, size_t index)
: _upstream(upstream), _index(index) {} : upstream_(upstream), index_(index) {}
ElementProxy(const ElementProxy& src) ElementProxy(const ElementProxy& src)
: _upstream(src._upstream), _index(src._index) {} : upstream_(src.upstream_), index_(src.index_) {}
FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) { FORCE_INLINE ElementProxy& operator=(const ElementProxy& src) {
this->set(src); this->set(src);
@ -41,20 +41,20 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
private: private:
FORCE_INLINE MemoryPool* getPool() const { FORCE_INLINE MemoryPool* getPool() const {
return VariantAttorney::getPool(_upstream); return VariantAttorney::getPool(upstream_);
} }
FORCE_INLINE VariantData* getData() const { FORCE_INLINE VariantData* getData() const {
return variantGetElement(VariantAttorney::getData(_upstream), _index); return variantGetElement(VariantAttorney::getData(upstream_), index_);
} }
FORCE_INLINE VariantData* getOrCreateData() const { FORCE_INLINE VariantData* getOrCreateData() const {
return variantGetOrAddElement(VariantAttorney::getOrCreateData(_upstream), return variantGetOrAddElement(VariantAttorney::getOrCreateData(upstream_),
_index, VariantAttorney::getPool(_upstream)); index_, VariantAttorney::getPool(upstream_));
} }
TUpstream _upstream; TUpstream upstream_;
size_t _index; size_t index_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -20,32 +20,32 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
typedef JsonArrayIterator iterator; typedef JsonArrayIterator iterator;
// Constructs an unbound reference. // Constructs an unbound reference.
FORCE_INLINE JsonArray() : _data(0), _pool(0) {} FORCE_INLINE JsonArray() : data_(0), pool_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonArray(detail::MemoryPool* pool, detail::CollectionData* data) FORCE_INLINE JsonArray(detail::MemoryPool* pool, detail::CollectionData* data)
: _data(data), _pool(pool) {} : data_(data), pool_(pool) {}
// Returns a JsonVariant pointing to the array. // Returns a JsonVariant pointing to the array.
// https://arduinojson.org/v6/api/jsonvariant/ // https://arduinojson.org/v6/api/jsonvariant/
operator JsonVariant() { operator JsonVariant() {
void* data = _data; // prevent warning cast-align void* data = data_; // prevent warning cast-align
return JsonVariant(_pool, reinterpret_cast<detail::VariantData*>(data)); return JsonVariant(pool_, reinterpret_cast<detail::VariantData*>(data));
} }
// Returns a read-only reference to the array. // Returns a read-only reference to the array.
// https://arduinojson.org/v6/api/jsonarrayconst/ // https://arduinojson.org/v6/api/jsonarrayconst/
operator JsonArrayConst() const { operator JsonArrayConst() const {
return JsonArrayConst(_data); return JsonArrayConst(data_);
} }
// Appends a new (null) element to the array. // Appends a new (null) element to the array.
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsonarray/add/ // https://arduinojson.org/v6/api/jsonarray/add/
JsonVariant add() const { JsonVariant add() const {
if (!_data) if (!data_)
return JsonVariant(); return JsonVariant();
return JsonVariant(_pool, _data->addElement(_pool)); return JsonVariant(pool_, data_->addElement(pool_));
} }
// Appends a value to the array. // Appends a value to the array.
@ -65,9 +65,9 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Returns an iterator to the first element of the array. // Returns an iterator to the first element of the array.
// https://arduinojson.org/v6/api/jsonarray/begin/ // https://arduinojson.org/v6/api/jsonarray/begin/
FORCE_INLINE iterator begin() const { FORCE_INLINE iterator begin() const {
if (!_data) if (!data_)
return iterator(); return iterator();
return iterator(_pool, _data->head()); return iterator(pool_, data_->head());
} }
// Returns an iterator following the last element of the array. // Returns an iterator following the last element of the array.
@ -79,41 +79,41 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Copies an array. // Copies an array.
// https://arduinojson.org/v6/api/jsonarray/set/ // https://arduinojson.org/v6/api/jsonarray/set/
FORCE_INLINE bool set(JsonArrayConst src) const { FORCE_INLINE bool set(JsonArrayConst src) const {
if (!_data || !src._data) if (!data_ || !src.data_)
return false; return false;
return _data->copyFrom(*src._data, _pool); return data_->copyFrom(*src.data_, pool_);
} }
// Compares the content of two arrays. // Compares the content of two arrays.
FORCE_INLINE bool operator==(JsonArray rhs) const { FORCE_INLINE bool operator==(JsonArray rhs) const {
return JsonArrayConst(_data) == JsonArrayConst(rhs._data); return JsonArrayConst(data_) == JsonArrayConst(rhs.data_);
} }
// Removes the element at the specified iterator. // Removes the element at the specified iterator.
// ⚠ Doesn't release the memory associated with the removed element. // ⚠ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/ // https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(iterator it) const { FORCE_INLINE void remove(iterator it) const {
if (!_data) if (!data_)
return; return;
_data->removeSlot(it._slot); data_->removeSlot(it.slot_);
} }
// Removes the element at the specified index. // Removes the element at the specified index.
// ⚠ Doesn't release the memory associated with the removed element. // ⚠ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsonarray/remove/ // https://arduinojson.org/v6/api/jsonarray/remove/
FORCE_INLINE void remove(size_t index) const { FORCE_INLINE void remove(size_t index) const {
if (!_data) if (!data_)
return; return;
_data->removeElement(index); data_->removeElement(index);
} }
// Removes all the elements of the array. // Removes all the elements of the array.
// ⚠ Doesn't release the memory associated with the removed elements. // ⚠ Doesn't release the memory associated with the removed elements.
// https://arduinojson.org/v6/api/jsonarray/clear/ // https://arduinojson.org/v6/api/jsonarray/clear/
void clear() const { void clear() const {
if (!_data) if (!data_)
return; return;
_data->clear(); data_->clear();
} }
// Gets or sets the element at the specified index. // Gets or sets the element at the specified index.
@ -133,54 +133,54 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
} }
operator JsonVariantConst() const { operator JsonVariantConst() const {
return JsonVariantConst(collectionToVariant(_data)); return JsonVariantConst(collectionToVariant(data_));
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v6/api/jsonarray/isnull/ // https://arduinojson.org/v6/api/jsonarray/isnull/
FORCE_INLINE bool isNull() const { FORCE_INLINE bool isNull() const {
return _data == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v6/api/jsonarray/isnull/ // https://arduinojson.org/v6/api/jsonarray/isnull/
FORCE_INLINE operator bool() const { FORCE_INLINE operator bool() const {
return _data != 0; return data_ != 0;
} }
// Returns the number of bytes occupied by the array. // Returns the number of bytes occupied by the array.
// https://arduinojson.org/v6/api/jsonarray/memoryusage/ // https://arduinojson.org/v6/api/jsonarray/memoryusage/
FORCE_INLINE size_t memoryUsage() const { FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0; return data_ ? data_->memoryUsage() : 0;
} }
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
// https://arduinojson.org/v6/api/jsonarray/nesting/ // https://arduinojson.org/v6/api/jsonarray/nesting/
FORCE_INLINE size_t nesting() const { FORCE_INLINE size_t nesting() const {
return variantNesting(collectionToVariant(_data)); return variantNesting(collectionToVariant(data_));
} }
// Returns the number of elements in the array. // Returns the number of elements in the array.
// https://arduinojson.org/v6/api/jsonarray/size/ // https://arduinojson.org/v6/api/jsonarray/size/
FORCE_INLINE size_t size() const { FORCE_INLINE size_t size() const {
return _data ? _data->size() : 0; return data_ ? data_->size() : 0;
} }
private: private:
detail::MemoryPool* getPool() const { detail::MemoryPool* getPool() const {
return _pool; return pool_;
} }
detail::VariantData* getData() const { detail::VariantData* getData() const {
return collectionToVariant(_data); return collectionToVariant(data_);
} }
detail::VariantData* getOrCreateData() const { detail::VariantData* getOrCreateData() const {
return collectionToVariant(_data); return collectionToVariant(data_);
} }
detail::CollectionData* _data; detail::CollectionData* data_;
detail::MemoryPool* _pool; detail::MemoryPool* pool_;
}; };
template <> template <>

@ -24,9 +24,9 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns an iterator to the first element of the array. // Returns an iterator to the first element of the array.
// https://arduinojson.org/v6/api/jsonarrayconst/begin/ // https://arduinojson.org/v6/api/jsonarrayconst/begin/
FORCE_INLINE iterator begin() const { FORCE_INLINE iterator begin() const {
if (!_data) if (!data_)
return iterator(); return iterator();
return iterator(_data->head()); return iterator(data_->head());
} }
// Returns an iterator to the element following the last element of the array. // Returns an iterator to the element following the last element of the array.
@ -36,18 +36,18 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
} }
// Creates an unbound reference. // Creates an unbound reference.
FORCE_INLINE JsonArrayConst() : _data(0) {} FORCE_INLINE JsonArrayConst() : data_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonArrayConst(const detail::CollectionData* data) FORCE_INLINE JsonArrayConst(const detail::CollectionData* data)
: _data(data) {} : data_(data) {}
// Compares the content of two arrays. // Compares the content of two arrays.
// Returns true if the two arrays are equal. // Returns true if the two arrays are equal.
FORCE_INLINE bool operator==(JsonArrayConst rhs) const { FORCE_INLINE bool operator==(JsonArrayConst rhs) const {
if (_data == rhs._data) if (data_ == rhs.data_)
return true; return true;
if (!_data || !rhs._data) if (!data_ || !rhs.data_)
return false; return false;
iterator it1 = begin(); iterator it1 = begin();
@ -70,49 +70,49 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Returns the element at the specified index. // Returns the element at the specified index.
// https://arduinojson.org/v6/api/jsonarrayconst/subscript/ // https://arduinojson.org/v6/api/jsonarrayconst/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const { FORCE_INLINE JsonVariantConst operator[](size_t index) const {
return JsonVariantConst(_data ? _data->getElement(index) : 0); return JsonVariantConst(data_ ? data_->getElement(index) : 0);
} }
operator JsonVariantConst() const { operator JsonVariantConst() const {
return JsonVariantConst(collectionToVariant(_data)); return JsonVariantConst(collectionToVariant(data_));
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v6/api/jsonarrayconst/isnull/ // https://arduinojson.org/v6/api/jsonarrayconst/isnull/
FORCE_INLINE bool isNull() const { FORCE_INLINE bool isNull() const {
return _data == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v6/api/jsonarrayconst/isnull/ // https://arduinojson.org/v6/api/jsonarrayconst/isnull/
FORCE_INLINE operator bool() const { FORCE_INLINE operator bool() const {
return _data != 0; return data_ != 0;
} }
// Returns the number of bytes occupied by the array. // Returns the number of bytes occupied by the array.
// https://arduinojson.org/v6/api/jsonarrayconst/memoryusage/ // https://arduinojson.org/v6/api/jsonarrayconst/memoryusage/
FORCE_INLINE size_t memoryUsage() const { FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0; return data_ ? data_->memoryUsage() : 0;
} }
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
// https://arduinojson.org/v6/api/jsonarrayconst/nesting/ // https://arduinojson.org/v6/api/jsonarrayconst/nesting/
FORCE_INLINE size_t nesting() const { FORCE_INLINE size_t nesting() const {
return variantNesting(collectionToVariant(_data)); return variantNesting(collectionToVariant(data_));
} }
// Returns the number of elements in the array. // Returns the number of elements in the array.
// https://arduinojson.org/v6/api/jsonarrayconst/size/ // https://arduinojson.org/v6/api/jsonarrayconst/size/
FORCE_INLINE size_t size() const { FORCE_INLINE size_t size() const {
return _data ? _data->size() : 0; return data_ ? data_->size() : 0;
} }
private: private:
const detail::VariantData* getData() const { const detail::VariantData* getData() const {
return collectionToVariant(_data); return collectionToVariant(data_);
} }
const detail::CollectionData* _data; const detail::CollectionData* data_;
}; };
template <> template <>

@ -12,110 +12,110 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
class VariantPtr { class VariantPtr {
public: public:
VariantPtr(detail::MemoryPool* pool, detail::VariantData* data) VariantPtr(detail::MemoryPool* pool, detail::VariantData* data)
: _variant(pool, data) {} : variant_(pool, data) {}
JsonVariant* operator->() { JsonVariant* operator->() {
return &_variant; return &variant_;
} }
JsonVariant& operator*() { JsonVariant& operator*() {
return _variant; return variant_;
} }
private: private:
JsonVariant _variant; JsonVariant variant_;
}; };
class JsonArrayIterator { class JsonArrayIterator {
friend class JsonArray; friend class JsonArray;
public: public:
JsonArrayIterator() : _slot(0) {} JsonArrayIterator() : slot_(0) {}
explicit JsonArrayIterator(detail::MemoryPool* pool, explicit JsonArrayIterator(detail::MemoryPool* pool,
detail::VariantSlot* slot) detail::VariantSlot* slot)
: _pool(pool), _slot(slot) {} : pool_(pool), slot_(slot) {}
JsonVariant operator*() const { JsonVariant operator*() const {
return JsonVariant(_pool, _slot->data()); return JsonVariant(pool_, slot_->data());
} }
VariantPtr operator->() { VariantPtr operator->() {
return VariantPtr(_pool, _slot->data()); return VariantPtr(pool_, slot_->data());
} }
bool operator==(const JsonArrayIterator& other) const { bool operator==(const JsonArrayIterator& other) const {
return _slot == other._slot; return slot_ == other.slot_;
} }
bool operator!=(const JsonArrayIterator& other) const { bool operator!=(const JsonArrayIterator& other) const {
return _slot != other._slot; return slot_ != other.slot_;
} }
JsonArrayIterator& operator++() { JsonArrayIterator& operator++() {
_slot = _slot->next(); slot_ = slot_->next();
return *this; return *this;
} }
JsonArrayIterator& operator+=(size_t distance) { JsonArrayIterator& operator+=(size_t distance) {
_slot = _slot->next(distance); slot_ = slot_->next(distance);
return *this; return *this;
} }
private: private:
detail::MemoryPool* _pool; detail::MemoryPool* pool_;
detail::VariantSlot* _slot; detail::VariantSlot* slot_;
}; };
class VariantConstPtr { class VariantConstPtr {
public: public:
VariantConstPtr(const detail::VariantData* data) : _variant(data) {} VariantConstPtr(const detail::VariantData* data) : variant_(data) {}
JsonVariantConst* operator->() { JsonVariantConst* operator->() {
return &_variant; return &variant_;
} }
JsonVariantConst& operator*() { JsonVariantConst& operator*() {
return _variant; return variant_;
} }
private: private:
JsonVariantConst _variant; JsonVariantConst variant_;
}; };
class JsonArrayConstIterator { class JsonArrayConstIterator {
friend class JsonArray; friend class JsonArray;
public: public:
JsonArrayConstIterator() : _slot(0) {} JsonArrayConstIterator() : slot_(0) {}
explicit JsonArrayConstIterator(const detail::VariantSlot* slot) explicit JsonArrayConstIterator(const detail::VariantSlot* slot)
: _slot(slot) {} : slot_(slot) {}
JsonVariantConst operator*() const { JsonVariantConst operator*() const {
return JsonVariantConst(_slot->data()); return JsonVariantConst(slot_->data());
} }
VariantConstPtr operator->() { VariantConstPtr operator->() {
return VariantConstPtr(_slot->data()); return VariantConstPtr(slot_->data());
} }
bool operator==(const JsonArrayConstIterator& other) const { bool operator==(const JsonArrayConstIterator& other) const {
return _slot == other._slot; return slot_ == other.slot_;
} }
bool operator!=(const JsonArrayConstIterator& other) const { bool operator!=(const JsonArrayConstIterator& other) const {
return _slot != other._slot; return slot_ != other.slot_;
} }
JsonArrayConstIterator& operator++() { JsonArrayConstIterator& operator++() {
_slot = _slot->next(); slot_ = slot_->next();
return *this; return *this;
} }
JsonArrayConstIterator& operator+=(size_t distance) { JsonArrayConstIterator& operator+=(size_t distance) {
_slot = _slot->next(distance); slot_ = slot_->next(distance);
return *this; return *this;
} }
private: private:
const detail::VariantSlot* _slot; const detail::VariantSlot* slot_;
}; };
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

@ -16,8 +16,8 @@ class VariantData;
class VariantSlot; class VariantSlot;
class CollectionData { class CollectionData {
VariantSlot* _head; VariantSlot* head_;
VariantSlot* _tail; VariantSlot* tail_;
public: public:
// Must be a POD! // Must be a POD!
@ -67,7 +67,7 @@ class CollectionData {
bool copyFrom(const CollectionData& src, MemoryPool* pool); bool copyFrom(const CollectionData& src, MemoryPool* pool);
VariantSlot* head() const { VariantSlot* head() const {
return _head; return head_;
} }
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance); void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance);

@ -16,13 +16,13 @@ inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
if (!slot) if (!slot)
return 0; return 0;
if (_tail) { if (tail_) {
ARDUINOJSON_ASSERT(pool->owns(_tail)); // Can't alter a linked array/object ARDUINOJSON_ASSERT(pool->owns(tail_)); // Can't alter a linked array/object
_tail->setNextNotNull(slot); tail_->setNextNotNull(slot);
_tail = slot; tail_ = slot;
} else { } else {
_head = slot; head_ = slot;
_tail = slot; tail_ = slot;
} }
slot->clear(); slot->clear();
@ -45,8 +45,8 @@ inline VariantData* CollectionData::addMember(TAdaptedString key,
} }
inline void CollectionData::clear() { inline void CollectionData::clear() {
_head = 0; head_ = 0;
_tail = 0; tail_ = 0;
} }
template <typename TAdaptedString> template <typename TAdaptedString>
@ -57,7 +57,7 @@ inline bool CollectionData::containsKey(const TAdaptedString& key) const {
inline bool CollectionData::copyFrom(const CollectionData& src, inline bool CollectionData::copyFrom(const CollectionData& src,
MemoryPool* pool) { MemoryPool* pool) {
clear(); clear();
for (VariantSlot* s = src._head; s; s = s->next()) { for (VariantSlot* s = src.head_; s; s = s->next()) {
VariantData* var; VariantData* var;
if (s->key() != 0) { if (s->key() != 0) {
JsonString key(s->key(), JsonString key(s->key(),
@ -78,7 +78,7 @@ template <typename TAdaptedString>
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const { inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
if (key.isNull()) if (key.isNull())
return 0; return 0;
VariantSlot* slot = _head; VariantSlot* slot = head_;
while (slot) { while (slot) {
if (stringEquals(key, adaptString(slot->key()))) if (stringEquals(key, adaptString(slot->key())))
break; break;
@ -88,13 +88,13 @@ inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
} }
inline VariantSlot* CollectionData::getSlot(size_t index) const { inline VariantSlot* CollectionData::getSlot(size_t index) const {
if (!_head) if (!head_)
return 0; return 0;
return _head->next(index); return head_->next(index);
} }
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const { inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
VariantSlot* current = _head; VariantSlot* current = head_;
while (current) { while (current) {
VariantSlot* next = current->next(); VariantSlot* next = current->next();
if (next == target) if (next == target)
@ -132,7 +132,7 @@ inline VariantData* CollectionData::getElement(size_t index) const {
inline VariantData* CollectionData::getOrAddElement(size_t index, inline VariantData* CollectionData::getOrAddElement(size_t index,
MemoryPool* pool) { MemoryPool* pool) {
VariantSlot* slot = _head; VariantSlot* slot = head_;
while (slot && index > 0) { while (slot && index > 0) {
slot = slot->next(); slot = slot->next();
index--; index--;
@ -154,9 +154,9 @@ inline void CollectionData::removeSlot(VariantSlot* slot) {
if (prev) if (prev)
prev->setNext(next); prev->setNext(next);
else else
_head = next; head_ = next;
if (!next) if (!next)
_tail = prev; tail_ = prev;
} }
inline void CollectionData::removeElement(size_t index) { inline void CollectionData::removeElement(size_t index) {
@ -165,7 +165,7 @@ inline void CollectionData::removeElement(size_t index) {
inline size_t CollectionData::memoryUsage() const { inline size_t CollectionData::memoryUsage() const {
size_t total = 0; size_t total = 0;
for (VariantSlot* s = _head; s; s = s->next()) { for (VariantSlot* s = head_; s; s = s->next()) {
total += sizeof(VariantSlot) + s->data()->memoryUsage(); total += sizeof(VariantSlot) + s->data()->memoryUsage();
if (s->ownsKey()) if (s->ownsKey())
total += strlen(s->key()) + 1; total += strlen(s->key()) + 1;
@ -174,7 +174,7 @@ inline size_t CollectionData::memoryUsage() const {
} }
inline size_t CollectionData::size() const { inline size_t CollectionData::size() const {
return slotSize(_head); return slotSize(head_);
} }
template <typename T> template <typename T>
@ -188,9 +188,9 @@ inline void movePointer(T*& p, ptrdiff_t offset) {
inline void CollectionData::movePointers(ptrdiff_t stringDistance, inline void CollectionData::movePointers(ptrdiff_t stringDistance,
ptrdiff_t variantDistance) { ptrdiff_t variantDistance) {
movePointer(_head, variantDistance); movePointer(head_, variantDistance);
movePointer(_tail, variantDistance); movePointer(tail_, variantDistance);
for (VariantSlot* slot = _head; slot; slot = slot->next()) for (VariantSlot* slot = head_; slot; slot = slot->next())
slot->movePointers(stringDistance, variantDistance); slot->movePointers(stringDistance, variantDistance);
} }

@ -130,10 +130,14 @@
# define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0 # define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
# endif # endif
// Disable support for PROGMEM // Enable PROGMEM support on AVR only
# ifndef ARDUINOJSON_ENABLE_PROGMEM # ifndef ARDUINOJSON_ENABLE_PROGMEM
# ifdef __AVR__
# define ARDUINOJSON_ENABLE_PROGMEM 1
# else
# define ARDUINOJSON_ENABLE_PROGMEM 0 # define ARDUINOJSON_ENABLE_PROGMEM 0
# endif # endif
# endif
#endif // ARDUINO #endif // ARDUINO

@ -26,49 +26,49 @@ class DeserializationError {
}; };
DeserializationError() {} DeserializationError() {}
DeserializationError(Code c) : _code(c) {} DeserializationError(Code c) : code_(c) {}
// Compare with DeserializationError // Compare with DeserializationError
friend bool operator==(const DeserializationError& lhs, friend bool operator==(const DeserializationError& lhs,
const DeserializationError& rhs) { const DeserializationError& rhs) {
return lhs._code == rhs._code; return lhs.code_ == rhs.code_;
} }
friend bool operator!=(const DeserializationError& lhs, friend bool operator!=(const DeserializationError& lhs,
const DeserializationError& rhs) { const DeserializationError& rhs) {
return lhs._code != rhs._code; return lhs.code_ != rhs.code_;
} }
// Compare with Code // Compare with Code
friend bool operator==(const DeserializationError& lhs, Code rhs) { friend bool operator==(const DeserializationError& lhs, Code rhs) {
return lhs._code == rhs; return lhs.code_ == rhs;
} }
friend bool operator==(Code lhs, const DeserializationError& rhs) { friend bool operator==(Code lhs, const DeserializationError& rhs) {
return lhs == rhs._code; return lhs == rhs.code_;
} }
friend bool operator!=(const DeserializationError& lhs, Code rhs) { friend bool operator!=(const DeserializationError& lhs, Code rhs) {
return lhs._code != rhs; return lhs.code_ != rhs;
} }
friend bool operator!=(Code lhs, const DeserializationError& rhs) { friend bool operator!=(Code lhs, const DeserializationError& rhs) {
return lhs != rhs._code; return lhs != rhs.code_;
} }
// Returns true if there is an error // Returns true if there is an error
explicit operator bool() const { explicit operator bool() const {
return _code != Ok; return code_ != Ok;
} }
// Returns internal enum, useful for switch statement // Returns internal enum, useful for switch statement
Code code() const { Code code() const {
return _code; return code_;
} }
const char* c_str() const { const char* c_str() const {
static const char* messages[] = { static const char* messages[] = {
"Ok", "EmptyInput", "IncompleteInput", "Ok", "EmptyInput", "IncompleteInput",
"InvalidInput", "NoMemory", "TooDeep"}; "InvalidInput", "NoMemory", "TooDeep"};
ARDUINOJSON_ASSERT(static_cast<size_t>(_code) < ARDUINOJSON_ASSERT(static_cast<size_t>(code_) <
sizeof(messages) / sizeof(messages[0])); sizeof(messages) / sizeof(messages[0]));
return messages[_code]; return messages[code_];
} }
#if ARDUINOJSON_ENABLE_PROGMEM #if ARDUINOJSON_ENABLE_PROGMEM
@ -82,12 +82,12 @@ class DeserializationError {
ARDUINOJSON_DEFINE_PROGMEM_ARRAY(const char*, messages, ARDUINOJSON_DEFINE_PROGMEM_ARRAY(const char*, messages,
{s0, s1, s2, s3, s4, s5}); {s0, s1, s2, s3, s4, s5});
return reinterpret_cast<const __FlashStringHelper*>( return reinterpret_cast<const __FlashStringHelper*>(
detail::pgm_read(messages + _code)); detail::pgm_read(messages + code_));
} }
#endif #endif
private: private:
Code _code; Code code_;
}; };
#if ARDUINOJSON_ENABLE_STD_STREAM #if ARDUINOJSON_ENABLE_STD_STREAM

@ -11,34 +11,34 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
namespace DeserializationOption { namespace DeserializationOption {
class Filter { class Filter {
public: public:
explicit Filter(JsonVariantConst v) : _variant(v) {} explicit Filter(JsonVariantConst v) : variant_(v) {}
bool allow() const { bool allow() const {
return _variant; return variant_;
} }
bool allowArray() const { bool allowArray() const {
return _variant == true || _variant.is<JsonArrayConst>(); return variant_ == true || variant_.is<JsonArrayConst>();
} }
bool allowObject() const { bool allowObject() const {
return _variant == true || _variant.is<JsonObjectConst>(); return variant_ == true || variant_.is<JsonObjectConst>();
} }
bool allowValue() const { bool allowValue() const {
return _variant == true; return variant_ == true;
} }
template <typename TKey> template <typename TKey>
Filter operator[](const TKey& key) const { Filter operator[](const TKey& key) const {
if (_variant == true) // "true" means "allow recursively" if (variant_ == true) // "true" means "allow recursively"
return *this; return *this;
JsonVariantConst member = _variant[key]; JsonVariantConst member = variant_[key];
return Filter(member.isNull() ? _variant["*"] : member); return Filter(member.isNull() ? variant_["*"] : member);
} }
private: private:
JsonVariantConst _variant; JsonVariantConst variant_;
}; };
} // namespace DeserializationOption } // namespace DeserializationOption

@ -12,20 +12,20 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
namespace DeserializationOption { namespace DeserializationOption {
class NestingLimit { class NestingLimit {
public: public:
NestingLimit() : _value(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {} NestingLimit() : value_(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
explicit NestingLimit(uint8_t n) : _value(n) {} explicit NestingLimit(uint8_t n) : value_(n) {}
NestingLimit decrement() const { NestingLimit decrement() const {
ARDUINOJSON_ASSERT(_value > 0); ARDUINOJSON_ASSERT(value_ > 0);
return NestingLimit(static_cast<uint8_t>(_value - 1)); return NestingLimit(static_cast<uint8_t>(value_ - 1));
} }
bool reached() const { bool reached() const {
return _value == 0; return value_ == 0;
} }
private: private:
uint8_t _value; uint8_t value_;
}; };
} // namespace DeserializationOption } // namespace DeserializationOption

@ -15,18 +15,20 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TSource, typename Enable = void> template <typename TSource, typename Enable = void>
struct Reader { struct Reader {
public: public:
Reader(TSource& source) : _source(&source) {} Reader(TSource& source) : source_(&source) {}
int read() { int read() {
return _source->read(); // Error here? You passed an unsupported input type // clang-format off
return source_->read(); // Error here? See https://arduinojson.org/v6/invalid-input/
// clang-format on
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
return _source->readBytes(buffer, length); return source_->readBytes(buffer, length);
} }
private: private:
TSource* _source; TSource* source_;
}; };
template <typename TSource, typename Enable = void> template <typename TSource, typename Enable = void>

@ -12,20 +12,20 @@ template <typename TSource>
struct Reader<TSource, struct Reader<TSource,
typename enable_if<is_base_of<Stream, TSource>::value>::type> { typename enable_if<is_base_of<Stream, TSource>::value>::type> {
public: public:
explicit Reader(Stream& stream) : _stream(&stream) {} explicit Reader(Stream& stream) : stream_(&stream) {}
int read() { int read() {
// don't use _stream.read() as it ignores the timeout // don't use stream_.read() as it ignores the timeout
char c; char c;
return _stream->readBytes(&c, 1) ? static_cast<unsigned char>(c) : -1; return stream_->readBytes(&c, 1) ? static_cast<unsigned char>(c) : -1;
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
return _stream->readBytes(buffer, length); return stream_->readBytes(buffer, length);
} }
private: private:
Stream* _stream; Stream* stream_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -4,51 +4,51 @@
#pragma once #pragma once
#include <Arduino.h> #include <ArduinoJson/Polyfills/pgmspace.hpp>
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <> template <>
struct Reader<const __FlashStringHelper*, void> { struct Reader<const __FlashStringHelper*, void> {
const char* _ptr; const char* ptr_;
public: public:
explicit Reader(const __FlashStringHelper* ptr) explicit Reader(const __FlashStringHelper* ptr)
: _ptr(reinterpret_cast<const char*>(ptr)) {} : ptr_(reinterpret_cast<const char*>(ptr)) {}
int read() { int read() {
return pgm_read_byte(_ptr++); return pgm_read_byte(ptr_++);
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
memcpy_P(buffer, _ptr, length); memcpy_P(buffer, ptr_, length);
_ptr += length; ptr_ += length;
return length; return length;
} }
}; };
template <> template <>
struct BoundedReader<const __FlashStringHelper*, void> { struct BoundedReader<const __FlashStringHelper*, void> {
const char* _ptr; const char* ptr_;
const char* _end; const char* end_;
public: public:
explicit BoundedReader(const __FlashStringHelper* ptr, size_t size) explicit BoundedReader(const __FlashStringHelper* ptr, size_t size)
: _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {} : ptr_(reinterpret_cast<const char*>(ptr)), end_(ptr_ + size) {}
int read() { int read() {
if (_ptr < _end) if (ptr_ < end_)
return pgm_read_byte(_ptr++); return pgm_read_byte(ptr_++);
else else
return -1; return -1;
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
size_t available = static_cast<size_t>(_end - _ptr); size_t available = static_cast<size_t>(end_ - ptr_);
if (available < length) if (available < length)
length = available; length = available;
memcpy_P(buffer, _ptr, length); memcpy_P(buffer, ptr_, length);
_ptr += length; ptr_ += length;
return length; return length;
} }
}; };

@ -8,23 +8,23 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TIterator> template <typename TIterator>
class IteratorReader { class IteratorReader {
TIterator _ptr, _end; TIterator ptr_, end_;
public: public:
explicit IteratorReader(TIterator begin, TIterator end) explicit IteratorReader(TIterator begin, TIterator end)
: _ptr(begin), _end(end) {} : ptr_(begin), end_(end) {}
int read() { int read() {
if (_ptr < _end) if (ptr_ < end_)
return static_cast<unsigned char>(*_ptr++); return static_cast<unsigned char>(*ptr_++);
else else
return -1; return -1;
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
size_t i = 0; size_t i = 0;
while (i < length && _ptr < _end) while (i < length && ptr_ < end_)
buffer[i++] = *_ptr++; buffer[i++] = *ptr_++;
return i; return i;
} }
}; };

@ -21,19 +21,19 @@ struct IsCharOrVoid<const T> : IsCharOrVoid<T> {};
template <typename TSource> template <typename TSource>
struct Reader<TSource*, struct Reader<TSource*,
typename enable_if<IsCharOrVoid<TSource>::value>::type> { typename enable_if<IsCharOrVoid<TSource>::value>::type> {
const char* _ptr; const char* ptr_;
public: public:
explicit Reader(const void* ptr) explicit Reader(const void* ptr)
: _ptr(ptr ? reinterpret_cast<const char*>(ptr) : "") {} : ptr_(ptr ? reinterpret_cast<const char*>(ptr) : "") {}
int read() { int read() {
return static_cast<unsigned char>(*_ptr++); return static_cast<unsigned char>(*ptr_++);
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
for (size_t i = 0; i < length; i++) for (size_t i = 0; i < length; i++)
buffer[i] = *_ptr++; buffer[i] = *ptr_++;
return length; return length;
} }
}; };

@ -12,19 +12,19 @@ template <typename TSource>
struct Reader<TSource, typename enable_if< struct Reader<TSource, typename enable_if<
is_base_of<std::istream, TSource>::value>::type> { is_base_of<std::istream, TSource>::value>::type> {
public: public:
explicit Reader(std::istream& stream) : _stream(&stream) {} explicit Reader(std::istream& stream) : stream_(&stream) {}
int read() { int read() {
return _stream->get(); return stream_->get();
} }
size_t readBytes(char* buffer, size_t length) { size_t readBytes(char* buffer, size_t length) {
_stream->read(buffer, static_cast<std::streamsize>(length)); stream_->read(buffer, static_cast<std::streamsize>(length));
return static_cast<size_t>(_stream->gcount()); return static_cast<size_t>(stream_->gcount());
} }
private: private:
std::istream* _stream; std::istream* stream_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -12,6 +12,17 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// A meta-function that returns the first type of the parameter pack
// or void if empty
template <typename...>
struct first_or_void {
using type = void;
};
template <typename T, typename... Rest>
struct first_or_void<T, Rest...> {
using type = T;
};
template <template <typename, typename> class TDeserializer, typename TReader, template <template <typename, typename> class TDeserializer, typename TReader,
typename TWriter> typename TWriter>
TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool* pool, TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool* pool,
@ -22,7 +33,9 @@ TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool* pool,
} }
template <template <typename, typename> class TDeserializer, typename TStream, template <template <typename, typename> class TDeserializer, typename TStream,
typename... Args> typename... Args,
typename = typename enable_if< // issue #1897
!is_integral<typename first_or_void<Args...>::type>::value>::type>
DeserializationError deserialize(JsonDocument& doc, TStream&& input, DeserializationError deserialize(JsonDocument& doc, TStream&& input,
Args... args) { Args... args) {
auto reader = makeReader(detail::forward<TStream>(input)); auto reader = makeReader(detail::forward<TStream>(input));

@ -14,27 +14,27 @@ template <typename TAllocator>
class AllocatorOwner { class AllocatorOwner {
public: public:
AllocatorOwner() {} AllocatorOwner() {}
AllocatorOwner(TAllocator a) : _allocator(a) {} AllocatorOwner(TAllocator a) : allocator_(a) {}
void* allocate(size_t size) { void* allocate(size_t size) {
return _allocator.allocate(size); return allocator_.allocate(size);
} }
void deallocate(void* ptr) { void deallocate(void* ptr) {
if (ptr) if (ptr)
_allocator.deallocate(ptr); allocator_.deallocate(ptr);
} }
void* reallocate(void* ptr, size_t new_size) { void* reallocate(void* ptr, size_t new_size) {
return _allocator.reallocate(ptr, new_size); return allocator_.reallocate(ptr, new_size);
} }
TAllocator& allocator() { TAllocator& allocator() {
return _allocator; return allocator_;
} }
private: private:
TAllocator _allocator; TAllocator allocator_;
}; };
// A JsonDocument that uses the provided allocator to allocate its memory pool. // A JsonDocument that uses the provided allocator to allocate its memory pool.
@ -106,18 +106,18 @@ class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
// Reduces the capacity of the memory pool to match the current usage. // Reduces the capacity of the memory pool to match the current usage.
// https://arduinojson.org/v6/api/basicjsondocument/shrinktofit/ // https://arduinojson.org/v6/api/basicjsondocument/shrinktofit/
void shrinkToFit() { void shrinkToFit() {
ptrdiff_t bytes_reclaimed = _pool.squash(); ptrdiff_t bytes_reclaimed = pool_.squash();
if (bytes_reclaimed == 0) if (bytes_reclaimed == 0)
return; return;
void* old_ptr = _pool.buffer(); void* old_ptr = pool_.buffer();
void* new_ptr = this->reallocate(old_ptr, _pool.capacity()); void* new_ptr = this->reallocate(old_ptr, pool_.capacity());
ptrdiff_t ptr_offset = ptrdiff_t ptr_offset =
static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr); static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr);
_pool.movePointers(ptr_offset); pool_.movePointers(ptr_offset);
_data.movePointers(ptr_offset, ptr_offset - bytes_reclaimed); data_.movePointers(ptr_offset, ptr_offset - bytes_reclaimed);
} }
// Reclaims the memory leaked when removing and replacing values. // Reclaims the memory leaked when removing and replacing values.
@ -127,7 +127,6 @@ class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
BasicJsonDocument tmp(*this); BasicJsonDocument tmp(*this);
if (!tmp.capacity()) if (!tmp.capacity())
return false; return false;
tmp.set(*this);
moveAssignFrom(tmp); moveAssignFrom(tmp);
return true; return true;
} }
@ -142,7 +141,7 @@ class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
void reallocPool(size_t requiredSize) { void reallocPool(size_t requiredSize) {
size_t capa = detail::addPadding(requiredSize); size_t capa = detail::addPadding(requiredSize);
if (capa == _pool.capacity()) if (capa == pool_.capacity())
return; return;
freePool(); freePool();
replacePool(allocPool(detail::addPadding(requiredSize))); replacePool(allocPool(detail::addPadding(requiredSize)));
@ -159,10 +158,10 @@ class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
void moveAssignFrom(BasicJsonDocument& src) { void moveAssignFrom(BasicJsonDocument& src) {
freePool(); freePool();
_data = src._data; data_ = src.data_;
_pool = src._pool; pool_ = src.pool_;
src._data.setNull(); src.data_.setNull();
src._pool = {0, 0}; src.pool_ = {0, 0};
} }
}; };

@ -40,8 +40,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Empties the document and resets the memory pool // Empties the document and resets the memory pool
// https://arduinojson.org/v6/api/jsondocument/clear/ // https://arduinojson.org/v6/api/jsondocument/clear/
void clear() { void clear() {
_pool.clear(); pool_.clear();
_data.init(); data_.setNull();
} }
// Returns true if the root is of the specified type. // Returns true if the root is of the specified type.
@ -67,31 +67,31 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Returns the number of used bytes in the memory pool. // Returns the number of used bytes in the memory pool.
// https://arduinojson.org/v6/api/jsondocument/memoryusage/ // https://arduinojson.org/v6/api/jsondocument/memoryusage/
size_t memoryUsage() const { size_t memoryUsage() const {
return _pool.size(); return pool_.size();
} }
// Returns trues if the memory pool was too small. // Returns trues if the memory pool was too small.
// https://arduinojson.org/v6/api/jsondocument/overflowed/ // https://arduinojson.org/v6/api/jsondocument/overflowed/
bool overflowed() const { bool overflowed() const {
return _pool.overflowed(); return pool_.overflowed();
} }
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
// https://arduinojson.org/v6/api/jsondocument/nesting/ // https://arduinojson.org/v6/api/jsondocument/nesting/
size_t nesting() const { size_t nesting() const {
return variantNesting(&_data); return variantNesting(&data_);
} }
// Returns the capacity of the memory pool. // Returns the capacity of the memory pool.
// https://arduinojson.org/v6/api/jsondocument/capacity/ // https://arduinojson.org/v6/api/jsondocument/capacity/
size_t capacity() const { size_t capacity() const {
return _pool.capacity(); return pool_.capacity();
} }
// Returns the number of elements in the root array or object. // Returns the number of elements in the root array or object.
// https://arduinojson.org/v6/api/jsondocument/size/ // https://arduinojson.org/v6/api/jsondocument/size/
size_t size() const { size_t size() const {
return _data.size(); return data_.size();
} }
// Copies the specified document. // Copies the specified document.
@ -161,14 +161,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// https://arduinojson.org/v6/api/jsondocument/containskey/ // https://arduinojson.org/v6/api/jsondocument/containskey/
template <typename TChar> template <typename TChar>
bool containsKey(TChar* key) const { bool containsKey(TChar* key) const {
return _data.getMember(detail::adaptString(key)) != 0; return data_.getMember(detail::adaptString(key)) != 0;
} }
// Returns true if the root object contains the specified key. // Returns true if the root object contains the specified key.
// https://arduinojson.org/v6/api/jsondocument/containskey/ // https://arduinojson.org/v6/api/jsondocument/containskey/
template <typename TString> template <typename TString>
bool containsKey(const TString& key) const { bool containsKey(const TString& key) const {
return _data.getMember(detail::adaptString(key)) != 0; return data_.getMember(detail::adaptString(key)) != 0;
} }
// Gets or sets a root object's member. // Gets or sets a root object's member.
@ -197,7 +197,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value, FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst(_data.getMember(detail::adaptString(key))); return JsonVariantConst(data_.getMember(detail::adaptString(key)));
} }
// Gets a root object's member. // Gets a root object's member.
@ -206,7 +206,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value, FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst(_data.getMember(detail::adaptString(key))); return JsonVariantConst(data_.getMember(detail::adaptString(key)));
} }
// Gets or sets a root array's element. // Gets or sets a root array's element.
@ -218,14 +218,14 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets a root array's member. // Gets a root array's member.
// https://arduinojson.org/v6/api/jsondocument/subscript/ // https://arduinojson.org/v6/api/jsondocument/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const { FORCE_INLINE JsonVariantConst operator[](size_t index) const {
return JsonVariantConst(_data.getElement(index)); return JsonVariantConst(data_.getElement(index));
} }
// Appends a new (null) element to the root array. // Appends a new (null) element to the root array.
// Returns a reference to the new element. // Returns a reference to the new element.
// https://arduinojson.org/v6/api/jsondocument/add/ // https://arduinojson.org/v6/api/jsondocument/add/
FORCE_INLINE JsonVariant add() { FORCE_INLINE JsonVariant add() {
return JsonVariant(&_pool, _data.addElement(&_pool)); return JsonVariant(&pool_, data_.addElement(&pool_));
} }
// Appends a value to the root array. // Appends a value to the root array.
@ -246,7 +246,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// ⚠ Doesn't release the memory associated with the removed element. // ⚠ Doesn't release the memory associated with the removed element.
// https://arduinojson.org/v6/api/jsondocument/remove/ // https://arduinojson.org/v6/api/jsondocument/remove/
FORCE_INLINE void remove(size_t index) { FORCE_INLINE void remove(size_t index) {
_data.remove(index); data_.remove(index);
} }
// Removes a member of the root object. // Removes a member of the root object.
@ -255,7 +255,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TChar> template <typename TChar>
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value>::type FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value>::type
remove(TChar* key) { remove(TChar* key) {
_data.remove(detail::adaptString(key)); data_.remove(detail::adaptString(key));
} }
// Removes a member of the root object. // Removes a member of the root object.
@ -265,7 +265,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
FORCE_INLINE FORCE_INLINE
typename detail::enable_if<detail::IsString<TString>::value>::type typename detail::enable_if<detail::IsString<TString>::value>::type
remove(const TString& key) { remove(const TString& key) {
_data.remove(detail::adaptString(key)); data_.remove(detail::adaptString(key));
} }
FORCE_INLINE operator JsonVariant() { FORCE_INLINE operator JsonVariant() {
@ -277,50 +277,44 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
} }
protected: protected:
JsonDocument() : _pool(0, 0) { JsonDocument() : pool_(0, 0) {}
_data.init();
}
JsonDocument(detail::MemoryPool pool) : _pool(pool) { JsonDocument(detail::MemoryPool pool) : pool_(pool) {}
_data.init();
}
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) { JsonDocument(char* buf, size_t capa) : pool_(buf, capa) {}
_data.init();
}
~JsonDocument() {} ~JsonDocument() {}
void replacePool(detail::MemoryPool pool) { void replacePool(detail::MemoryPool pool) {
_pool = pool; pool_ = pool;
} }
JsonVariant getVariant() { JsonVariant getVariant() {
return JsonVariant(&_pool, &_data); return JsonVariant(&pool_, &data_);
} }
JsonVariantConst getVariant() const { JsonVariantConst getVariant() const {
return JsonVariantConst(&_data); return JsonVariantConst(&data_);
} }
detail::MemoryPool _pool; detail::MemoryPool pool_;
detail::VariantData _data; detail::VariantData data_;
protected: protected:
detail::MemoryPool* getPool() { detail::MemoryPool* getPool() {
return &_pool; return &pool_;
} }
detail::VariantData* getData() { detail::VariantData* getData() {
return &_data; return &data_;
} }
const detail::VariantData* getData() const { const detail::VariantData* getData() const {
return &_data; return &data_;
} }
detail::VariantData* getOrCreateData() { detail::VariantData* getOrCreateData() {
return &_data; return &data_;
} }
}; };

@ -11,14 +11,14 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
// A JsonDocument with a memory pool on the stack. // A JsonDocument with a memory pool on the stack.
template <size_t desiredCapacity> template <size_t desiredCapacity>
class StaticJsonDocument : public JsonDocument { class StaticJsonDocument : public JsonDocument {
static const size_t _capacity = static const size_t capacity_ =
detail::AddPadding<detail::Max<1, desiredCapacity>::value>::value; detail::AddPadding<detail::Max<1, desiredCapacity>::value>::value;
public: public:
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {} StaticJsonDocument() : JsonDocument(buffer_, capacity_) {}
StaticJsonDocument(const StaticJsonDocument& src) StaticJsonDocument(const StaticJsonDocument& src)
: JsonDocument(_buffer, _capacity) { : JsonDocument(buffer_, capacity_) {
set(src); set(src);
} }
@ -27,12 +27,12 @@ class StaticJsonDocument : public JsonDocument {
const T& src, const T& src,
typename detail::enable_if< typename detail::enable_if<
detail::is_convertible<T, JsonVariantConst>::value>::type* = 0) detail::is_convertible<T, JsonVariantConst>::value>::type* = 0)
: JsonDocument(_buffer, _capacity) { : JsonDocument(buffer_, capacity_) {
set(src); set(src);
} }
// disambiguate // disambiguate
StaticJsonDocument(JsonVariant src) : JsonDocument(_buffer, _capacity) { StaticJsonDocument(JsonVariant src) : JsonDocument(buffer_, capacity_) {
set(src); set(src);
} }
@ -55,7 +55,7 @@ class StaticJsonDocument : public JsonDocument {
} }
private: private:
char _buffer[_capacity]; char buffer_[capacity_];
}; };
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

@ -23,10 +23,10 @@ class JsonDeserializer {
public: public:
JsonDeserializer(MemoryPool* pool, TReader reader, JsonDeserializer(MemoryPool* pool, TReader reader,
TStringStorage stringStorage) TStringStorage stringStorage)
: _stringStorage(stringStorage), : stringStorage_(stringStorage),
_foundSomething(false), foundSomething_(false),
_latch(reader), latch_(reader),
_pool(pool) {} pool_(pool) {}
template <typename TFilter> template <typename TFilter>
DeserializationError parse(VariantData& variant, TFilter filter, DeserializationError parse(VariantData& variant, TFilter filter,
@ -35,7 +35,7 @@ class JsonDeserializer {
err = parseVariant(variant, filter, nestingLimit); err = parseVariant(variant, filter, nestingLimit);
if (!err && _latch.last() != 0 && !variant.isEnclosed()) { if (!err && latch_.last() != 0 && !variant.isEnclosed()) {
// We don't detect trailing characters earlier, so we need to check now // We don't detect trailing characters earlier, so we need to check now
return DeserializationError::InvalidInput; return DeserializationError::InvalidInput;
} }
@ -45,11 +45,11 @@ class JsonDeserializer {
private: private:
char current() { char current() {
return _latch.current(); return latch_.current();
} }
void move() { void move() {
_latch.clear(); latch_.clear();
} }
bool eat(char charToSkip) { bool eat(char charToSkip) {
@ -173,7 +173,7 @@ class JsonDeserializer {
for (;;) { for (;;) {
if (memberFilter.allow()) { if (memberFilter.allow()) {
// Allocate slot in array // Allocate slot in array
VariantData* value = array.addElement(_pool); VariantData* value = array.addElement(pool_);
if (!value) if (!value)
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
@ -269,7 +269,7 @@ class JsonDeserializer {
if (!eat(':')) if (!eat(':'))
return DeserializationError::InvalidInput; return DeserializationError::InvalidInput;
JsonString key = _stringStorage.str(); JsonString key = stringStorage_.str();
TFilter memberFilter = filter[key.c_str()]; TFilter memberFilter = filter[key.c_str()];
@ -278,10 +278,10 @@ class JsonDeserializer {
if (!variant) { if (!variant) {
// Save key in memory pool. // Save key in memory pool.
// This MUST be done before adding the slot. // This MUST be done before adding the slot.
key = _stringStorage.save(); key = stringStorage_.save();
// Allocate slot in object // Allocate slot in object
VariantSlot* slot = object.addSlot(_pool); VariantSlot* slot = object.addSlot(pool_);
if (!slot) if (!slot)
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
@ -377,7 +377,7 @@ class JsonDeserializer {
} }
DeserializationError::Code parseKey() { DeserializationError::Code parseKey() {
_stringStorage.startString(); stringStorage_.startString();
if (isQuote(current())) { if (isQuote(current())) {
return parseQuotedString(); return parseQuotedString();
} else { } else {
@ -388,13 +388,13 @@ class JsonDeserializer {
DeserializationError::Code parseStringValue(VariantData& variant) { DeserializationError::Code parseStringValue(VariantData& variant) {
DeserializationError::Code err; DeserializationError::Code err;
_stringStorage.startString(); stringStorage_.startString();
err = parseQuotedString(); err = parseQuotedString();
if (err) if (err)
return err; return err;
variant.setString(_stringStorage.save()); variant.setString(stringStorage_.save());
return DeserializationError::Ok; return DeserializationError::Ok;
} }
@ -430,9 +430,9 @@ class JsonDeserializer {
if (err) if (err)
return err; return err;
if (codepoint.append(codeunit)) if (codepoint.append(codeunit))
Utf8::encodeCodepoint(codepoint.value(), _stringStorage); Utf8::encodeCodepoint(codepoint.value(), stringStorage_);
#else #else
_stringStorage.append('\\'); stringStorage_.append('\\');
#endif #endif
continue; continue;
} }
@ -444,10 +444,10 @@ class JsonDeserializer {
move(); move();
} }
_stringStorage.append(c); stringStorage_.append(c);
} }
if (!_stringStorage.isValid()) if (!stringStorage_.isValid())
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
return DeserializationError::Ok; return DeserializationError::Ok;
@ -460,14 +460,14 @@ class JsonDeserializer {
if (canBeInNonQuotedString(c)) { // no quotes if (canBeInNonQuotedString(c)) { // no quotes
do { do {
move(); move();
_stringStorage.append(c); stringStorage_.append(c);
c = current(); c = current();
} while (canBeInNonQuotedString(c)); } while (canBeInNonQuotedString(c));
} else { } else {
return DeserializationError::InvalidInput; return DeserializationError::InvalidInput;
} }
if (!_stringStorage.isValid()) if (!stringStorage_.isValid())
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
return DeserializationError::Ok; return DeserializationError::Ok;
@ -516,12 +516,12 @@ class JsonDeserializer {
char c = current(); char c = current();
while (canBeInNumber(c) && n < 63) { while (canBeInNumber(c) && n < 63) {
move(); move();
_buffer[n++] = c; buffer_[n++] = c;
c = current(); c = current();
} }
_buffer[n] = 0; buffer_[n] = 0;
if (!parseNumber(_buffer, result)) if (!parseNumber(buffer_, result))
return DeserializationError::InvalidInput; return DeserializationError::InvalidInput;
return DeserializationError::Ok; return DeserializationError::Ok;
@ -585,7 +585,7 @@ class JsonDeserializer {
switch (current()) { switch (current()) {
// end of string // end of string
case '\0': case '\0':
return _foundSomething ? DeserializationError::IncompleteInput return foundSomething_ ? DeserializationError::IncompleteInput
: DeserializationError::EmptyInput; : DeserializationError::EmptyInput;
// spaces // spaces
@ -640,7 +640,7 @@ class JsonDeserializer {
#endif #endif
default: default:
_foundSomething = true; foundSomething_ = true;
return DeserializationError::Ok; return DeserializationError::Ok;
} }
} }
@ -659,11 +659,11 @@ class JsonDeserializer {
return DeserializationError::Ok; return DeserializationError::Ok;
} }
TStringStorage _stringStorage; TStringStorage stringStorage_;
bool _foundSomething; bool foundSomething_;
Latch<TReader> _latch; Latch<TReader> latch_;
MemoryPool* _pool; MemoryPool* pool_;
char _buffer[64]; // using a member instead of a local variable because it char buffer_[64]; // using a member instead of a local variable because it
// ended in the recursive path after compiler inlined the // ended in the recursive path after compiler inlined the
// code // code
}; };

@ -16,7 +16,7 @@ class JsonSerializer : public Visitor<size_t> {
public: public:
static const bool producesText = true; static const bool producesText = true;
JsonSerializer(TWriter writer) : _formatter(writer) {} JsonSerializer(TWriter writer) : formatter_(writer) {}
FORCE_INLINE size_t visitArray(const CollectionData& array) { FORCE_INLINE size_t visitArray(const CollectionData& array) {
write('['); write('[');
@ -43,7 +43,7 @@ class JsonSerializer : public Visitor<size_t> {
const VariantSlot* slot = object.head(); const VariantSlot* slot = object.head();
while (slot != 0) { while (slot != 0) {
_formatter.writeString(slot->key()); formatter_.writeString(slot->key());
write(':'); write(':');
slot->data()->accept(*this); slot->data()->accept(*this);
@ -59,60 +59,60 @@ class JsonSerializer : public Visitor<size_t> {
} }
size_t visitFloat(JsonFloat value) { size_t visitFloat(JsonFloat value) {
_formatter.writeFloat(value); formatter_.writeFloat(value);
return bytesWritten(); return bytesWritten();
} }
size_t visitString(const char* value) { size_t visitString(const char* value) {
_formatter.writeString(value); formatter_.writeString(value);
return bytesWritten(); return bytesWritten();
} }
size_t visitString(const char* value, size_t n) { size_t visitString(const char* value, size_t n) {
_formatter.writeString(value, n); formatter_.writeString(value, n);
return bytesWritten(); return bytesWritten();
} }
size_t visitRawJson(const char* data, size_t n) { size_t visitRawJson(const char* data, size_t n) {
_formatter.writeRaw(data, n); formatter_.writeRaw(data, n);
return bytesWritten(); return bytesWritten();
} }
size_t visitSignedInteger(JsonInteger value) { size_t visitSignedInteger(JsonInteger value) {
_formatter.writeInteger(value); formatter_.writeInteger(value);
return bytesWritten(); return bytesWritten();
} }
size_t visitUnsignedInteger(JsonUInt value) { size_t visitUnsignedInteger(JsonUInt value) {
_formatter.writeInteger(value); formatter_.writeInteger(value);
return bytesWritten(); return bytesWritten();
} }
size_t visitBoolean(bool value) { size_t visitBoolean(bool value) {
_formatter.writeBoolean(value); formatter_.writeBoolean(value);
return bytesWritten(); return bytesWritten();
} }
size_t visitNull() { size_t visitNull() {
_formatter.writeRaw("null"); formatter_.writeRaw("null");
return bytesWritten(); return bytesWritten();
} }
protected: protected:
size_t bytesWritten() const { size_t bytesWritten() const {
return _formatter.bytesWritten(); return formatter_.bytesWritten();
} }
void write(char c) { void write(char c) {
_formatter.writeRaw(c); formatter_.writeRaw(c);
} }
void write(const char* s) { void write(const char* s) {
_formatter.writeRaw(s); formatter_.writeRaw(s);
} }
private: private:
TextFormatter<TWriter> _formatter; TextFormatter<TWriter> formatter_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -11,45 +11,45 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TReader> template <typename TReader>
class Latch { class Latch {
public: public:
Latch(TReader reader) : _reader(reader), _loaded(false) { Latch(TReader reader) : reader_(reader), loaded_(false) {
#if ARDUINOJSON_DEBUG #if ARDUINOJSON_DEBUG
_ended = false; ended_ = false;
#endif #endif
} }
void clear() { void clear() {
_loaded = false; loaded_ = false;
} }
int last() const { int last() const {
return _current; return current_;
} }
FORCE_INLINE char current() { FORCE_INLINE char current() {
if (!_loaded) { if (!loaded_) {
load(); load();
} }
return _current; return current_;
} }
private: private:
void load() { void load() {
ARDUINOJSON_ASSERT(!_ended); ARDUINOJSON_ASSERT(!ended_);
int c = _reader.read(); int c = reader_.read();
#if ARDUINOJSON_DEBUG #if ARDUINOJSON_DEBUG
if (c <= 0) if (c <= 0)
_ended = true; ended_ = true;
#endif #endif
_current = static_cast<char>(c > 0 ? c : 0); current_ = static_cast<char>(c > 0 ? c : 0);
_loaded = true; loaded_ = true;
} }
TReader _reader; TReader reader_;
char _current; // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject) char current_; // NOLINT(clang-analyzer-optin.cplusplus.UninitializedObject)
// Not initialized in constructor (+10 bytes on AVR) // Not initialized in constructor (+10 bytes on AVR)
bool _loaded; bool loaded_;
#if ARDUINOJSON_DEBUG #if ARDUINOJSON_DEBUG
bool _ended; bool ended_;
#endif #endif
}; };

@ -16,13 +16,13 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
typedef JsonSerializer<TWriter> base; typedef JsonSerializer<TWriter> base;
public: public:
PrettyJsonSerializer(TWriter writer) : base(writer), _nesting(0) {} PrettyJsonSerializer(TWriter writer) : base(writer), nesting_(0) {}
size_t visitArray(const CollectionData& array) { size_t visitArray(const CollectionData& array) {
const VariantSlot* slot = array.head(); const VariantSlot* slot = array.head();
if (slot) { if (slot) {
base::write("[\r\n"); base::write("[\r\n");
_nesting++; nesting_++;
while (slot != 0) { while (slot != 0) {
indent(); indent();
slot->data()->accept(*this); slot->data()->accept(*this);
@ -30,7 +30,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
slot = slot->next(); slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n"); base::write(slot ? ",\r\n" : "\r\n");
} }
_nesting--; nesting_--;
indent(); indent();
base::write("]"); base::write("]");
} else { } else {
@ -43,7 +43,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
const VariantSlot* slot = object.head(); const VariantSlot* slot = object.head();
if (slot) { if (slot) {
base::write("{\r\n"); base::write("{\r\n");
_nesting++; nesting_++;
while (slot != 0) { while (slot != 0) {
indent(); indent();
base::visitString(slot->key()); base::visitString(slot->key());
@ -53,7 +53,7 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
slot = slot->next(); slot = slot->next();
base::write(slot ? ",\r\n" : "\r\n"); base::write(slot ? ",\r\n" : "\r\n");
} }
_nesting--; nesting_--;
indent(); indent();
base::write("}"); base::write("}");
} else { } else {
@ -64,11 +64,11 @@ class PrettyJsonSerializer : public JsonSerializer<TWriter> {
private: private:
void indent() { void indent() {
for (uint8_t i = 0; i < _nesting; i++) for (uint8_t i = 0; i < nesting_; i++)
base::write(ARDUINOJSON_TAB); base::write(ARDUINOJSON_TAB);
} }
uint8_t _nesting; uint8_t nesting_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -20,13 +20,13 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TWriter> template <typename TWriter>
class TextFormatter { class TextFormatter {
public: public:
explicit TextFormatter(TWriter writer) : _writer(writer) {} explicit TextFormatter(TWriter writer) : writer_(writer) {}
TextFormatter& operator=(const TextFormatter&) = delete; TextFormatter& operator=(const TextFormatter&) = delete;
// Returns the number of bytes sent to the TWriter implementation. // Returns the number of bytes sent to the TWriter implementation.
size_t bytesWritten() const { size_t bytesWritten() const {
return _writer.count(); return writer_.count();
} }
void writeBoolean(bool value) { void writeBoolean(bool value) {
@ -146,28 +146,28 @@ class TextFormatter {
} }
void writeRaw(const char* s) { void writeRaw(const char* s) {
_writer.write(reinterpret_cast<const uint8_t*>(s), strlen(s)); writer_.write(reinterpret_cast<const uint8_t*>(s), strlen(s));
} }
void writeRaw(const char* s, size_t n) { void writeRaw(const char* s, size_t n) {
_writer.write(reinterpret_cast<const uint8_t*>(s), n); writer_.write(reinterpret_cast<const uint8_t*>(s), n);
} }
void writeRaw(const char* begin, const char* end) { void writeRaw(const char* begin, const char* end) {
_writer.write(reinterpret_cast<const uint8_t*>(begin), writer_.write(reinterpret_cast<const uint8_t*>(begin),
static_cast<size_t>(end - begin)); static_cast<size_t>(end - begin));
} }
template <size_t N> template <size_t N>
void writeRaw(const char (&s)[N]) { void writeRaw(const char (&s)[N]) {
_writer.write(reinterpret_cast<const uint8_t*>(s), N - 1); writer_.write(reinterpret_cast<const uint8_t*>(s), N - 1);
} }
void writeRaw(char c) { void writeRaw(char c) {
_writer.write(static_cast<uint8_t>(c)); writer_.write(static_cast<uint8_t>(c));
} }
protected: protected:
CountingDecorator<TWriter> _writer; CountingDecorator<TWriter> writer_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -31,31 +31,31 @@ inline bool isLowSurrogate(uint16_t codeunit) {
class Codepoint { class Codepoint {
public: public:
Codepoint() : _highSurrogate(0), _codepoint(0) {} Codepoint() : highSurrogate_(0), codepoint_(0) {}
bool append(uint16_t codeunit) { bool append(uint16_t codeunit) {
if (isHighSurrogate(codeunit)) { if (isHighSurrogate(codeunit)) {
_highSurrogate = codeunit & 0x3FF; highSurrogate_ = codeunit & 0x3FF;
return false; return false;
} }
if (isLowSurrogate(codeunit)) { if (isLowSurrogate(codeunit)) {
_codepoint = codepoint_ =
uint32_t(0x10000 + ((_highSurrogate << 10) | (codeunit & 0x3FF))); uint32_t(0x10000 + ((highSurrogate_ << 10) | (codeunit & 0x3FF)));
return true; return true;
} }
_codepoint = codeunit; codepoint_ = codeunit;
return true; return true;
} }
uint32_t value() const { uint32_t value() const {
return _codepoint; return codepoint_;
} }
private: private:
uint16_t _highSurrogate; uint16_t highSurrogate_;
uint32_t _codepoint; uint32_t codepoint_;
}; };
} // namespace Utf16 } // namespace Utf16
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -26,43 +26,43 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
// _begin _end // begin_ end_
// v v // v v
// +-------------+--------------+--------------+ // +-------------+--------------+--------------+
// | strings... | (free) | ...variants | // | strings... | (free) | ...variants |
// +-------------+--------------+--------------+ // +-------------+--------------+--------------+
// ^ ^ // ^ ^
// _left _right // left_ right_
class MemoryPool { class MemoryPool {
public: public:
MemoryPool(char* buf, size_t capa) MemoryPool(char* buf, size_t capa)
: _begin(buf), : begin_(buf),
_left(buf), left_(buf),
_right(buf ? buf + capa : 0), right_(buf ? buf + capa : 0),
_end(buf ? buf + capa : 0), end_(buf ? buf + capa : 0),
_overflowed(false) { overflowed_(false) {
ARDUINOJSON_ASSERT(isAligned(_begin)); ARDUINOJSON_ASSERT(isAligned(begin_));
ARDUINOJSON_ASSERT(isAligned(_right)); ARDUINOJSON_ASSERT(isAligned(right_));
ARDUINOJSON_ASSERT(isAligned(_end)); ARDUINOJSON_ASSERT(isAligned(end_));
} }
void* buffer() { void* buffer() {
return _begin; // NOLINT(clang-analyzer-unix.Malloc) return begin_; // NOLINT(clang-analyzer-unix.Malloc)
// movePointers() alters this pointer // movePointers() alters this pointer
} }
// Gets the capacity of the memoryPool in bytes // Gets the capacity of the memoryPool in bytes
size_t capacity() const { size_t capacity() const {
return size_t(_end - _begin); return size_t(end_ - begin_);
} }
size_t size() const { size_t size() const {
return size_t(_left - _begin + _end - _right); return size_t(left_ - begin_ + end_ - right_);
} }
bool overflowed() const { bool overflowed() const {
return _overflowed; return overflowed_;
} }
VariantSlot* allocVariant() { VariantSlot* allocVariant() {
@ -91,40 +91,40 @@ class MemoryPool {
} }
void getFreeZone(char** zoneStart, size_t* zoneSize) const { void getFreeZone(char** zoneStart, size_t* zoneSize) const {
*zoneStart = _left; *zoneStart = left_;
*zoneSize = size_t(_right - _left); *zoneSize = size_t(right_ - left_);
} }
const char* saveStringFromFreeZone(size_t len) { const char* saveStringFromFreeZone(size_t len) {
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
const char* dup = findString(adaptString(_left, len)); const char* dup = findString(adaptString(left_, len));
if (dup) if (dup)
return dup; return dup;
#endif #endif
const char* str = _left; const char* str = left_;
_left += len; left_ += len;
*_left++ = 0; *left_++ = 0;
checkInvariants(); checkInvariants();
return str; return str;
} }
void markAsOverflowed() { void markAsOverflowed() {
_overflowed = true; overflowed_ = true;
} }
void clear() { void clear() {
_left = _begin; left_ = begin_;
_right = _end; right_ = end_;
_overflowed = false; overflowed_ = false;
} }
bool canAlloc(size_t bytes) const { bool canAlloc(size_t bytes) const {
return _left + bytes <= _right; return left_ + bytes <= right_;
} }
bool owns(void* p) const { bool owns(void* p) const {
return _begin <= p && p < _end; return begin_ <= p && p < end_;
} }
// Workaround for missing placement new // Workaround for missing placement new
@ -134,51 +134,51 @@ class MemoryPool {
// Squash the free space between strings and variants // Squash the free space between strings and variants
// //
// _begin _end // begin_ end_
// v v // v v
// +-------------+--------------+ // +-------------+--------------+
// | strings... | ...variants | // | strings... | ...variants |
// +-------------+--------------+ // +-------------+--------------+
// ^ // ^
// _left _right // left_ right_
// //
// This funcion is called before a realloc. // This funcion is called before a realloc.
ptrdiff_t squash() { ptrdiff_t squash() {
char* new_right = addPadding(_left); char* new_right = addPadding(left_);
if (new_right >= _right) if (new_right >= right_)
return 0; return 0;
size_t right_size = static_cast<size_t>(_end - _right); size_t right_size = static_cast<size_t>(end_ - right_);
memmove(new_right, _right, right_size); memmove(new_right, right_, right_size);
ptrdiff_t bytes_reclaimed = _right - new_right; ptrdiff_t bytes_reclaimed = right_ - new_right;
_right = new_right; right_ = new_right;
_end = new_right + right_size; end_ = new_right + right_size;
return bytes_reclaimed; return bytes_reclaimed;
} }
// Move all pointers together // Move all pointers together
// This funcion is called after a realloc. // This funcion is called after a realloc.
void movePointers(ptrdiff_t offset) { void movePointers(ptrdiff_t offset) {
_begin += offset; begin_ += offset;
_left += offset; left_ += offset;
_right += offset; right_ += offset;
_end += offset; end_ += offset;
} }
private: private:
void checkInvariants() { void checkInvariants() {
ARDUINOJSON_ASSERT(_begin <= _left); ARDUINOJSON_ASSERT(begin_ <= left_);
ARDUINOJSON_ASSERT(_left <= _right); ARDUINOJSON_ASSERT(left_ <= right_);
ARDUINOJSON_ASSERT(_right <= _end); ARDUINOJSON_ASSERT(right_ <= end_);
ARDUINOJSON_ASSERT(isAligned(_right)); ARDUINOJSON_ASSERT(isAligned(right_));
} }
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION #if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
template <typename TAdaptedString> template <typename TAdaptedString>
const char* findString(const TAdaptedString& str) const { const char* findString(const TAdaptedString& str) const {
size_t n = str.size(); size_t n = str.size();
for (char* next = _begin; next + n < _left; ++next) { for (char* next = begin_; next + n < left_; ++next) {
if (next[n] == '\0' && stringEquals(str, adaptString(next, n))) if (next[n] == '\0' && stringEquals(str, adaptString(next, n)))
return next; return next;
@ -192,11 +192,11 @@ class MemoryPool {
char* allocString(size_t n) { char* allocString(size_t n) {
if (!canAlloc(n)) { if (!canAlloc(n)) {
_overflowed = true; overflowed_ = true;
return 0; return 0;
} }
char* s = _left; char* s = left_;
_left += n; left_ += n;
checkInvariants(); checkInvariants();
return s; return s;
} }
@ -208,15 +208,15 @@ class MemoryPool {
void* allocRight(size_t bytes) { void* allocRight(size_t bytes) {
if (!canAlloc(bytes)) { if (!canAlloc(bytes)) {
_overflowed = true; overflowed_ = true;
return 0; return 0;
} }
_right -= bytes; right_ -= bytes;
return _right; return right_;
} }
char *_begin, *_left, *_right, *_end; char *begin_, *left_, *right_, *end_;
bool _overflowed; bool overflowed_;
}; };
template <typename TAdaptedString, typename TCallback> template <typename TAdaptedString, typename TCallback>

@ -12,43 +12,43 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
template <typename T> template <typename T>
class SerializedValue { class SerializedValue {
public: public:
explicit SerializedValue(T str) : _str(str) {} explicit SerializedValue(T str) : str_(str) {}
operator T() const { operator T() const {
return _str; return str_;
} }
const char* data() const { const char* data() const {
return _str.c_str(); return str_.c_str();
} }
size_t size() const { size_t size() const {
// CAUTION: the old Arduino String doesn't have size() // CAUTION: the old Arduino String doesn't have size()
return _str.length(); return str_.length();
} }
private: private:
T _str; T str_;
}; };
template <typename TChar> template <typename TChar>
class SerializedValue<TChar*> { class SerializedValue<TChar*> {
public: public:
explicit SerializedValue(TChar* p, size_t n) : _data(p), _size(n) {} explicit SerializedValue(TChar* p, size_t n) : data_(p), size_(n) {}
operator TChar*() const { operator TChar*() const {
return _data; return data_;
} }
TChar* data() const { TChar* data() const {
return _data; return data_;
} }
size_t size() const { size_t size() const {
return _size; return size_;
} }
private: private:
TChar* _data; TChar* data_;
size_t _size; size_t size_;
}; };
template <typename T> template <typename T>

@ -18,17 +18,17 @@ class MsgPackDeserializer {
public: public:
MsgPackDeserializer(MemoryPool* pool, TReader reader, MsgPackDeserializer(MemoryPool* pool, TReader reader,
TStringStorage stringStorage) TStringStorage stringStorage)
: _pool(pool), : pool_(pool),
_reader(reader), reader_(reader),
_stringStorage(stringStorage), stringStorage_(stringStorage),
_foundSomething(false) {} foundSomething_(false) {}
template <typename TFilter> template <typename TFilter>
DeserializationError parse(VariantData& variant, TFilter filter, DeserializationError parse(VariantData& variant, TFilter filter,
DeserializationOption::NestingLimit nestingLimit) { DeserializationOption::NestingLimit nestingLimit) {
DeserializationError::Code err; DeserializationError::Code err;
err = parseVariant(&variant, filter, nestingLimit); err = parseVariant(&variant, filter, nestingLimit);
return _foundSomething ? err : DeserializationError::EmptyInput; return foundSomething_ ? err : DeserializationError::EmptyInput;
} }
private: private:
@ -43,7 +43,7 @@ class MsgPackDeserializer {
if (err) if (err)
return err; return err;
_foundSomething = true; foundSomething_ = true;
bool allowValue = filter.allowValue(); bool allowValue = filter.allowValue();
@ -224,7 +224,7 @@ class MsgPackDeserializer {
} }
DeserializationError::Code readByte(uint8_t& value) { DeserializationError::Code readByte(uint8_t& value) {
int c = _reader.read(); int c = reader_.read();
if (c < 0) if (c < 0)
return DeserializationError::IncompleteInput; return DeserializationError::IncompleteInput;
value = static_cast<uint8_t>(c); value = static_cast<uint8_t>(c);
@ -232,7 +232,7 @@ class MsgPackDeserializer {
} }
DeserializationError::Code readBytes(uint8_t* p, size_t n) { DeserializationError::Code readBytes(uint8_t* p, size_t n) {
if (_reader.readBytes(reinterpret_cast<char*>(p), n) == n) if (reader_.readBytes(reinterpret_cast<char*>(p), n) == n)
return DeserializationError::Ok; return DeserializationError::Ok;
return DeserializationError::IncompleteInput; return DeserializationError::IncompleteInput;
} }
@ -244,7 +244,7 @@ class MsgPackDeserializer {
DeserializationError::Code skipBytes(size_t n) { DeserializationError::Code skipBytes(size_t n) {
for (; n; --n) { for (; n; --n) {
if (_reader.read() < 0) if (reader_.read() < 0)
return DeserializationError::IncompleteInput; return DeserializationError::IncompleteInput;
} }
return DeserializationError::Ok; return DeserializationError::Ok;
@ -371,14 +371,14 @@ class MsgPackDeserializer {
if (err) if (err)
return err; return err;
variant->setString(_stringStorage.save()); variant->setString(stringStorage_.save());
return DeserializationError::Ok; return DeserializationError::Ok;
} }
DeserializationError::Code readString(size_t n) { DeserializationError::Code readString(size_t n) {
DeserializationError::Code err; DeserializationError::Code err;
_stringStorage.startString(); stringStorage_.startString();
for (; n; --n) { for (; n; --n) {
uint8_t c; uint8_t c;
@ -386,10 +386,10 @@ class MsgPackDeserializer {
if (err) if (err)
return err; return err;
_stringStorage.append(static_cast<char>(c)); stringStorage_.append(static_cast<char>(c));
} }
if (!_stringStorage.isValid()) if (!stringStorage_.isValid())
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
return DeserializationError::Ok; return DeserializationError::Ok;
@ -435,7 +435,7 @@ class MsgPackDeserializer {
if (memberFilter.allow()) { if (memberFilter.allow()) {
ARDUINOJSON_ASSERT(array != 0); ARDUINOJSON_ASSERT(array != 0);
value = array->addElement(_pool); value = array->addElement(pool_);
if (!value) if (!value)
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
} else { } else {
@ -486,7 +486,7 @@ class MsgPackDeserializer {
if (err) if (err)
return err; return err;
JsonString key = _stringStorage.str(); JsonString key = stringStorage_.str();
TFilter memberFilter = filter[key.c_str()]; TFilter memberFilter = filter[key.c_str()];
VariantData* member; VariantData* member;
@ -495,9 +495,9 @@ class MsgPackDeserializer {
// Save key in memory pool. // Save key in memory pool.
// This MUST be done before adding the slot. // This MUST be done before adding the slot.
key = _stringStorage.save(); key = stringStorage_.save();
VariantSlot* slot = object->addSlot(_pool); VariantSlot* slot = object->addSlot(pool_);
if (!slot) if (!slot)
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
@ -554,10 +554,10 @@ class MsgPackDeserializer {
return skipBytes(size + 1U); return skipBytes(size + 1U);
} }
MemoryPool* _pool; MemoryPool* pool_;
TReader _reader; TReader reader_;
TStringStorage _stringStorage; TStringStorage stringStorage_;
bool _foundSomething; bool foundSomething_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -19,7 +19,7 @@ class MsgPackSerializer : public Visitor<size_t> {
public: public:
static const bool producesText = false; static const bool producesText = false;
MsgPackSerializer(TWriter writer) : _writer(writer) {} MsgPackSerializer(TWriter writer) : writer_(writer) {}
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) { typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) {
@ -47,7 +47,7 @@ class MsgPackSerializer : public Visitor<size_t> {
size_t visitArray(const CollectionData& array) { size_t visitArray(const CollectionData& array) {
size_t n = array.size(); size_t n = array.size();
if (n < 0x10) { if (n < 0x10) {
writeByte(uint8_t(0x90 + array.size())); writeByte(uint8_t(0x90 + n));
} else if (n < 0x10000) { } else if (n < 0x10000) {
writeByte(0xDC); writeByte(0xDC);
writeInteger(uint16_t(n)); writeInteger(uint16_t(n));
@ -177,15 +177,15 @@ class MsgPackSerializer : public Visitor<size_t> {
private: private:
size_t bytesWritten() const { size_t bytesWritten() const {
return _writer.count(); return writer_.count();
} }
void writeByte(uint8_t c) { void writeByte(uint8_t c) {
_writer.write(c); writer_.write(c);
} }
void writeBytes(const uint8_t* p, size_t n) { void writeBytes(const uint8_t* p, size_t n) {
_writer.write(p, n); writer_.write(p, n);
} }
template <typename T> template <typename T>
@ -194,7 +194,7 @@ class MsgPackSerializer : public Visitor<size_t> {
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value)); writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
} }
CountingDecorator<TWriter> _writer; CountingDecorator<TWriter> writer_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -11,16 +11,15 @@
#ifndef ARDUINOJSON_VERSION_NAMESPACE #ifndef ARDUINOJSON_VERSION_NAMESPACE
# define ARDUINOJSON_VERSION_NAMESPACE \ # define ARDUINOJSON_VERSION_NAMESPACE \
ARDUINOJSON_CONCAT3( \ ARDUINOJSON_CONCAT4( \
ARDUINOJSON_CONCAT4(V, ARDUINOJSON_VERSION_MAJOR, \ ARDUINOJSON_VERSION_MACRO, \
ARDUINOJSON_VERSION_MINOR, \
ARDUINOJSON_VERSION_REVISION), \
ARDUINOJSON_BIN2ALPHA( \ ARDUINOJSON_BIN2ALPHA( \
ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_USE_LONG_LONG, \ ARDUINOJSON_ENABLE_PROGMEM, ARDUINOJSON_USE_LONG_LONG, \
ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \ ARDUINOJSON_USE_DOUBLE, ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \
ARDUINOJSON_BIN2ALPHA( \ ARDUINOJSON_BIN2ALPHA( \
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \ ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE)) ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE), \
ARDUINOJSON_SLOT_OFFSET_SIZE)
#endif #endif

@ -146,7 +146,6 @@ inline bool parseNumber(const char* s, VariantData& result) {
template <typename T> template <typename T>
inline T parseNumber(const char* s) { inline T parseNumber(const char* s) {
VariantData value; VariantData value;
value.init(); // VariantData is a POD, so it has no constructor
parseNumber(s, value); parseNumber(s, value);
return Converter<T>::fromJson(JsonVariantConst(&value)); return Converter<T>::fromJson(JsonVariantConst(&value));
} }

@ -20,61 +20,61 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
typedef JsonObjectIterator iterator; typedef JsonObjectIterator iterator;
// Creates an unbound reference. // Creates an unbound reference.
FORCE_INLINE JsonObject() : _data(0), _pool(0) {} FORCE_INLINE JsonObject() : data_(0), pool_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
FORCE_INLINE JsonObject(detail::MemoryPool* buf, detail::CollectionData* data) FORCE_INLINE JsonObject(detail::MemoryPool* buf, detail::CollectionData* data)
: _data(data), _pool(buf) {} : data_(data), pool_(buf) {}
operator JsonVariant() const { operator JsonVariant() const {
void* data = _data; // prevent warning cast-align void* data = data_; // prevent warning cast-align
return JsonVariant(_pool, reinterpret_cast<detail::VariantData*>(data)); return JsonVariant(pool_, reinterpret_cast<detail::VariantData*>(data));
} }
operator JsonObjectConst() const { operator JsonObjectConst() const {
return JsonObjectConst(_data); return JsonObjectConst(data_);
} }
operator JsonVariantConst() const { operator JsonVariantConst() const {
return JsonVariantConst(collectionToVariant(_data)); return JsonVariantConst(collectionToVariant(data_));
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v6/api/jsonobject/isnull/ // https://arduinojson.org/v6/api/jsonobject/isnull/
FORCE_INLINE bool isNull() const { FORCE_INLINE bool isNull() const {
return _data == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v6/api/jsonobject/isnull/ // https://arduinojson.org/v6/api/jsonobject/isnull/
FORCE_INLINE operator bool() const { FORCE_INLINE operator bool() const {
return _data != 0; return data_ != 0;
} }
// Returns the number of bytes occupied by the object. // Returns the number of bytes occupied by the object.
// https://arduinojson.org/v6/api/jsonobject/memoryusage/ // https://arduinojson.org/v6/api/jsonobject/memoryusage/
FORCE_INLINE size_t memoryUsage() const { FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0; return data_ ? data_->memoryUsage() : 0;
} }
// Returns the depth (nesting level) of the object. // Returns the depth (nesting level) of the object.
// https://arduinojson.org/v6/api/jsonobject/nesting/ // https://arduinojson.org/v6/api/jsonobject/nesting/
FORCE_INLINE size_t nesting() const { FORCE_INLINE size_t nesting() const {
return variantNesting(collectionToVariant(_data)); return variantNesting(collectionToVariant(data_));
} }
// Returns the number of members in the object. // Returns the number of members in the object.
// https://arduinojson.org/v6/api/jsonobject/size/ // https://arduinojson.org/v6/api/jsonobject/size/
FORCE_INLINE size_t size() const { FORCE_INLINE size_t size() const {
return _data ? _data->size() : 0; return data_ ? data_->size() : 0;
} }
// Returns an iterator to the first key-value pair of the object. // Returns an iterator to the first key-value pair of the object.
// https://arduinojson.org/v6/api/jsonobject/begin/ // https://arduinojson.org/v6/api/jsonobject/begin/
FORCE_INLINE iterator begin() const { FORCE_INLINE iterator begin() const {
if (!_data) if (!data_)
return iterator(); return iterator();
return iterator(_pool, _data->head()); return iterator(pool_, data_->head());
} }
// Returns an iterator following the last key-value pair of the object. // Returns an iterator following the last key-value pair of the object.
@ -87,22 +87,22 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// ⚠ Doesn't release the memory associated with the removed members. // ⚠ Doesn't release the memory associated with the removed members.
// https://arduinojson.org/v6/api/jsonobject/clear/ // https://arduinojson.org/v6/api/jsonobject/clear/
void clear() const { void clear() const {
if (!_data) if (!data_)
return; return;
_data->clear(); data_->clear();
} }
// Copies an object. // Copies an object.
// https://arduinojson.org/v6/api/jsonobject/set/ // https://arduinojson.org/v6/api/jsonobject/set/
FORCE_INLINE bool set(JsonObjectConst src) { FORCE_INLINE bool set(JsonObjectConst src) {
if (!_data || !src._data) if (!data_ || !src.data_)
return false; return false;
return _data->copyFrom(*src._data, _pool); return data_->copyFrom(*src.data_, pool_);
} }
// Compares the content of two objects. // Compares the content of two objects.
FORCE_INLINE bool operator==(JsonObject rhs) const { FORCE_INLINE bool operator==(JsonObject rhs) const {
return JsonObjectConst(_data) == JsonObjectConst(rhs._data); return JsonObjectConst(data_) == JsonObjectConst(rhs.data_);
} }
// Gets or sets the member with specified key. // Gets or sets the member with specified key.
@ -129,9 +129,9 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// ⚠ Doesn't release the memory associated with the removed member. // ⚠ Doesn't release the memory associated with the removed member.
// https://arduinojson.org/v6/api/jsonobject/remove/ // https://arduinojson.org/v6/api/jsonobject/remove/
FORCE_INLINE void remove(iterator it) const { FORCE_INLINE void remove(iterator it) const {
if (!_data) if (!data_)
return; return;
_data->removeSlot(it._slot); data_->removeSlot(it.slot_);
} }
// Removes the member with the specified key. // Removes the member with the specified key.
@ -194,33 +194,33 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
private: private:
detail::MemoryPool* getPool() const { detail::MemoryPool* getPool() const {
return _pool; return pool_;
} }
detail::VariantData* getData() const { detail::VariantData* getData() const {
return detail::collectionToVariant(_data); return detail::collectionToVariant(data_);
} }
detail::VariantData* getOrCreateData() const { detail::VariantData* getOrCreateData() const {
return detail::collectionToVariant(_data); return detail::collectionToVariant(data_);
} }
template <typename TAdaptedString> template <typename TAdaptedString>
inline detail::VariantData* getMember(TAdaptedString key) const { inline detail::VariantData* getMember(TAdaptedString key) const {
if (!_data) if (!data_)
return 0; return 0;
return _data->getMember(key); return data_->getMember(key);
} }
template <typename TAdaptedString> template <typename TAdaptedString>
void removeMember(TAdaptedString key) const { void removeMember(TAdaptedString key) const {
if (!_data) if (!data_)
return; return;
_data->removeMember(key); data_->removeMember(key);
} }
detail::CollectionData* _data; detail::CollectionData* data_;
detail::MemoryPool* _pool; detail::MemoryPool* pool_;
}; };
template <> template <>

@ -19,51 +19,51 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
typedef JsonObjectConstIterator iterator; typedef JsonObjectConstIterator iterator;
// Creates an unbound reference. // Creates an unbound reference.
JsonObjectConst() : _data(0) {} JsonObjectConst() : data_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonObjectConst(const detail::CollectionData* data) : _data(data) {} JsonObjectConst(const detail::CollectionData* data) : data_(data) {}
operator JsonVariantConst() const { operator JsonVariantConst() const {
return JsonVariantConst(collectionToVariant(_data)); return JsonVariantConst(collectionToVariant(data_));
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
// https://arduinojson.org/v6/api/jsonobjectconst/isnull/ // https://arduinojson.org/v6/api/jsonobjectconst/isnull/
FORCE_INLINE bool isNull() const { FORCE_INLINE bool isNull() const {
return _data == 0; return data_ == 0;
} }
// Returns true if the reference is bound. // Returns true if the reference is bound.
// https://arduinojson.org/v6/api/jsonobjectconst/isnull/ // https://arduinojson.org/v6/api/jsonobjectconst/isnull/
FORCE_INLINE operator bool() const { FORCE_INLINE operator bool() const {
return _data != 0; return data_ != 0;
} }
// Returns the number of bytes occupied by the object. // Returns the number of bytes occupied by the object.
// https://arduinojson.org/v6/api/jsonobjectconst/memoryusage/ // https://arduinojson.org/v6/api/jsonobjectconst/memoryusage/
FORCE_INLINE size_t memoryUsage() const { FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0; return data_ ? data_->memoryUsage() : 0;
} }
// Returns the depth (nesting level) of the object. // Returns the depth (nesting level) of the object.
// https://arduinojson.org/v6/api/jsonobjectconst/nesting/ // https://arduinojson.org/v6/api/jsonobjectconst/nesting/
FORCE_INLINE size_t nesting() const { FORCE_INLINE size_t nesting() const {
return variantNesting(collectionToVariant(_data)); return variantNesting(collectionToVariant(data_));
} }
// Returns the number of members in the object. // Returns the number of members in the object.
// https://arduinojson.org/v6/api/jsonobjectconst/size/ // https://arduinojson.org/v6/api/jsonobjectconst/size/
FORCE_INLINE size_t size() const { FORCE_INLINE size_t size() const {
return _data ? _data->size() : 0; return data_ ? data_->size() : 0;
} }
// Returns an iterator to the first key-value pair of the object. // Returns an iterator to the first key-value pair of the object.
// https://arduinojson.org/v6/api/jsonobjectconst/begin/ // https://arduinojson.org/v6/api/jsonobjectconst/begin/
FORCE_INLINE iterator begin() const { FORCE_INLINE iterator begin() const {
if (!_data) if (!data_)
return iterator(); return iterator();
return iterator(_data->head()); return iterator(data_->head());
} }
// Returns an iterator following the last key-value pair of the object. // Returns an iterator following the last key-value pair of the object.
@ -106,10 +106,10 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Compares objects. // Compares objects.
FORCE_INLINE bool operator==(JsonObjectConst rhs) const { FORCE_INLINE bool operator==(JsonObjectConst rhs) const {
if (_data == rhs._data) if (data_ == rhs.data_)
return true; return true;
if (!_data || !rhs._data) if (!data_ || !rhs.data_)
return false; return false;
size_t count = 0; size_t count = 0;
@ -123,17 +123,17 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
private: private:
const detail::VariantData* getData() const { const detail::VariantData* getData() const {
return collectionToVariant(_data); return collectionToVariant(data_);
} }
template <typename TAdaptedString> template <typename TAdaptedString>
const detail::VariantData* getMember(TAdaptedString key) const { const detail::VariantData* getMember(TAdaptedString key) const {
if (!_data) if (!data_)
return 0; return 0;
return _data->getMember(key); return data_->getMember(key);
} }
const detail::CollectionData* _data; const detail::CollectionData* data_;
}; };
template <> template <>

@ -12,112 +12,112 @@ ARDUINOJSON_BEGIN_PUBLIC_NAMESPACE
class JsonPairPtr { class JsonPairPtr {
public: public:
JsonPairPtr(detail::MemoryPool* pool, detail::VariantSlot* slot) JsonPairPtr(detail::MemoryPool* pool, detail::VariantSlot* slot)
: _pair(pool, slot) {} : pair_(pool, slot) {}
const JsonPair* operator->() const { const JsonPair* operator->() const {
return &_pair; return &pair_;
} }
const JsonPair& operator*() const { const JsonPair& operator*() const {
return _pair; return pair_;
} }
private: private:
JsonPair _pair; JsonPair pair_;
}; };
class JsonObjectIterator { class JsonObjectIterator {
friend class JsonObject; friend class JsonObject;
public: public:
JsonObjectIterator() : _slot(0) {} JsonObjectIterator() : slot_(0) {}
explicit JsonObjectIterator(detail::MemoryPool* pool, explicit JsonObjectIterator(detail::MemoryPool* pool,
detail::VariantSlot* slot) detail::VariantSlot* slot)
: _pool(pool), _slot(slot) {} : pool_(pool), slot_(slot) {}
JsonPair operator*() const { JsonPair operator*() const {
return JsonPair(_pool, _slot); return JsonPair(pool_, slot_);
} }
JsonPairPtr operator->() { JsonPairPtr operator->() {
return JsonPairPtr(_pool, _slot); return JsonPairPtr(pool_, slot_);
} }
bool operator==(const JsonObjectIterator& other) const { bool operator==(const JsonObjectIterator& other) const {
return _slot == other._slot; return slot_ == other.slot_;
} }
bool operator!=(const JsonObjectIterator& other) const { bool operator!=(const JsonObjectIterator& other) const {
return _slot != other._slot; return slot_ != other.slot_;
} }
JsonObjectIterator& operator++() { JsonObjectIterator& operator++() {
_slot = _slot->next(); slot_ = slot_->next();
return *this; return *this;
} }
JsonObjectIterator& operator+=(size_t distance) { JsonObjectIterator& operator+=(size_t distance) {
_slot = _slot->next(distance); slot_ = slot_->next(distance);
return *this; return *this;
} }
private: private:
detail::MemoryPool* _pool; detail::MemoryPool* pool_;
detail::VariantSlot* _slot; detail::VariantSlot* slot_;
}; };
class JsonPairConstPtr { class JsonPairConstPtr {
public: public:
JsonPairConstPtr(const detail::VariantSlot* slot) : _pair(slot) {} JsonPairConstPtr(const detail::VariantSlot* slot) : pair_(slot) {}
const JsonPairConst* operator->() const { const JsonPairConst* operator->() const {
return &_pair; return &pair_;
} }
const JsonPairConst& operator*() const { const JsonPairConst& operator*() const {
return _pair; return pair_;
} }
private: private:
JsonPairConst _pair; JsonPairConst pair_;
}; };
class JsonObjectConstIterator { class JsonObjectConstIterator {
friend class JsonObject; friend class JsonObject;
public: public:
JsonObjectConstIterator() : _slot(0) {} JsonObjectConstIterator() : slot_(0) {}
explicit JsonObjectConstIterator(const detail::VariantSlot* slot) explicit JsonObjectConstIterator(const detail::VariantSlot* slot)
: _slot(slot) {} : slot_(slot) {}
JsonPairConst operator*() const { JsonPairConst operator*() const {
return JsonPairConst(_slot); return JsonPairConst(slot_);
} }
JsonPairConstPtr operator->() { JsonPairConstPtr operator->() {
return JsonPairConstPtr(_slot); return JsonPairConstPtr(slot_);
} }
bool operator==(const JsonObjectConstIterator& other) const { bool operator==(const JsonObjectConstIterator& other) const {
return _slot == other._slot; return slot_ == other.slot_;
} }
bool operator!=(const JsonObjectConstIterator& other) const { bool operator!=(const JsonObjectConstIterator& other) const {
return _slot != other._slot; return slot_ != other.slot_;
} }
JsonObjectConstIterator& operator++() { JsonObjectConstIterator& operator++() {
_slot = _slot->next(); slot_ = slot_->next();
return *this; return *this;
} }
JsonObjectConstIterator& operator+=(size_t distance) { JsonObjectConstIterator& operator+=(size_t distance) {
_slot = _slot->next(distance); slot_ = slot_->next(distance);
return *this; return *this;
} }
private: private:
const detail::VariantSlot* _slot; const detail::VariantSlot* slot_;
}; };
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

@ -17,25 +17,25 @@ class JsonPair {
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonPair(detail::MemoryPool* pool, detail::VariantSlot* slot) { JsonPair(detail::MemoryPool* pool, detail::VariantSlot* slot) {
if (slot) { if (slot) {
_key = JsonString(slot->key(), slot->ownsKey() ? JsonString::Copied key_ = JsonString(slot->key(), slot->ownsKey() ? JsonString::Copied
: JsonString::Linked); : JsonString::Linked);
_value = JsonVariant(pool, slot->data()); value_ = JsonVariant(pool, slot->data());
} }
} }
// Returns the key. // Returns the key.
JsonString key() const { JsonString key() const {
return _key; return key_;
} }
// Returns the value. // Returns the value.
JsonVariant value() const { JsonVariant value() const {
return _value; return value_;
} }
private: private:
JsonString _key; JsonString key_;
JsonVariant _value; JsonVariant value_;
}; };
// A read-only key-value pair. // A read-only key-value pair.
@ -44,25 +44,25 @@ class JsonPairConst {
public: public:
JsonPairConst(const detail::VariantSlot* slot) { JsonPairConst(const detail::VariantSlot* slot) {
if (slot) { if (slot) {
_key = JsonString(slot->key(), slot->ownsKey() ? JsonString::Copied key_ = JsonString(slot->key(), slot->ownsKey() ? JsonString::Copied
: JsonString::Linked); : JsonString::Linked);
_value = JsonVariantConst(slot->data()); value_ = JsonVariantConst(slot->data());
} }
} }
// Returns the key. // Returns the key.
JsonString key() const { JsonString key() const {
return _key; return key_;
} }
// Returns the value. // Returns the value.
JsonVariantConst value() const { JsonVariantConst value() const {
return _value; return value_;
} }
private: private:
JsonString _key; JsonString key_;
JsonVariantConst _value; JsonVariantConst value_;
}; };
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

@ -18,10 +18,10 @@ class MemberProxy
public: public:
FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef key) FORCE_INLINE MemberProxy(TUpstream upstream, TStringRef key)
: _upstream(upstream), _key(key) {} : upstream_(upstream), key_(key) {}
MemberProxy(const MemberProxy& src) MemberProxy(const MemberProxy& src)
: _upstream(src._upstream), _key(src._key) {} : upstream_(src.upstream_), key_(src.key_) {}
FORCE_INLINE MemberProxy& operator=(const MemberProxy& src) { FORCE_INLINE MemberProxy& operator=(const MemberProxy& src) {
this->set(src); this->set(src);
@ -42,23 +42,23 @@ class MemberProxy
private: private:
FORCE_INLINE MemoryPool* getPool() const { FORCE_INLINE MemoryPool* getPool() const {
return VariantAttorney::getPool(_upstream); return VariantAttorney::getPool(upstream_);
} }
FORCE_INLINE VariantData* getData() const { FORCE_INLINE VariantData* getData() const {
return variantGetMember(VariantAttorney::getData(_upstream), return variantGetMember(VariantAttorney::getData(upstream_),
adaptString(_key)); adaptString(key_));
} }
FORCE_INLINE VariantData* getOrCreateData() const { FORCE_INLINE VariantData* getOrCreateData() const {
return variantGetOrAddMember(VariantAttorney::getOrCreateData(_upstream), return variantGetOrAddMember(VariantAttorney::getOrCreateData(upstream_),
adaptString(_key), adaptString(key_),
VariantAttorney::getPool(_upstream)); VariantAttorney::getPool(upstream_));
} }
private: private:
TUpstream _upstream; TUpstream upstream_;
TStringRef _key; TStringRef key_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -4,7 +4,13 @@
#pragma once #pragma once
#include <Arduino.h> #ifdef ARDUINO
# include <Arduino.h>
#else
// Allow using PROGMEM outside of Arduino (issue #1903)
class __FlashStringHelper;
# include <avr/pgmspace.h>
#endif
#include <ArduinoJson/Configuration.hpp> #include <ArduinoJson/Configuration.hpp>
#include <ArduinoJson/Namespace.hpp> #include <ArduinoJson/Namespace.hpp>

@ -54,14 +54,14 @@ inline T pgm_read(const T* p) {
template <typename T> template <typename T>
class pgm_ptr { class pgm_ptr {
public: public:
explicit pgm_ptr(const T* ptr) : _ptr(ptr) {} explicit pgm_ptr(const T* ptr) : ptr_(ptr) {}
T operator[](intptr_t index) const { T operator[](intptr_t index) const {
return pgm_read(_ptr + index); return pgm_read(ptr_ + index);
} }
private: private:
const T* _ptr; const T* ptr_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -6,8 +6,6 @@
#define ARDUINOJSON_CONCAT_(A, B) A##B #define ARDUINOJSON_CONCAT_(A, B) A##B
#define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_CONCAT_(A, B) #define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_CONCAT_(A, B)
#define ARDUINOJSON_CONCAT3(A, B, C) \
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), C)
#define ARDUINOJSON_CONCAT4(A, B, C, D) \ #define ARDUINOJSON_CONCAT4(A, B, C, D) \
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), ARDUINOJSON_CONCAT2(C, D)) ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), ARDUINOJSON_CONCAT2(C, D))
@ -17,7 +15,7 @@
#define ARDUINOJSON_BIN2ALPHA_0011() D #define ARDUINOJSON_BIN2ALPHA_0011() D
#define ARDUINOJSON_BIN2ALPHA_0100() E #define ARDUINOJSON_BIN2ALPHA_0100() E
#define ARDUINOJSON_BIN2ALPHA_0101() F #define ARDUINOJSON_BIN2ALPHA_0101() F
#define ARDUINOJSON_BIN2ALPHA_0110() F #define ARDUINOJSON_BIN2ALPHA_0110() G
#define ARDUINOJSON_BIN2ALPHA_0111() H #define ARDUINOJSON_BIN2ALPHA_0111() H
#define ARDUINOJSON_BIN2ALPHA_1000() I #define ARDUINOJSON_BIN2ALPHA_1000() I
#define ARDUINOJSON_BIN2ALPHA_1001() J #define ARDUINOJSON_BIN2ALPHA_1001() J

@ -27,10 +27,10 @@ struct is_convertible {
static int probe(To); static int probe(To);
static char probe(...); static char probe(...);
static From& _from; static From& from_;
public: public:
static const bool value = sizeof(probe(_from)) == sizeof(int); static const bool value = sizeof(probe(from_)) == sizeof(int);
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -11,23 +11,23 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TWriter> template <typename TWriter>
class CountingDecorator { class CountingDecorator {
public: public:
explicit CountingDecorator(TWriter& writer) : _writer(writer), _count(0) {} explicit CountingDecorator(TWriter& writer) : writer_(writer), count_(0) {}
void write(uint8_t c) { void write(uint8_t c) {
_count += _writer.write(c); count_ += writer_.write(c);
} }
void write(const uint8_t* s, size_t n) { void write(const uint8_t* s, size_t n) {
_count += _writer.write(s, n); count_ += writer_.write(s, n);
} }
size_t count() const { size_t count() const {
return _count; return count_;
} }
private: private:
TWriter _writer; TWriter writer_;
size_t _count; size_t count_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -12,18 +12,18 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TDestination, typename Enable = void> template <typename TDestination, typename Enable = void>
class Writer { class Writer {
public: public:
explicit Writer(TDestination& dest) : _dest(&dest) {} explicit Writer(TDestination& dest) : dest_(&dest) {}
size_t write(uint8_t c) { size_t write(uint8_t c) {
return _dest->write(c); return dest_->write(c);
} }
size_t write(const uint8_t* s, size_t n) { size_t write(const uint8_t* s, size_t n) {
return _dest->write(s, n); return dest_->write(s, n);
} }
private: private:
TDestination* _dest; TDestination* dest_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -13,8 +13,8 @@ class Writer<::String, void> {
static const size_t bufferCapacity = ARDUINOJSON_STRING_BUFFER_SIZE; static const size_t bufferCapacity = ARDUINOJSON_STRING_BUFFER_SIZE;
public: public:
explicit Writer(::String& str) : _destination(&str) { explicit Writer(::String& str) : destination_(&str) {
_size = 0; size_ = 0;
} }
~Writer() { ~Writer() {
@ -22,10 +22,10 @@ class Writer<::String, void> {
} }
size_t write(uint8_t c) { size_t write(uint8_t c) {
if (_size + 1 >= bufferCapacity) if (size_ + 1 >= bufferCapacity)
if (flush() != 0) if (flush() != 0)
return 0; return 0;
_buffer[_size++] = static_cast<char>(c); buffer_[size_++] = static_cast<char>(c);
return 1; return 1;
} }
@ -37,17 +37,17 @@ class Writer<::String, void> {
} }
size_t flush() { size_t flush() {
ARDUINOJSON_ASSERT(_size < bufferCapacity); ARDUINOJSON_ASSERT(size_ < bufferCapacity);
_buffer[_size] = 0; buffer_[size_] = 0;
if (_destination->concat(_buffer)) if (destination_->concat(buffer_))
_size = 0; size_ = 0;
return _size; return size_;
} }
private: private:
::String* _destination; ::String* destination_;
char _buffer[bufferCapacity]; char buffer_[bufferCapacity];
size_t _size; size_t size_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -13,18 +13,18 @@ class Writer<
TDestination, TDestination,
typename enable_if<is_base_of<::Print, TDestination>::value>::type> { typename enable_if<is_base_of<::Print, TDestination>::value>::type> {
public: public:
explicit Writer(::Print& print) : _print(&print) {} explicit Writer(::Print& print) : print_(&print) {}
size_t write(uint8_t c) { size_t write(uint8_t c) {
return _print->write(c); return print_->write(c);
} }
size_t write(const uint8_t* s, size_t n) { size_t write(const uint8_t* s, size_t n) {
return _print->write(s, n); return print_->write(s, n);
} }
private: private:
::Print* _print; ::Print* print_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -13,21 +13,21 @@ class Writer<
TDestination, TDestination,
typename enable_if<is_base_of<std::ostream, TDestination>::value>::type> { typename enable_if<is_base_of<std::ostream, TDestination>::value>::type> {
public: public:
explicit Writer(std::ostream& os) : _os(&os) {} explicit Writer(std::ostream& os) : os_(&os) {}
size_t write(uint8_t c) { size_t write(uint8_t c) {
_os->put(static_cast<char>(c)); os_->put(static_cast<char>(c));
return 1; return 1;
} }
size_t write(const uint8_t* s, size_t n) { size_t write(const uint8_t* s, size_t n) {
_os->write(reinterpret_cast<const char*>(s), os_->write(reinterpret_cast<const char*>(s),
static_cast<std::streamsize>(n)); static_cast<std::streamsize>(n));
return n; return n;
} }
private: private:
std::ostream* _os; std::ostream* os_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -24,20 +24,20 @@ template <typename TDestination>
class Writer<TDestination, class Writer<TDestination,
typename enable_if<is_std_string<TDestination>::value>::type> { typename enable_if<is_std_string<TDestination>::value>::type> {
public: public:
Writer(TDestination& str) : _str(&str) {} Writer(TDestination& str) : str_(&str) {}
size_t write(uint8_t c) { size_t write(uint8_t c) {
_str->push_back(static_cast<char>(c)); str_->push_back(static_cast<char>(c));
return 1; return 1;
} }
size_t write(const uint8_t* s, size_t n) { size_t write(const uint8_t* s, size_t n) {
_str->append(reinterpret_cast<const char*>(s), n); str_->append(reinterpret_cast<const char*>(s), n);
return n; return n;
} }
private: private:
TDestination* _str; TDestination* str_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -10,19 +10,19 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class StringCopier { class StringCopier {
public: public:
StringCopier(MemoryPool* pool) : _pool(pool) {} StringCopier(MemoryPool* pool) : pool_(pool) {}
void startString() { void startString() {
_pool->getFreeZone(&_ptr, &_capacity); pool_->getFreeZone(&ptr_, &capacity_);
_size = 0; size_ = 0;
if (_capacity == 0) if (capacity_ == 0)
_pool->markAsOverflowed(); pool_->markAsOverflowed();
} }
JsonString save() { JsonString save() {
ARDUINOJSON_ASSERT(_ptr); ARDUINOJSON_ASSERT(ptr_);
ARDUINOJSON_ASSERT(_size < _capacity); // needs room for the terminator ARDUINOJSON_ASSERT(size_ < capacity_); // needs room for the terminator
return JsonString(_pool->saveStringFromFreeZone(_size), _size, return JsonString(pool_->saveStringFromFreeZone(size_), size_,
JsonString::Copied); JsonString::Copied);
} }
@ -37,36 +37,36 @@ class StringCopier {
} }
void append(char c) { void append(char c) {
if (_size + 1 < _capacity) if (size_ + 1 < capacity_)
_ptr[_size++] = c; ptr_[size_++] = c;
else else
_pool->markAsOverflowed(); pool_->markAsOverflowed();
} }
bool isValid() const { bool isValid() const {
return !_pool->overflowed(); return !pool_->overflowed();
} }
size_t size() const { size_t size() const {
return _size; return size_;
} }
JsonString str() const { JsonString str() const {
ARDUINOJSON_ASSERT(_ptr); ARDUINOJSON_ASSERT(ptr_);
ARDUINOJSON_ASSERT(_size < _capacity); ARDUINOJSON_ASSERT(size_ < capacity_);
_ptr[_size] = 0; ptr_[size_] = 0;
return JsonString(_ptr, _size, JsonString::Copied); return JsonString(ptr_, size_, JsonString::Copied);
} }
private: private:
MemoryPool* _pool; MemoryPool* pool_;
// These fields aren't initialized by the constructor but startString() // These fields aren't initialized by the constructor but startString()
// //
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject) // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
char* _ptr; char* ptr_;
// NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject) // NOLINTNEXTLINE(clang-analyzer-optin.cplusplus.UninitializedObject)
size_t _size, _capacity; size_t size_, capacity_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -11,20 +11,20 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class StringMover { class StringMover {
public: public:
StringMover(char* ptr) : _writePtr(ptr) {} StringMover(char* ptr) : writePtr_(ptr) {}
void startString() { void startString() {
_startPtr = _writePtr; startPtr_ = writePtr_;
} }
FORCE_INLINE JsonString save() { FORCE_INLINE JsonString save() {
JsonString s = str(); JsonString s = str();
_writePtr++; writePtr_++;
return s; return s;
} }
void append(char c) { void append(char c) {
*_writePtr++ = c; *writePtr_++ = c;
} }
bool isValid() const { bool isValid() const {
@ -32,17 +32,17 @@ class StringMover {
} }
JsonString str() const { JsonString str() const {
_writePtr[0] = 0; // terminator writePtr_[0] = 0; // terminator
return JsonString(_startPtr, size(), JsonString::Linked); return JsonString(startPtr_, size(), JsonString::Linked);
} }
size_t size() const { size_t size() const {
return size_t(_writePtr - _startPtr); return size_t(writePtr_ - startPtr_);
} }
private: private:
char* _writePtr; char* writePtr_;
char* _startPtr; char* startPtr_;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

@ -4,8 +4,6 @@
#pragma once #pragma once
#include <Arduino.h>
#include <ArduinoJson/Polyfills/pgmspace.hpp> #include <ArduinoJson/Polyfills/pgmspace.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp> #include <ArduinoJson/Strings/StringAdapter.hpp>
@ -16,20 +14,20 @@ class FlashString {
static const size_t typeSortKey = 1; static const size_t typeSortKey = 1;
FlashString(const __FlashStringHelper* str, size_t sz) FlashString(const __FlashStringHelper* str, size_t sz)
: _str(reinterpret_cast<const char*>(str)), _size(sz) {} : str_(reinterpret_cast<const char*>(str)), size_(sz) {}
bool isNull() const { bool isNull() const {
return !_str; return !str_;
} }
char operator[](size_t i) const { char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0); ARDUINOJSON_ASSERT(str_ != 0);
ARDUINOJSON_ASSERT(i <= _size); ARDUINOJSON_ASSERT(i <= size_);
return static_cast<char>(pgm_read_byte(_str + i)); return static_cast<char>(pgm_read_byte(str_ + i));
} }
size_t size() const { size_t size() const {
return _size; return size_;
} }
friend bool stringEquals(FlashString a, SizedRamString b) { friend bool stringEquals(FlashString a, SizedRamString b) {
@ -38,7 +36,7 @@ class FlashString {
ARDUINOJSON_ASSERT(!b.isNull()); ARDUINOJSON_ASSERT(!b.isNull());
if (a.size() != b.size()) if (a.size() != b.size())
return false; return false;
return ::memcmp_P(b.data(), a._str, a._size) == 0; return ::memcmp_P(b.data(), a.str_, a.size_) == 0;
} }
friend int stringCompare(FlashString a, SizedRamString b) { friend int stringCompare(FlashString a, SizedRamString b) {
@ -46,7 +44,7 @@ class FlashString {
ARDUINOJSON_ASSERT(!a.isNull()); ARDUINOJSON_ASSERT(!a.isNull());
ARDUINOJSON_ASSERT(!b.isNull()); ARDUINOJSON_ASSERT(!b.isNull());
size_t minsize = a.size() < b.size() ? a.size() : b.size(); size_t minsize = a.size() < b.size() ? a.size() : b.size();
int res = ::memcmp_P(b.data(), a._str, minsize); int res = ::memcmp_P(b.data(), a.str_, minsize);
if (res) if (res)
return -res; return -res;
if (a.size() < b.size()) if (a.size() < b.size())
@ -58,7 +56,7 @@ class FlashString {
friend void stringGetChars(FlashString s, char* p, size_t n) { friend void stringGetChars(FlashString s, char* p, size_t n) {
ARDUINOJSON_ASSERT(s.size() <= n); ARDUINOJSON_ASSERT(s.size() <= n);
::memcpy_P(p, s._str, n); ::memcpy_P(p, s.str_, n);
} }
StringStoragePolicy::Copy storagePolicy() const { StringStoragePolicy::Copy storagePolicy() const {
@ -66,8 +64,8 @@ class FlashString {
} }
private: private:
const char* _str; const char* str_;
size_t _size; size_t size_;
}; };
template <> template <>

@ -13,15 +13,15 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class JsonStringAdapter : public SizedRamString { class JsonStringAdapter : public SizedRamString {
public: public:
JsonStringAdapter(const JsonString& s) JsonStringAdapter(const JsonString& s)
: SizedRamString(s.c_str(), s.size()), _linked(s.isLinked()) {} : SizedRamString(s.c_str(), s.size()), linked_(s.isLinked()) {}
StringStoragePolicy::LinkOrCopy storagePolicy() const { StringStoragePolicy::LinkOrCopy storagePolicy() const {
StringStoragePolicy::LinkOrCopy policy = {_linked}; StringStoragePolicy::LinkOrCopy policy = {linked_};
return policy; return policy;
} }
private: private:
bool _linked; bool linked_;
}; };
template <> template <>

@ -21,31 +21,31 @@ class ZeroTerminatedRamString {
public: public:
static const size_t typeSortKey = 3; static const size_t typeSortKey = 3;
ZeroTerminatedRamString(const char* str) : _str(str) {} ZeroTerminatedRamString(const char* str) : str_(str) {}
bool isNull() const { bool isNull() const {
return !_str; return !str_;
} }
size_t size() const { size_t size() const {
return _str ? ::strlen(_str) : 0; return str_ ? ::strlen(str_) : 0;
} }
char operator[](size_t i) const { char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0); ARDUINOJSON_ASSERT(str_ != 0);
ARDUINOJSON_ASSERT(i <= size()); ARDUINOJSON_ASSERT(i <= size());
return _str[i]; return str_[i];
} }
const char* data() const { const char* data() const {
return _str; return str_;
} }
friend int stringCompare(ZeroTerminatedRamString a, friend int stringCompare(ZeroTerminatedRamString a,
ZeroTerminatedRamString b) { ZeroTerminatedRamString b) {
ARDUINOJSON_ASSERT(!a.isNull()); ARDUINOJSON_ASSERT(!a.isNull());
ARDUINOJSON_ASSERT(!b.isNull()); ARDUINOJSON_ASSERT(!b.isNull());
return ::strcmp(a._str, b._str); return ::strcmp(a.str_, b.str_);
} }
friend bool stringEquals(ZeroTerminatedRamString a, friend bool stringEquals(ZeroTerminatedRamString a,
@ -58,7 +58,7 @@ class ZeroTerminatedRamString {
} }
protected: protected:
const char* _str; const char* str_;
}; };
template <typename TChar> template <typename TChar>
@ -101,24 +101,24 @@ class SizedRamString {
public: public:
static const size_t typeSortKey = 2; static const size_t typeSortKey = 2;
SizedRamString(const char* str, size_t sz) : _str(str), _size(sz) {} SizedRamString(const char* str, size_t sz) : str_(str), size_(sz) {}
bool isNull() const { bool isNull() const {
return !_str; return !str_;
} }
size_t size() const { size_t size() const {
return _size; return size_;
} }
char operator[](size_t i) const { char operator[](size_t i) const {
ARDUINOJSON_ASSERT(_str != 0); ARDUINOJSON_ASSERT(str_ != 0);
ARDUINOJSON_ASSERT(i <= size()); ARDUINOJSON_ASSERT(i <= size());
return _str[i]; return str_[i];
} }
const char* data() const { const char* data() const {
return _str; return str_;
} }
StringStoragePolicy::Copy storagePolicy() const { StringStoragePolicy::Copy storagePolicy() const {
@ -126,8 +126,8 @@ class SizedRamString {
} }
protected: protected:
const char* _str; const char* str_;
size_t _size; size_t size_;
}; };
template <typename TChar> template <typename TChar>

@ -16,51 +16,51 @@ class JsonString {
public: public:
enum Ownership { Copied, Linked }; enum Ownership { Copied, Linked };
JsonString() : _data(0), _size(0), _ownership(Linked) {} JsonString() : data_(0), size_(0), ownership_(Linked) {}
JsonString(const char* data, Ownership ownership = Linked) JsonString(const char* data, Ownership ownership = Linked)
: _data(data), _size(data ? ::strlen(data) : 0), _ownership(ownership) {} : data_(data), size_(data ? ::strlen(data) : 0), ownership_(ownership) {}
JsonString(const char* data, size_t sz, Ownership ownership = Linked) JsonString(const char* data, size_t sz, Ownership ownership = Linked)
: _data(data), _size(sz), _ownership(ownership) {} : data_(data), size_(sz), ownership_(ownership) {}
// Returns a pointer to the characters. // Returns a pointer to the characters.
const char* c_str() const { const char* c_str() const {
return _data; return data_;
} }
// Returns true if the string is null. // Returns true if the string is null.
bool isNull() const { bool isNull() const {
return !_data; return !data_;
} }
// Returns true if the string is stored by address. // Returns true if the string is stored by address.
// Returns false if the string is stored by copy. // Returns false if the string is stored by copy.
bool isLinked() const { bool isLinked() const {
return _ownership == Linked; return ownership_ == Linked;
} }
// Returns length of the string. // Returns length of the string.
size_t size() const { size_t size() const {
return _size; return size_;
} }
// Returns true if the string is non-null // Returns true if the string is non-null
explicit operator bool() const { explicit operator bool() const {
return _data != 0; return data_ != 0;
} }
// Returns true if strings are equal. // Returns true if strings are equal.
friend bool operator==(JsonString lhs, JsonString rhs) { friend bool operator==(JsonString lhs, JsonString rhs) {
if (lhs._size != rhs._size) if (lhs.size_ != rhs.size_)
return false; return false;
if (lhs._data == rhs._data) if (lhs.data_ == rhs.data_)
return true; return true;
if (!lhs._data) if (!lhs.data_)
return false; return false;
if (!rhs._data) if (!rhs.data_)
return false; return false;
return memcmp(lhs._data, rhs._data, lhs._size) == 0; return memcmp(lhs.data_, rhs.data_, lhs.size_) == 0;
} }
// Returns true if strings differs. // Returns true if strings differs.
@ -76,9 +76,9 @@ class JsonString {
#endif #endif
private: private:
const char* _data; const char* data_;
size_t _size; size_t size_;
Ownership _ownership; Ownership ownership_;
}; };
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

@ -205,43 +205,43 @@ struct Converter<decltype(nullptr)> : private detail::VariantAttorney {
namespace detail { namespace detail {
class MemoryPoolPrint : public Print { class MemoryPoolPrint : public Print {
public: public:
MemoryPoolPrint(MemoryPool* pool) : _pool(pool), _size(0) { MemoryPoolPrint(MemoryPool* pool) : pool_(pool), size_(0) {
pool->getFreeZone(&_string, &_capacity); pool->getFreeZone(&string_, &capacity_);
} }
JsonString str() { JsonString str() {
ARDUINOJSON_ASSERT(_size < _capacity); ARDUINOJSON_ASSERT(size_ < capacity_);
return JsonString(_pool->saveStringFromFreeZone(_size), _size, return JsonString(pool_->saveStringFromFreeZone(size_), size_,
JsonString::Copied); JsonString::Copied);
} }
size_t write(uint8_t c) { size_t write(uint8_t c) {
if (_size >= _capacity) if (size_ >= capacity_)
return 0; return 0;
_string[_size++] = char(c); string_[size_++] = char(c);
return 1; return 1;
} }
size_t write(const uint8_t* buffer, size_t size) { size_t write(const uint8_t* buffer, size_t size) {
if (_size + size >= _capacity) { if (size_ + size >= capacity_) {
_size = _capacity; // mark as overflowed size_ = capacity_; // mark as overflowed
return 0; return 0;
} }
memcpy(&_string[_size], buffer, size); memcpy(&string_[size_], buffer, size);
_size += size; size_ += size;
return size; return size;
} }
bool overflowed() const { bool overflowed() const {
return _size >= _capacity; return size_ >= capacity_;
} }
private: private:
MemoryPool* _pool; MemoryPool* pool_;
size_t _size; size_t size_;
char* _string; char* string_;
size_t _capacity; size_t capacity_;
}; };
} // namespace detail } // namespace detail

@ -16,27 +16,27 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
public: public:
// Creates an unbound reference. // Creates an unbound reference.
JsonVariant() : _data(0), _pool(0) {} JsonVariant() : data_(0), pool_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonVariant(detail::MemoryPool* pool, detail::VariantData* data) JsonVariant(detail::MemoryPool* pool, detail::VariantData* data)
: _data(data), _pool(pool) {} : data_(data), pool_(pool) {}
private: private:
FORCE_INLINE detail::MemoryPool* getPool() const { FORCE_INLINE detail::MemoryPool* getPool() const {
return _pool; return pool_;
} }
FORCE_INLINE detail::VariantData* getData() const { FORCE_INLINE detail::VariantData* getData() const {
return _data; return data_;
} }
FORCE_INLINE detail::VariantData* getOrCreateData() const { FORCE_INLINE detail::VariantData* getOrCreateData() const {
return _data; return data_;
} }
detail::VariantData* _data; detail::VariantData* data_;
detail::MemoryPool* _pool; detail::MemoryPool* pool_;
}; };
template <> template <>

@ -30,39 +30,39 @@ class JsonVariantConst : public detail::VariantTag,
public: public:
// Creates an unbound reference. // Creates an unbound reference.
JsonVariantConst() : _data(0) {} JsonVariantConst() : data_(0) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
explicit JsonVariantConst(const detail::VariantData* data) : _data(data) {} explicit JsonVariantConst(const detail::VariantData* data) : data_(data) {}
// Returns true if the value is null or the reference is unbound. // Returns true if the value is null or the reference is unbound.
// https://arduinojson.org/v6/api/jsonvariantconst/isnull/ // https://arduinojson.org/v6/api/jsonvariantconst/isnull/
FORCE_INLINE bool isNull() const { FORCE_INLINE bool isNull() const {
using namespace detail; using namespace detail;
return variantIsNull(_data); return variantIsNull(data_);
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
FORCE_INLINE bool isUnbound() const { FORCE_INLINE bool isUnbound() const {
return !_data; return !data_;
} }
// Returns the number of bytes occupied by the value. // Returns the number of bytes occupied by the value.
// https://arduinojson.org/v6/api/jsonvariantconst/memoryusage/ // https://arduinojson.org/v6/api/jsonvariantconst/memoryusage/
FORCE_INLINE size_t memoryUsage() const { FORCE_INLINE size_t memoryUsage() const {
return _data ? _data->memoryUsage() : 0; return data_ ? data_->memoryUsage() : 0;
} }
// Returns the depth (nesting level) of the value. // Returns the depth (nesting level) of the value.
// https://arduinojson.org/v6/api/jsonvariantconst/nesting/ // https://arduinojson.org/v6/api/jsonvariantconst/nesting/
FORCE_INLINE size_t nesting() const { FORCE_INLINE size_t nesting() const {
return variantNesting(_data); return variantNesting(data_);
} }
// Returns the size of the array or object. // Returns the size of the array or object.
// https://arduinojson.org/v6/api/jsonvariantconst/size/ // https://arduinojson.org/v6/api/jsonvariantconst/size/
size_t size() const { size_t size() const {
return variantSize(_data); return variantSize(data_);
} }
// Casts the value to the specified type. // Casts the value to the specified type.
@ -93,7 +93,7 @@ class JsonVariantConst : public detail::VariantTag,
// Gets array's element at specified index. // Gets array's element at specified index.
// https://arduinojson.org/v6/api/jsonvariantconst/subscript/ // https://arduinojson.org/v6/api/jsonvariantconst/subscript/
FORCE_INLINE JsonVariantConst operator[](size_t index) const { FORCE_INLINE JsonVariantConst operator[](size_t index) const {
return JsonVariantConst(variantGetElement(_data, index)); return JsonVariantConst(variantGetElement(data_, index));
} }
// Gets object's member with specified key. // Gets object's member with specified key.
@ -102,7 +102,7 @@ class JsonVariantConst : public detail::VariantTag,
FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value, FORCE_INLINE typename detail::enable_if<detail::IsString<TString>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](const TString& key) const { operator[](const TString& key) const {
return JsonVariantConst(variantGetMember(_data, detail::adaptString(key))); return JsonVariantConst(variantGetMember(data_, detail::adaptString(key)));
} }
// Gets object's member with specified key. // Gets object's member with specified key.
@ -111,7 +111,7 @@ class JsonVariantConst : public detail::VariantTag,
FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value, FORCE_INLINE typename detail::enable_if<detail::IsString<TChar*>::value,
JsonVariantConst>::type JsonVariantConst>::type
operator[](TChar* key) const { operator[](TChar* key) const {
return JsonVariantConst(variantGetMember(_data, detail::adaptString(key))); return JsonVariantConst(variantGetMember(data_, detail::adaptString(key)));
} }
// Returns true if tge object contains the specified key. // Returns true if tge object contains the specified key.
@ -134,11 +134,11 @@ class JsonVariantConst : public detail::VariantTag,
protected: protected:
const detail::VariantData* getData() const { const detail::VariantData* getData() const {
return _data; return data_;
} }
private: private:
const detail::VariantData* _data; const detail::VariantData* data_;
}; };
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

@ -10,17 +10,17 @@
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
struct SlotKeySetter { struct SlotKeySetter {
SlotKeySetter(VariantSlot* instance) : _instance(instance) {} SlotKeySetter(VariantSlot* instance) : instance_(instance) {}
template <typename TStoredString> template <typename TStoredString>
void operator()(TStoredString s) { void operator()(TStoredString s) {
if (!s) if (!s)
return; return;
ARDUINOJSON_ASSERT(_instance != 0); ARDUINOJSON_ASSERT(instance_ != 0);
_instance->setKey(s); instance_->setKey(s);
} }
VariantSlot* _instance; VariantSlot* instance_;
}; };
template <typename TAdaptedString> template <typename TAdaptedString>

@ -81,12 +81,12 @@ struct Comparer<decltype(nullptr), void> : NullComparer {
}; };
struct ArrayComparer : ComparerBase { struct ArrayComparer : ComparerBase {
const CollectionData* _rhs; const CollectionData* rhs_;
explicit ArrayComparer(const CollectionData& rhs) : _rhs(&rhs) {} explicit ArrayComparer(const CollectionData& rhs) : rhs_(&rhs) {}
CompareResult visitArray(const CollectionData& lhs) { CompareResult visitArray(const CollectionData& lhs) {
if (JsonArrayConst(&lhs) == JsonArrayConst(_rhs)) if (JsonArrayConst(&lhs) == JsonArrayConst(rhs_))
return COMPARE_RESULT_EQUAL; return COMPARE_RESULT_EQUAL;
else else
return COMPARE_RESULT_DIFFER; return COMPARE_RESULT_DIFFER;
@ -94,12 +94,12 @@ struct ArrayComparer : ComparerBase {
}; };
struct ObjectComparer : ComparerBase { struct ObjectComparer : ComparerBase {
const CollectionData* _rhs; const CollectionData* rhs_;
explicit ObjectComparer(const CollectionData& rhs) : _rhs(&rhs) {} explicit ObjectComparer(const CollectionData& rhs) : rhs_(&rhs) {}
CompareResult visitObject(const CollectionData& lhs) { CompareResult visitObject(const CollectionData& lhs) {
if (JsonObjectConst(&lhs) == JsonObjectConst(_rhs)) if (JsonObjectConst(&lhs) == JsonObjectConst(rhs_))
return COMPARE_RESULT_EQUAL; return COMPARE_RESULT_EQUAL;
else else
return COMPARE_RESULT_DIFFER; return COMPARE_RESULT_DIFFER;
@ -107,15 +107,15 @@ struct ObjectComparer : ComparerBase {
}; };
struct RawComparer : ComparerBase { struct RawComparer : ComparerBase {
const char* _rhsData; const char* rhsData_;
size_t _rhsSize; size_t rhsSize_;
explicit RawComparer(const char* rhsData, size_t rhsSize) explicit RawComparer(const char* rhsData, size_t rhsSize)
: _rhsData(rhsData), _rhsSize(rhsSize) {} : rhsData_(rhsData), rhsSize_(rhsSize) {}
CompareResult visitRawJson(const char* lhsData, size_t lhsSize) { CompareResult visitRawJson(const char* lhsData, size_t lhsSize) {
size_t size = _rhsSize < lhsSize ? _rhsSize : lhsSize; size_t size = rhsSize_ < lhsSize ? rhsSize_ : lhsSize;
int n = memcmp(lhsData, _rhsData, size); int n = memcmp(lhsData, rhsData_, size);
if (n < 0) if (n < 0)
return COMPARE_RESULT_LESS; return COMPARE_RESULT_LESS;
else if (n > 0) else if (n > 0)

@ -11,67 +11,50 @@
#include <ArduinoJson/Strings/StringAdapters.hpp> #include <ArduinoJson/Strings/StringAdapters.hpp>
#include <ArduinoJson/Variant/VariantContent.hpp> #include <ArduinoJson/Variant/VariantContent.hpp>
// VariantData can't have a constructor (to be a POD), so we have no way to fix
// this warning
#if defined(__GNUC__)
# if __GNUC__ >= 7
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
# pragma GCC diagnostic ignored "-Wuninitialized"
# endif
#endif
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class VariantData { class VariantData {
VariantContent _content; // must be first to allow cast from array to variant VariantContent content_; // must be first to allow cast from array to variant
uint8_t _flags; uint8_t flags_;
public: public:
// Must be a POD! VariantData() : flags_(VALUE_IS_NULL) {}
// - no constructor
// - no destructor
// - no virtual
// - no inheritance
void init() {
_flags = VALUE_IS_NULL;
}
void operator=(const VariantData& src) { void operator=(const VariantData& src) {
_content = src._content; content_ = src.content_;
_flags = uint8_t((_flags & OWNED_KEY_BIT) | (src._flags & ~OWNED_KEY_BIT)); flags_ = uint8_t((flags_ & OWNED_KEY_BIT) | (src.flags_ & ~OWNED_KEY_BIT));
} }
template <typename TVisitor> template <typename TVisitor>
typename TVisitor::result_type accept(TVisitor& visitor) const { typename TVisitor::result_type accept(TVisitor& visitor) const {
switch (type()) { switch (type()) {
case VALUE_IS_FLOAT: case VALUE_IS_FLOAT:
return visitor.visitFloat(_content.asFloat); return visitor.visitFloat(content_.asFloat);
case VALUE_IS_ARRAY: case VALUE_IS_ARRAY:
return visitor.visitArray(_content.asCollection); return visitor.visitArray(content_.asCollection);
case VALUE_IS_OBJECT: case VALUE_IS_OBJECT:
return visitor.visitObject(_content.asCollection); return visitor.visitObject(content_.asCollection);
case VALUE_IS_LINKED_STRING: case VALUE_IS_LINKED_STRING:
case VALUE_IS_OWNED_STRING: case VALUE_IS_OWNED_STRING:
return visitor.visitString(_content.asString.data, return visitor.visitString(content_.asString.data,
_content.asString.size); content_.asString.size);
case VALUE_IS_OWNED_RAW: case VALUE_IS_OWNED_RAW:
case VALUE_IS_LINKED_RAW: case VALUE_IS_LINKED_RAW:
return visitor.visitRawJson(_content.asString.data, return visitor.visitRawJson(content_.asString.data,
_content.asString.size); content_.asString.size);
case VALUE_IS_SIGNED_INTEGER: case VALUE_IS_SIGNED_INTEGER:
return visitor.visitSignedInteger(_content.asSignedInteger); return visitor.visitSignedInteger(content_.asSignedInteger);
case VALUE_IS_UNSIGNED_INTEGER: case VALUE_IS_UNSIGNED_INTEGER:
return visitor.visitUnsignedInteger(_content.asUnsignedInteger); return visitor.visitUnsignedInteger(content_.asUnsignedInteger);
case VALUE_IS_BOOLEAN: case VALUE_IS_BOOLEAN:
return visitor.visitBoolean(_content.asBoolean != 0); return visitor.visitBoolean(content_.asBoolean != 0);
default: default:
return visitor.visitNull(); return visitor.visitNull();
@ -89,7 +72,7 @@ class VariantData {
bool asBoolean() const; bool asBoolean() const;
CollectionData* asArray() { CollectionData* asArray() {
return isArray() ? &_content.asCollection : 0; return isArray() ? &content_.asCollection : 0;
} }
const CollectionData* asArray() const { const CollectionData* asArray() const {
@ -97,11 +80,11 @@ class VariantData {
} }
const CollectionData* asCollection() const { const CollectionData* asCollection() const {
return isCollection() ? &_content.asCollection : 0; return isCollection() ? &content_.asCollection : 0;
} }
CollectionData* asObject() { CollectionData* asObject() {
return isObject() ? &_content.asCollection : 0; return isObject() ? &content_.asCollection : 0;
} }
const CollectionData* asObject() const { const CollectionData* asObject() const {
@ -111,7 +94,7 @@ class VariantData {
bool copyFrom(const VariantData& src, MemoryPool* pool); bool copyFrom(const VariantData& src, MemoryPool* pool);
bool isArray() const { bool isArray() const {
return (_flags & VALUE_IS_ARRAY) != 0; return (flags_ & VALUE_IS_ARRAY) != 0;
} }
bool isBoolean() const { bool isBoolean() const {
@ -119,17 +102,17 @@ class VariantData {
} }
bool isCollection() const { bool isCollection() const {
return (_flags & COLLECTION_MASK) != 0; return (flags_ & COLLECTION_MASK) != 0;
} }
template <typename T> template <typename T>
bool isInteger() const { bool isInteger() const {
switch (type()) { switch (type()) {
case VALUE_IS_UNSIGNED_INTEGER: case VALUE_IS_UNSIGNED_INTEGER:
return canConvertNumber<T>(_content.asUnsignedInteger); return canConvertNumber<T>(content_.asUnsignedInteger);
case VALUE_IS_SIGNED_INTEGER: case VALUE_IS_SIGNED_INTEGER:
return canConvertNumber<T>(_content.asSignedInteger); return canConvertNumber<T>(content_.asSignedInteger);
default: default:
return false; return false;
@ -137,7 +120,7 @@ class VariantData {
} }
bool isFloat() const { bool isFloat() const {
return (_flags & NUMBER_BIT) != 0; return (flags_ & NUMBER_BIT) != 0;
} }
bool isString() const { bool isString() const {
@ -145,7 +128,7 @@ class VariantData {
} }
bool isObject() const { bool isObject() const {
return (_flags & VALUE_IS_OBJECT) != 0; return (flags_ & VALUE_IS_OBJECT) != 0;
} }
bool isNull() const { bool isNull() const {
@ -158,30 +141,30 @@ class VariantData {
void remove(size_t index) { void remove(size_t index) {
if (isArray()) if (isArray())
_content.asCollection.removeElement(index); content_.asCollection.removeElement(index);
} }
template <typename TAdaptedString> template <typename TAdaptedString>
void remove(TAdaptedString key) { void remove(TAdaptedString key) {
if (isObject()) if (isObject())
_content.asCollection.removeMember(key); content_.asCollection.removeMember(key);
} }
void setBoolean(bool value) { void setBoolean(bool value) {
setType(VALUE_IS_BOOLEAN); setType(VALUE_IS_BOOLEAN);
_content.asBoolean = value; content_.asBoolean = value;
} }
void setFloat(JsonFloat value) { void setFloat(JsonFloat value) {
setType(VALUE_IS_FLOAT); setType(VALUE_IS_FLOAT);
_content.asFloat = value; content_.asFloat = value;
} }
void setLinkedRaw(SerializedValue<const char*> value) { void setLinkedRaw(SerializedValue<const char*> value) {
if (value.data()) { if (value.data()) {
setType(VALUE_IS_LINKED_RAW); setType(VALUE_IS_LINKED_RAW);
_content.asString.data = value.data(); content_.asString.data = value.data();
_content.asString.size = value.size(); content_.asString.size = value.size();
} else { } else {
setType(VALUE_IS_NULL); setType(VALUE_IS_NULL);
} }
@ -192,8 +175,8 @@ class VariantData {
const char* dup = pool->saveString(adaptString(value.data(), value.size())); const char* dup = pool->saveString(adaptString(value.data(), value.size()));
if (dup) { if (dup) {
setType(VALUE_IS_OWNED_RAW); setType(VALUE_IS_OWNED_RAW);
_content.asString.data = dup; content_.asString.data = dup;
_content.asString.size = value.size(); content_.asString.size = value.size();
return true; return true;
} else { } else {
setType(VALUE_IS_NULL); setType(VALUE_IS_NULL);
@ -204,13 +187,13 @@ class VariantData {
template <typename T> template <typename T>
typename enable_if<is_unsigned<T>::value>::type setInteger(T value) { typename enable_if<is_unsigned<T>::value>::type setInteger(T value) {
setType(VALUE_IS_UNSIGNED_INTEGER); setType(VALUE_IS_UNSIGNED_INTEGER);
_content.asUnsignedInteger = static_cast<JsonUInt>(value); content_.asUnsignedInteger = static_cast<JsonUInt>(value);
} }
template <typename T> template <typename T>
typename enable_if<is_signed<T>::value>::type setInteger(T value) { typename enable_if<is_signed<T>::value>::type setInteger(T value) {
setType(VALUE_IS_SIGNED_INTEGER); setType(VALUE_IS_SIGNED_INTEGER);
_content.asSignedInteger = value; content_.asSignedInteger = value;
} }
void setNull() { void setNull() {
@ -223,20 +206,20 @@ class VariantData {
setType(VALUE_IS_LINKED_STRING); setType(VALUE_IS_LINKED_STRING);
else else
setType(VALUE_IS_OWNED_STRING); setType(VALUE_IS_OWNED_STRING);
_content.asString.data = s.c_str(); content_.asString.data = s.c_str();
_content.asString.size = s.size(); content_.asString.size = s.size();
} }
CollectionData& toArray() { CollectionData& toArray() {
setType(VALUE_IS_ARRAY); setType(VALUE_IS_ARRAY);
_content.asCollection.clear(); content_.asCollection.clear();
return _content.asCollection; return content_.asCollection;
} }
CollectionData& toObject() { CollectionData& toObject() {
setType(VALUE_IS_OBJECT); setType(VALUE_IS_OBJECT);
_content.asCollection.clear(); content_.asCollection.clear();
return _content.asCollection; return content_.asCollection;
} }
size_t memoryUsage() const { size_t memoryUsage() const {
@ -245,17 +228,17 @@ class VariantData {
case VALUE_IS_OWNED_RAW: case VALUE_IS_OWNED_RAW:
// We always add a zero at the end: the deduplication function uses it // We always add a zero at the end: the deduplication function uses it
// to detect the beginning of the next string. // to detect the beginning of the next string.
return _content.asString.size + 1; return content_.asString.size + 1;
case VALUE_IS_OBJECT: case VALUE_IS_OBJECT:
case VALUE_IS_ARRAY: case VALUE_IS_ARRAY:
return _content.asCollection.memoryUsage(); return content_.asCollection.memoryUsage();
default: default:
return 0; return 0;
} }
} }
size_t size() const { size_t size() const {
return isCollection() ? _content.asCollection.size() : 0; return isCollection() ? content_.asCollection.size() : 0;
} }
VariantData* addElement(MemoryPool* pool) { VariantData* addElement(MemoryPool* pool) {
@ -263,7 +246,7 @@ class VariantData {
toArray(); toArray();
if (!isArray()) if (!isArray())
return 0; return 0;
return _content.asCollection.addElement(pool); return content_.asCollection.addElement(pool);
} }
VariantData* getElement(size_t index) const { VariantData* getElement(size_t index) const {
@ -276,7 +259,7 @@ class VariantData {
toArray(); toArray();
if (!isArray()) if (!isArray())
return 0; return 0;
return _content.asCollection.getOrAddElement(index, pool); return content_.asCollection.getOrAddElement(index, pool);
} }
template <typename TAdaptedString> template <typename TAdaptedString>
@ -291,18 +274,18 @@ class VariantData {
toObject(); toObject();
if (!isObject()) if (!isObject())
return 0; return 0;
return _content.asCollection.getOrAddMember(key, pool); return content_.asCollection.getOrAddMember(key, pool);
} }
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) { void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) {
if (_flags & OWNED_VALUE_BIT) if (flags_ & OWNED_VALUE_BIT)
_content.asString.data += stringDistance; content_.asString.data += stringDistance;
if (_flags & COLLECTION_MASK) if (flags_ & COLLECTION_MASK)
_content.asCollection.movePointers(stringDistance, variantDistance); content_.asCollection.movePointers(stringDistance, variantDistance);
} }
uint8_t type() const { uint8_t type() const {
return _flags & VALUE_MASK; return flags_ & VALUE_MASK;
} }
template <typename TAdaptedString> template <typename TAdaptedString>
@ -317,29 +300,23 @@ class VariantData {
private: private:
void setType(uint8_t t) { void setType(uint8_t t) {
_flags &= OWNED_KEY_BIT; flags_ &= OWNED_KEY_BIT;
_flags |= t; flags_ |= t;
} }
struct VariantStringSetter { struct VariantStringSetter {
VariantStringSetter(VariantData* instance) : _instance(instance) {} VariantStringSetter(VariantData* instance) : instance_(instance) {}
template <typename TStoredString> template <typename TStoredString>
void operator()(TStoredString s) { void operator()(TStoredString s) {
if (s) if (s)
_instance->setString(s); instance_->setString(s);
else else
_instance->setNull(); instance_->setNull();
} }
VariantData* _instance; VariantData* instance_;
}; };
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE
#if defined(__GNUC__)
# if __GNUC__ >= 8
# pragma GCC diagnostic pop
# endif
#endif

@ -19,16 +19,16 @@ template <typename T>
inline T VariantData::asIntegral() const { inline T VariantData::asIntegral() const {
switch (type()) { switch (type()) {
case VALUE_IS_BOOLEAN: case VALUE_IS_BOOLEAN:
return _content.asBoolean; return content_.asBoolean;
case VALUE_IS_UNSIGNED_INTEGER: case VALUE_IS_UNSIGNED_INTEGER:
return convertNumber<T>(_content.asUnsignedInteger); return convertNumber<T>(content_.asUnsignedInteger);
case VALUE_IS_SIGNED_INTEGER: case VALUE_IS_SIGNED_INTEGER:
return convertNumber<T>(_content.asSignedInteger); return convertNumber<T>(content_.asSignedInteger);
case VALUE_IS_LINKED_STRING: case VALUE_IS_LINKED_STRING:
case VALUE_IS_OWNED_STRING: case VALUE_IS_OWNED_STRING:
return parseNumber<T>(_content.asString.data); return parseNumber<T>(content_.asString.data);
case VALUE_IS_FLOAT: case VALUE_IS_FLOAT:
return convertNumber<T>(_content.asFloat); return convertNumber<T>(content_.asFloat);
default: default:
return 0; return 0;
} }
@ -37,12 +37,12 @@ inline T VariantData::asIntegral() const {
inline bool VariantData::asBoolean() const { inline bool VariantData::asBoolean() const {
switch (type()) { switch (type()) {
case VALUE_IS_BOOLEAN: case VALUE_IS_BOOLEAN:
return _content.asBoolean; return content_.asBoolean;
case VALUE_IS_SIGNED_INTEGER: case VALUE_IS_SIGNED_INTEGER:
case VALUE_IS_UNSIGNED_INTEGER: case VALUE_IS_UNSIGNED_INTEGER:
return _content.asUnsignedInteger != 0; return content_.asUnsignedInteger != 0;
case VALUE_IS_FLOAT: case VALUE_IS_FLOAT:
return _content.asFloat != 0; return content_.asFloat != 0;
case VALUE_IS_NULL: case VALUE_IS_NULL:
return false; return false;
default: default:
@ -55,16 +55,16 @@ template <typename T>
inline T VariantData::asFloat() const { inline T VariantData::asFloat() const {
switch (type()) { switch (type()) {
case VALUE_IS_BOOLEAN: case VALUE_IS_BOOLEAN:
return static_cast<T>(_content.asBoolean); return static_cast<T>(content_.asBoolean);
case VALUE_IS_UNSIGNED_INTEGER: case VALUE_IS_UNSIGNED_INTEGER:
return static_cast<T>(_content.asUnsignedInteger); return static_cast<T>(content_.asUnsignedInteger);
case VALUE_IS_SIGNED_INTEGER: case VALUE_IS_SIGNED_INTEGER:
return static_cast<T>(_content.asSignedInteger); return static_cast<T>(content_.asSignedInteger);
case VALUE_IS_LINKED_STRING: case VALUE_IS_LINKED_STRING:
case VALUE_IS_OWNED_STRING: case VALUE_IS_OWNED_STRING:
return parseNumber<T>(_content.asString.data); return parseNumber<T>(content_.asString.data);
case VALUE_IS_FLOAT: case VALUE_IS_FLOAT:
return static_cast<T>(_content.asFloat); return static_cast<T>(content_.asFloat);
default: default:
return 0; return 0;
} }
@ -73,10 +73,10 @@ inline T VariantData::asFloat() const {
inline JsonString VariantData::asString() const { inline JsonString VariantData::asString() const {
switch (type()) { switch (type()) {
case VALUE_IS_LINKED_STRING: case VALUE_IS_LINKED_STRING:
return JsonString(_content.asString.data, _content.asString.size, return JsonString(content_.asString.data, content_.asString.size,
JsonString::Linked); JsonString::Linked);
case VALUE_IS_OWNED_STRING: case VALUE_IS_OWNED_STRING:
return JsonString(_content.asString.data, _content.asString.size, return JsonString(content_.asString.data, content_.asString.size,
JsonString::Copied); JsonString::Copied);
default: default:
return JsonString(); return JsonString();
@ -86,20 +86,20 @@ inline JsonString VariantData::asString() const {
inline bool VariantData::copyFrom(const VariantData& src, MemoryPool* pool) { inline bool VariantData::copyFrom(const VariantData& src, MemoryPool* pool) {
switch (src.type()) { switch (src.type()) {
case VALUE_IS_ARRAY: case VALUE_IS_ARRAY:
return toArray().copyFrom(src._content.asCollection, pool); return toArray().copyFrom(src.content_.asCollection, pool);
case VALUE_IS_OBJECT: case VALUE_IS_OBJECT:
return toObject().copyFrom(src._content.asCollection, pool); return toObject().copyFrom(src.content_.asCollection, pool);
case VALUE_IS_OWNED_STRING: { case VALUE_IS_OWNED_STRING: {
JsonString value = src.asString(); JsonString value = src.asString();
return setString(adaptString(value), pool); return setString(adaptString(value), pool);
} }
case VALUE_IS_OWNED_RAW: case VALUE_IS_OWNED_RAW:
return storeOwnedRaw( return storeOwnedRaw(
serialized(src._content.asString.data, src._content.asString.size), serialized(src.content_.asString.data, src.content_.asString.size),
pool); pool);
default: default:
setType(src.type()); setType(src.type());
_content = src._content; content_ = src.content_;
return true; return true;
} }
} }
@ -138,8 +138,9 @@ template <typename TDerived>
template <typename T> template <typename T>
typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type typename enable_if<is_same<T, JsonVariant>::value, JsonVariant>::type
VariantRefBase<TDerived>::to() const { VariantRefBase<TDerived>::to() const {
variantSetNull(getOrCreateData()); auto data = getOrCreateData();
return *this; variantSetNull(data);
return JsonVariant(getPool(), data);
} }
template <typename TDerived> template <typename TDerived>

@ -17,10 +17,10 @@ class VariantSlot {
// CAUTION: same layout as VariantData // CAUTION: same layout as VariantData
// we cannot use composition because it adds padding // we cannot use composition because it adds padding
// (+20% on ESP8266 for example) // (+20% on ESP8266 for example)
VariantContent _content; VariantContent content_;
uint8_t _flags; uint8_t flags_;
VariantSlotDiff _next; VariantSlotDiff next_;
const char* _key; const char* key_;
public: public:
// Must be a POD! // Must be a POD!
@ -30,15 +30,15 @@ class VariantSlot {
// - no inheritance // - no inheritance
VariantData* data() { VariantData* data() {
return reinterpret_cast<VariantData*>(&_content); return reinterpret_cast<VariantData*>(&content_);
} }
const VariantData* data() const { const VariantData* data() const {
return reinterpret_cast<const VariantData*>(&_content); return reinterpret_cast<const VariantData*>(&content_);
} }
VariantSlot* next() { VariantSlot* next() {
return _next ? this + _next : 0; return next_ ? this + next_ : 0;
} }
const VariantSlot* next() const { const VariantSlot* next() const {
@ -48,9 +48,9 @@ class VariantSlot {
VariantSlot* next(size_t distance) { VariantSlot* next(size_t distance) {
VariantSlot* slot = this; VariantSlot* slot = this;
while (distance--) { while (distance--) {
if (!slot->_next) if (!slot->next_)
return 0; return 0;
slot += slot->_next; slot += slot->next_;
} }
return slot; return slot;
} }
@ -64,7 +64,7 @@ class VariantSlot {
numeric_limits<VariantSlotDiff>::lowest()); numeric_limits<VariantSlotDiff>::lowest());
ARDUINOJSON_ASSERT(!slot || slot - this <= ARDUINOJSON_ASSERT(!slot || slot - this <=
numeric_limits<VariantSlotDiff>::highest()); numeric_limits<VariantSlotDiff>::highest());
_next = VariantSlotDiff(slot ? slot - this : 0); next_ = VariantSlotDiff(slot ? slot - this : 0);
} }
void setNextNotNull(VariantSlot* slot) { void setNextNotNull(VariantSlot* slot) {
@ -73,39 +73,39 @@ class VariantSlot {
numeric_limits<VariantSlotDiff>::lowest()); numeric_limits<VariantSlotDiff>::lowest());
ARDUINOJSON_ASSERT(slot - this <= ARDUINOJSON_ASSERT(slot - this <=
numeric_limits<VariantSlotDiff>::highest()); numeric_limits<VariantSlotDiff>::highest());
_next = VariantSlotDiff(slot - this); next_ = VariantSlotDiff(slot - this);
} }
void setKey(JsonString k) { void setKey(JsonString k) {
ARDUINOJSON_ASSERT(k); ARDUINOJSON_ASSERT(k);
if (k.isLinked()) if (k.isLinked())
_flags &= VALUE_MASK; flags_ &= VALUE_MASK;
else else
_flags |= OWNED_KEY_BIT; flags_ |= OWNED_KEY_BIT;
_key = k.c_str(); key_ = k.c_str();
} }
const char* key() const { const char* key() const {
return _key; return key_;
} }
bool ownsKey() const { bool ownsKey() const {
return (_flags & OWNED_KEY_BIT) != 0; return (flags_ & OWNED_KEY_BIT) != 0;
} }
void clear() { void clear() {
_next = 0; next_ = 0;
_flags = 0; flags_ = 0;
_key = 0; key_ = 0;
} }
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) { void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) {
if (_flags & OWNED_KEY_BIT) if (flags_ & OWNED_KEY_BIT)
_key += stringDistance; key_ += stringDistance;
if (_flags & OWNED_VALUE_BIT) if (flags_ & OWNED_VALUE_BIT)
_content.asString.data += stringDistance; content_.asString.data += stringDistance;
if (_flags & COLLECTION_MASK) if (flags_ & COLLECTION_MASK)
_content.asCollection.movePointers(stringDistance, variantDistance); content_.asCollection.movePointers(stringDistance, variantDistance);
} }
}; };

@ -4,7 +4,8 @@
#pragma once #pragma once
#define ARDUINOJSON_VERSION "6.21.0" #define ARDUINOJSON_VERSION "6.21.3"
#define ARDUINOJSON_VERSION_MAJOR 6 #define ARDUINOJSON_VERSION_MAJOR 6
#define ARDUINOJSON_VERSION_MINOR 21 #define ARDUINOJSON_VERSION_MINOR 21
#define ARDUINOJSON_VERSION_REVISION 0 #define ARDUINOJSON_VERSION_REVISION 3
#define ARDUINOJSON_VERSION_MACRO V6213

@ -312,6 +312,8 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) {
if (!voices[note].keydown) if (!voices[note].keydown)
{ {
currentNote = (note + 1) % max_notes; currentNote = (note + 1) % max_notes;
//if (keydown_counter == 0) // Original comment: TODO: should only do this if # keys down was 0
lfo.keydown();
voices[note].midi_note = pitch; voices[note].midi_note = pitch;
voices[note].velocity = velo; voices[note].velocity = velo;
voices[note].sustained = sustain; voices[note].sustained = sustain;
@ -331,10 +333,6 @@ void Dexed::keydown(int16_t pitch, uint8_t velo) {
note = (note + 1) % max_notes; note = (note + 1) % max_notes;
} }
if (keydown_counter == 0)
lfo.keydown();
if ( monoMode ) { if ( monoMode ) {
for (uint8_t i = 0; i < max_notes; i++) { for (uint8_t i = 0; i < max_notes; i++) {
if ( voices[i].live ) { if ( voices[i].live ) {

Loading…
Cancel
Save