upgrade ArduinoJson to 6.21.2

This commit is contained in:
Proddy
2023-07-03 11:44:37 +02:00
parent ab4f8d46ad
commit d2523fc5d2
66 changed files with 1702 additions and 1389 deletions

View File

@@ -1,6 +1,19 @@
ArduinoJson: change log ArduinoJson: change log
======================= =======================
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)
------- -------

161
lib/ArduinoJson/README.md Normal file
View File

@@ -0,0 +1,161 @@
<p align="center">
<a href="https://arduinojson.org/"><img alt="ArduinoJson" src="https://arduinojson.org/images/logo.svg" width="200" /></a>
</p>
---
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/bblanchon/ArduinoJson/ci.yml?branch=6.x&logo=github)](https://github.com/bblanchon/ArduinoJson/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A6.x)
[![Continuous Integration](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/arduinojson.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
[![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.2&logo=arduino&logoColor=white&color=blue)](https://www.ardu-badge.com/ArduinoJson/6.21.2)
[![PlatformIO Registry](https://badges.registry.platformio.org/packages/bblanchon/library/ArduinoJson.svg?version=6.21.2)](https://registry.platformio.org/packages/libraries/bblanchon/ArduinoJson?version=6.21.2)
[![ESP IDF](https://img.shields.io/static/v1?label=ESP+IDF&message=v6.21.2&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 Sponsors](https://img.shields.io/github/sponsors/bblanchon?logo=github&color=orange)](https://github.com/sponsors/bblanchon)
ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
## Features
* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/)
* [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/)
* [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/)
* [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/)
* [Optionally filters the input to keep only desired values](https://arduinojson.org/v6/api/json/deserializejson/#filtering)
* Supports single quotes as a string delimiter
* Compatible with [NDJSON](http://ndjson.org/) and [JSON Lines](https://jsonlines.org/)
* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/)
* [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/)
* [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/)
* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/)
* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/)
* Efficient
* [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/)
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/)
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/)
* [Deduplicates strings](https://arduinojson.org/news/2020/08/01/version-6-16-0/)
* Versatile
* Supports [custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/)
* Supports [`String`](https://arduinojson.org/v6/api/config/enable_arduino_string/), [`std::string`](https://arduinojson.org/v6/api/config/enable_std_string/), and [`std::string_view`](https://arduinojson.org/v6/api/config/enable_string_view/)
* Supports [`Stream`](https://arduinojson.org/v6/api/config/enable_arduino_stream/) and [`std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/)
* Supports [Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/)
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/#custom-writer)
* Supports [custom converters](https://arduinojson.org/news/2021/05/04/version-6-18-0/)
* Portable
* Usable on any C++ project (not limited to Arduino)
* Compatible with C++11, C++14 and C++17
* Support for C++98/C++03 available on [ArduinoJson 6.20.x](https://github.com/bblanchon/ArduinoJson/tree/6.20.x)
* Zero warnings with `-Wall -Wextra -pedantic` and `/W4`
* [Header-only library](https://en.wikipedia.org/wiki/Header-only)
* Works with virtually any board
* Arduino boards: [Uno](https://amzn.to/38aL2ik), [Due](https://amzn.to/36YkWi2), [Micro](https://amzn.to/35WkdwG), [Nano](https://amzn.to/2QTvwRX), [Mega](https://amzn.to/36XWhuf), [Yun](https://amzn.to/30odURc), [Leonardo](https://amzn.to/36XWjlR)...
* Espressif chips: [ESP8266](https://amzn.to/36YluV8), [ESP32](https://amzn.to/2G4pRCB)
* Lolin (WeMos) boards: [D1 mini](https://amzn.to/2QUpz7q), [D1 Mini Pro](https://amzn.to/36UsGSs)...
* Teensy boards: [4.0](https://amzn.to/30ljXGq), [3.2](https://amzn.to/2FT0EuC), [2.0](https://amzn.to/2QXUMXj)
* Particle boards: [Argon](https://amzn.to/2FQHa9X), [Boron](https://amzn.to/36WgLUd), [Electron](https://amzn.to/30vEc4k), [Photon](https://amzn.to/387F9Cd)...
* Texas Instruments boards: [MSP430](https://amzn.to/30nJWgg)...
* Soft cores: [Nios II](https://en.wikipedia.org/wiki/Nios_II)...
* Tested on all major development environments
* [Arduino IDE](https://www.arduino.cc/en/Main/Software)
* [Atmel Studio](http://www.atmel.com/microsite/atmel-studio/)
* [Atollic TrueSTUDIO](https://atollic.com/truestudio/)
* [Energia](http://energia.nu/)
* [IAR Embedded Workbench](https://www.iar.com/iar-embedded-workbench/)
* [Keil uVision](http://www.keil.com/)
* [MPLAB X IDE](http://www.microchip.com/mplab/mplab-x-ide)
* [Particle](https://www.particle.io/)
* [PlatformIO](http://platformio.org/)
* [Sloeber plugin for Eclipse](https://eclipse.baeyens.it/)
* [Visual Micro](http://www.visualmicro.com/)
* [Visual Studio](https://www.visualstudio.com/)
* [Even works with online compilers like wandbox.org](https://wandbox.org/permlink/RlZSKy17DjJ6HcdN)
* [CMake friendly](https://arduinojson.org/v6/how-to/use-arduinojson-with-cmake/)
* Well designed
* [Elegant API](http://arduinojson.org/v6/example/)
* [Thread-safe](https://en.wikipedia.org/wiki/Thread_safety)
* Self-contained (no external dependency)
* `const` friendly
* [`for` friendly](https://arduinojson.org/v6/api/jsonobject/begin_end/)
* [TMP friendly](https://en.wikipedia.org/wiki/Template_metaprogramming)
* Handles [integer overflows](https://arduinojson.org/v6/api/jsonvariant/as/#integer-overflows)
* Well tested
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
* Continuously tested on
* [Visual Studio 2017, 2019, 2022](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
* [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)
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
* Passes all default checks of [clang-tidy](https://releases.llvm.org/10.0.0/tools/clang/tools/extra/docs/clang-tidy/)
* Well documented
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/)
* [Examples](https://arduinojson.org/v6/example/)
* [How-tos](https://arduinojson.org/v6/example/)
* [FAQ](https://arduinojson.org/v6/faq/)
* [Troubleshooter](https://arduinojson.org/v6/troubleshooter/)
* [Book](https://arduinojson.org/book/)
* [Changelog](CHANGELOG.md)
* Vibrant user community
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories)
* [Used in hundreds of projects](https://www.hackster.io/search?i=projects&q=arduinojson)
* [Responsive support](https://github.com/bblanchon/ArduinoJson/issues?q=is%3Aissue+is%3Aclosed)
## Quickstart
### Deserialization
Here is a program that parses a JSON document with ArduinoJson.
```c++
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
DynamicJsonDocument doc(1024);
deserializeJson(doc, json);
const char* sensor = doc["sensor"];
long time = doc["time"];
double latitude = doc["data"][0];
double longitude = doc["data"][1];
```
See the [tutorial on arduinojson.org](https://arduinojson.org/v6/doc/deserialization/)
### Serialization
Here is a program that generates a JSON document with ArduinoJson:
```c++
DynamicJsonDocument doc(1024);
doc["sensor"] = "gps";
doc["time"] = 1351824120;
doc["data"][0] = 48.756080;
doc["data"][1] = 2.302038;
serializeJson(doc, Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
```
See the [tutorial on arduinojson.org](https://arduinojson.org/v6/doc/serialization/)
## Sponsors
ArduinoJson is thankful to its sponsors. Please give them a visit; they deserve it!
<p>
<a href="https://www.programmingelectronics.com/" rel="sponsored">
<img src="https://arduinojson.org/images/2021/10/programmingeleactronicsacademy.png" alt="Programming Electronics Academy" width="200">
</a>
</p>
<p>
<a href="https://github.com/1technophile" rel="sponsored">
<img alt="1technophile" src="https://avatars.githubusercontent.com/u/12672732?s=40&v=4">
</a>
</p>
If you run a commercial project that embeds ArduinoJson, think about [sponsoring the library's development](https://github.com/sponsors/bblanchon): it ensures the code that your products rely on stays actively maintained. It can also give your project some exposure to the makers' community.
If you are an individual user and want to support the development (or give a sign of appreciation), consider purchasing the book [Mastering ArduinoJson](https://arduinojson.org/book/)&nbsp;❤, or simply [cast a star](https://github.com/bblanchon/ArduinoJson/stargazers)&nbsp;⭐.

View File

@@ -0,0 +1,40 @@
# Macros
JSON_ARRAY_SIZE KEYWORD2
JSON_OBJECT_SIZE KEYWORD2
JSON_STRING_SIZE KEYWORD2
# Free functions
deserializeJson KEYWORD2
deserializeMsgPack KEYWORD2
serialized KEYWORD2
serializeJson KEYWORD2
serializeJsonPretty KEYWORD2
serializeMsgPack KEYWORD2
measureJson KEYWORD2
measureJsonPretty KEYWORD2
measureMsgPack KEYWORD2
# Methods
add KEYWORD2
as KEYWORD2
createNestedArray KEYWORD2
createNestedObject KEYWORD2
get KEYWORD2
set KEYWORD2
to KEYWORD2
# Type names
DeserializationError KEYWORD1 DATA_TYPE
DynamicJsonDocument KEYWORD1 DATA_TYPE
JsonArray KEYWORD1 DATA_TYPE
JsonArrayConst KEYWORD1 DATA_TYPE
JsonDocument KEYWORD1 DATA_TYPE
JsonFloat KEYWORD1 DATA_TYPE
JsonInteger KEYWORD1 DATA_TYPE
JsonObject KEYWORD1 DATA_TYPE
JsonObjectConst KEYWORD1 DATA_TYPE
JsonString KEYWORD1 DATA_TYPE
JsonUInt KEYWORD1 DATA_TYPE
JsonVariant KEYWORD1 DATA_TYPE
JsonVariantConst KEYWORD1 DATA_TYPE
StaticJsonDocument KEYWORD1 DATA_TYPE

View File

@@ -0,0 +1,11 @@
name=ArduinoJson
version=6.21.2
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=A simple and efficient JSON library for embedded C++.
paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ MessagePack, ✔ fixed allocation, ✔ zero-copy, ✔ streams, ✔ filtering, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation.
category=Data Processing
url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties
architectures=*
repository=https://github.com/bblanchon/ArduinoJson.git
license=MIT

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -15,18 +15,18 @@ 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 return source_->read(); // Error here? You passed an unsupported input type
} }
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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -16,31 +16,34 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <typename TReader, typename TStringStorage> template <typename TReader, typename TStringStorage>
class MsgPackDeserializer { class MsgPackDeserializer {
public: public:
MsgPackDeserializer(MemoryPool * pool, TReader reader, TStringStorage stringStorage) MsgPackDeserializer(MemoryPool* pool, TReader reader,
: _pool(pool) TStringStorage stringStorage)
, _reader(reader) : pool_(pool),
, _stringStorage(stringStorage) reader_(reader),
, _foundSomething(false) { stringStorage_(stringStorage),
} foundSomething_(false) {}
template <typename TFilter> template <typename TFilter>
DeserializationError parse(VariantData & variant, TFilter filter, DeserializationOption::NestingLimit nestingLimit) { DeserializationError parse(VariantData& variant, TFilter filter,
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:
template <typename TFilter> template <typename TFilter>
DeserializationError::Code parseVariant(VariantData * variant, TFilter filter, DeserializationOption::NestingLimit nestingLimit) { DeserializationError::Code parseVariant(
VariantData* variant, TFilter filter,
DeserializationOption::NestingLimit nestingLimit) {
DeserializationError::Code err; DeserializationError::Code err;
uint8_t code = 0; uint8_t code = 0; // TODO: why do we need to initialize this variable?
err = readByte(code); err = readByte(code);
if (err) if (err)
return err; return err;
_foundSomething = true; foundSomething_ = true;
bool allowValue = filter.allowValue(); bool allowValue = filter.allowValue();
@@ -221,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);
@@ -229,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;
} }
@@ -241,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;
@@ -275,7 +278,8 @@ class MsgPackDeserializer {
} }
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type readFloat(VariantData * variant) { typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type
readFloat(VariantData* variant) {
DeserializationError::Code err; DeserializationError::Code err;
T value; T value;
@@ -290,7 +294,8 @@ class MsgPackDeserializer {
} }
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 8, DeserializationError::Code>::type readDouble(VariantData * variant) { typename enable_if<sizeof(T) == 8, DeserializationError::Code>::type
readDouble(VariantData* variant) {
DeserializationError::Code err; DeserializationError::Code err;
T value; T value;
@@ -305,7 +310,8 @@ class MsgPackDeserializer {
} }
template <typename T> template <typename T>
typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type readDouble(VariantData * variant) { typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type
readDouble(VariantData* variant) {
DeserializationError::Code err; DeserializationError::Code err;
uint8_t i[8]; // input is 8 bytes uint8_t i[8]; // input is 8 bytes
T value; // output is 4 bytes T value; // output is 4 bytes
@@ -365,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;
@@ -380,17 +386,19 @@ 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;
} }
template <typename TSize, typename TFilter> template <typename TSize, typename TFilter>
DeserializationError::Code readArray(VariantData * variant, TFilter filter, DeserializationOption::NestingLimit nestingLimit) { DeserializationError::Code readArray(
VariantData* variant, TFilter filter,
DeserializationOption::NestingLimit nestingLimit) {
DeserializationError::Code err; DeserializationError::Code err;
TSize size; TSize size;
@@ -402,7 +410,9 @@ class MsgPackDeserializer {
} }
template <typename TFilter> template <typename TFilter>
DeserializationError::Code readArray(VariantData * variant, size_t n, TFilter filter, DeserializationOption::NestingLimit nestingLimit) { DeserializationError::Code readArray(
VariantData* variant, size_t n, TFilter filter,
DeserializationOption::NestingLimit nestingLimit) {
DeserializationError::Code err; DeserializationError::Code err;
if (nestingLimit.reached()) if (nestingLimit.reached())
@@ -425,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 {
@@ -441,7 +451,9 @@ class MsgPackDeserializer {
} }
template <typename TSize, typename TFilter> template <typename TSize, typename TFilter>
DeserializationError::Code readObject(VariantData * variant, TFilter filter, DeserializationOption::NestingLimit nestingLimit) { DeserializationError::Code readObject(
VariantData* variant, TFilter filter,
DeserializationOption::NestingLimit nestingLimit) {
DeserializationError::Code err; DeserializationError::Code err;
TSize size; TSize size;
@@ -453,7 +465,9 @@ class MsgPackDeserializer {
} }
template <typename TFilter> template <typename TFilter>
DeserializationError::Code readObject(VariantData * variant, size_t n, TFilter filter, DeserializationOption::NestingLimit nestingLimit) { DeserializationError::Code readObject(
VariantData* variant, size_t n, TFilter filter,
DeserializationOption::NestingLimit nestingLimit) {
DeserializationError::Code err; DeserializationError::Code err;
if (nestingLimit.reached()) if (nestingLimit.reached())
@@ -472,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;
@@ -481,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;
@@ -540,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
@@ -561,9 +575,11 @@ DeserializationError deserializeMsgPack(JsonDocument & doc, Args &&... args) {
// Parses a MessagePack input and puts the result in a JsonDocument. // Parses a MessagePack input and puts the result in a JsonDocument.
// https://arduinojson.org/v6/api/msgpack/deserializemsgpack/ // https://arduinojson.org/v6/api/msgpack/deserializemsgpack/
template <typename TChar, typename... Args> template <typename TChar, typename... Args>
DeserializationError deserializeMsgPack(JsonDocument & doc, TChar * input, Args &&... args) { DeserializationError deserializeMsgPack(JsonDocument& doc, TChar* input,
Args&&... args) {
using namespace detail; using namespace detail;
return deserialize<MsgPackDeserializer>(doc, input, detail::forward<Args>(args)...); return deserialize<MsgPackDeserializer>(doc, input,
detail::forward<Args>(args)...);
} }
ARDUINOJSON_END_PUBLIC_NAMESPACE ARDUINOJSON_END_PUBLIC_NAMESPACE

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,7 +4,13 @@
#pragma once #pragma once
#ifdef ARDUINO
# include <Arduino.h> # 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>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -20,12 +20,11 @@ template <typename T, typename Enable = void>
struct Comparer; struct Comparer;
template <typename T> template <typename T>
struct Comparer<T, typename enable_if<IsString<T>::value>::type> : ComparerBase { struct Comparer<T, typename enable_if<IsString<T>::value>::type>
T rhs; : ComparerBase {
T rhs; // TODO: store adapted string?
explicit Comparer(T value) explicit Comparer(T value) : rhs(value) {}
: rhs(value) {
}
CompareResult visitString(const char* lhs, size_t n) { CompareResult visitString(const char* lhs, size_t n) {
int i = stringCompare(adaptString(rhs), adaptString(lhs, n)); int i = stringCompare(adaptString(rhs), adaptString(lhs, n));
@@ -46,12 +45,12 @@ struct Comparer<T, typename enable_if<IsString<T>::value>::type> : ComparerBase
}; };
template <typename T> template <typename T>
struct Comparer<T, typename enable_if<is_integral<T>::value || is_floating_point<T>::value>::type> : ComparerBase { struct Comparer<T, typename enable_if<is_integral<T>::value ||
is_floating_point<T>::value>::type>
: ComparerBase {
T rhs; T rhs;
explicit Comparer(T value) explicit Comparer(T value) : rhs(value) {}
: rhs(value) {
}
CompareResult visitFloat(JsonFloat lhs) { CompareResult visitFloat(JsonFloat lhs) {
return arithmeticCompare(lhs, rhs); return arithmeticCompare(lhs, rhs);
@@ -78,20 +77,16 @@ struct NullComparer : ComparerBase {
template <> template <>
struct Comparer<decltype(nullptr), void> : NullComparer { struct Comparer<decltype(nullptr), void> : NullComparer {
explicit Comparer(decltype(nullptr)) explicit Comparer(decltype(nullptr)) : NullComparer() {}
: NullComparer() {
}
}; };
struct ArrayComparer : ComparerBase { struct ArrayComparer : ComparerBase {
const CollectionData * _rhs; const CollectionData* rhs_;
explicit ArrayComparer(const CollectionData & rhs) explicit ArrayComparer(const CollectionData& rhs) : rhs_(&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;
@@ -99,14 +94,12 @@ struct ArrayComparer : ComparerBase {
}; };
struct ObjectComparer : ComparerBase { struct ObjectComparer : ComparerBase {
const CollectionData * _rhs; const CollectionData* rhs_;
explicit ObjectComparer(const CollectionData & rhs) explicit ObjectComparer(const CollectionData& rhs) : rhs_(&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;
@@ -114,17 +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) : rhsData_(rhsData), rhsSize_(rhsSize) {}
, _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)
@@ -137,9 +128,7 @@ struct RawComparer : ComparerBase {
struct VariantComparer : ComparerBase { struct VariantComparer : ComparerBase {
const VariantData* rhs; const VariantData* rhs;
explicit VariantComparer(const VariantData * value) explicit VariantComparer(const VariantData* value) : rhs(value) {}
: rhs(value) {
}
CompareResult visitArray(const CollectionData& lhs) { CompareResult visitArray(const CollectionData& lhs) {
ArrayComparer comparer(lhs); ArrayComparer comparer(lhs);
@@ -202,10 +191,11 @@ struct VariantComparer : ComparerBase {
}; };
template <typename T> template <typename T>
struct Comparer<T, typename enable_if<is_convertible<T, ArduinoJson::JsonVariantConst>::value>::type> : VariantComparer { struct Comparer<T, typename enable_if<is_convertible<
T, ArduinoJson::JsonVariantConst>::value>::type>
: VariantComparer {
explicit Comparer(const T& value) explicit Comparer(const T& value)
: VariantComparer(VariantAttorney::getData(value)) { : VariantComparer(VariantAttorney::getData(value)) {}
}
}; };
template <typename T> template <typename T>

View File

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

View File

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

View File

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

View File

@@ -4,7 +4,7 @@
#pragma once #pragma once
#define ARDUINOJSON_VERSION "6.21.0" #define ARDUINOJSON_VERSION "6.21.2"
#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 2

View File

@@ -0,0 +1,91 @@
# ArduinoJson - https://arduinojson.org
# Copyright © 2014-2023, Benoit BLANCHON
# MIT License
# I have no idea what this is about, I simply followed the instructions from:
# https://dominikberner.ch/cmake-interface-lib/
add_library(ArduinoJson INTERFACE)
include(GNUInstallDirs)
# Adding the install interface generator expression makes sure that the include
# files are installed to the proper location (provided by GNUInstallDirs)
target_include_directories(ArduinoJson
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_definitions(ArduinoJson
INTERFACE
ARDUINOJSON_DEBUG=$<CONFIG:Debug>
)
# locations are provided by GNUInstallDirs
install(
TARGETS
ArduinoJson
EXPORT
ArduinoJson_Targets
ARCHIVE DESTINATION
${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION
${CMAKE_INSTALL_BINDIR}
)
include(CMakePackageConfigHelpers)
if(${CMAKE_VERSION} VERSION_GREATER "3.14.0")
set(ARCH_INDEPENDENT "ARCH_INDEPENDENT")
endif()
write_basic_package_version_file(
"${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake"
VERSION
${PROJECT_VERSION}
COMPATIBILITY
SameMajorVersion
${ARCH_INDEPENDENT}
)
configure_package_config_file(
"${PROJECT_SOURCE_DIR}/extras/ArduinoJsonConfig.cmake.in"
"${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake"
INSTALL_DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake
)
install(
EXPORT
ArduinoJson_Targets
FILE
ArduinoJsonTargets.cmake
DESTINATION
${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake
)
install(
FILES
"${PROJECT_BINARY_DIR}/ArduinoJsonConfig.cmake"
"${PROJECT_BINARY_DIR}/ArduinoJsonConfigVersion.cmake"
DESTINATION
"${CMAKE_INSTALL_DATAROOTDIR}/ArduinoJson/cmake"
)
install(
FILES
ArduinoJson.h
ArduinoJson.hpp
DESTINATION
include
)
install(
DIRECTORY
"${CMAKE_CURRENT_SOURCE_DIR}/ArduinoJson"
DESTINATION
include
)