mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
local libs
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#include "src/ArduinoJson.h"
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#include "src/ArduinoJson.h"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,10 @@
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright © 2014-2020 Benoit BLANCHON
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright © 2014-2020 Benoit BLANCHON
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,137 +1,137 @@
|
||||

|
||||
|
||||
---
|
||||
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.15.0)
|
||||
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
[](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
[](https://github.com/bblanchon/ArduinoJson/stargazers)
|
||||
|
||||
ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
||||
|
||||
## Features
|
||||
|
||||
* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally filters the input to keep only desired values](https://arduinojson.org/v6/api/json/deserializejson/#filtering?utm_source=github&utm_medium=readme)
|
||||
* Supports single quotes as a string delimiter
|
||||
* Compatible with NDJSON and JSON Lines
|
||||
* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/?utm_source=github&utm_medium=readme)
|
||||
* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/?utm_source=github&utm_medium=readme)
|
||||
* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/?utm_source=github&utm_medium=readme)
|
||||
* Efficient
|
||||
* [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/?utm_source=github&utm_medium=readme)
|
||||
* Versatile
|
||||
* [Supports custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
|
||||
* Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme)
|
||||
* Supports Arduino's `Stream` and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
|
||||
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
|
||||
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/#custom-writer?utm_source=github&utm_medium=readme)
|
||||
* Portable
|
||||
* Usable on any C++ project (not limited to Arduino)
|
||||
* Compatible with C++98
|
||||
* 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)...
|
||||
* 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)
|
||||
* [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/t7KP7I6dVuLhqzDl)
|
||||
* Well designed
|
||||
* [Elegant API](http://127.0.0.1:4000/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/?utm_source=github&utm_medium=readme)
|
||||
* [TMP friendly](https://en.wikipedia.org/wiki/Template_metaprogramming)
|
||||
* Handles [integer overflows](https://arduinojson.org/v6/api/jsonvariant/as/#integer-overflows?utm_source=github&utm_medium=readme)
|
||||
* Well tested
|
||||
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
* Continuously tested on
|
||||
* [Visual Studio 2010, 2012, 2013, 2015, 2017, 2019](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||
* [GCC 4.4, 4.6, 4.7, 4.8, 4.9, 5, 6, 7, 8](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
* [Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7, 8](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
* Well documented
|
||||
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/?utm_source=github&utm_medium=readme)
|
||||
* [Examples](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme)
|
||||
* [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme)
|
||||
* Vibrant user community
|
||||
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories) and [PlatformIO](https://platformio.org/lib/search)
|
||||
* [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/doc/decoding/?utm_source=github&utm_medium=readme)
|
||||
|
||||
### Serialization
|
||||
|
||||
Here is a program that generates a JSON document with ArduinoJson:
|
||||
|
||||
```c++
|
||||
DynamicJsonDocument doc(1024);
|
||||
|
||||
doc["sensor"] = "gps";
|
||||
doc["time"] = 1351824120;
|
||||
|
||||
JsonArray data = doc.createNestedArray("data");
|
||||
data.add(48.756080);
|
||||
data.add(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/doc/encoding/?utm_source=github&utm_medium=readme)
|
||||
|
||||
## Support the project
|
||||
|
||||
Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)!
|
||||
|
||||
What? You don't like it but you *love* it?
|
||||
We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time?utm_source=github&utm_medium=readme!
|
||||

|
||||
|
||||
---
|
||||
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.16.1)
|
||||
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
[](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
[](https://github.com/bblanchon/ArduinoJson/stargazers)
|
||||
|
||||
ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
|
||||
|
||||
## Features
|
||||
|
||||
* [JSON deserialization](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally decodes UTF-16 escape sequences to UTF-8](https://arduinojson.org/v6/api/config/decode_unicode/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally stores links to the input buffer (zero-copy)](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally supports comments in the input](https://arduinojson.org/v6/api/config/enable_comments/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally filters the input to keep only desired values](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#filtering)
|
||||
* Supports single quotes as a string delimiter
|
||||
* Compatible with NDJSON and JSON Lines
|
||||
* [JSON serialization](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Can write to a buffer or a stream](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally indents the document (prettified JSON)](https://arduinojson.org/v6/api/json/serializejsonpretty/?utm_source=github&utm_medium=readme)
|
||||
* [MessagePack serialization](https://arduinojson.org/v6/api/msgpack/serializemsgpack/?utm_source=github&utm_medium=readme)
|
||||
* [MessagePack deserialization](https://arduinojson.org/v6/api/msgpack/deserializemsgpack/?utm_source=github&utm_medium=readme)
|
||||
* Efficient
|
||||
* [Twice smaller than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Almost 10% faster than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Consumes roughly 10% less RAM than the "official" Arduino_JSON library](https://arduinojson.org/2019/11/19/arduinojson-vs-arduino_json/?utm_source=github&utm_medium=readme)
|
||||
* [Fixed memory allocation, no heap fragmentation](https://arduinojson.org/v6/api/jsondocument/?utm_source=github&utm_medium=readme)
|
||||
* [Optionally works without heap memory (zero malloc)](https://arduinojson.org/v6/api/staticjsondocument/?utm_source=github&utm_medium=readme)
|
||||
* Deduplicates strings
|
||||
* Versatile
|
||||
* [Supports custom allocators (to use external RAM chip, for example)](https://arduinojson.org/v6/how-to/use-external-ram-on-esp32/?utm_source=github&utm_medium=readme)
|
||||
* Supports [Arduino's `String`](https://arduinojson.org/v6/api/config/enable_arduino_string/) and [STL's `std::string`](https://arduinojson.org/v6/api/config/enable_std_string/?utm_source=github&utm_medium=readme)
|
||||
* Supports Arduino's `Stream` and [STL's `std::istream`/`std::ostream`](https://arduinojson.org/v6/api/config/enable_std_stream/?utm_source=github&utm_medium=readme)
|
||||
* [Supports Flash strings](https://arduinojson.org/v6/api/config/enable_progmem/?utm_source=github&utm_medium=readme)
|
||||
* Supports [custom readers](https://arduinojson.org/v6/api/json/deserializejson/?utm_source=github&utm_medium=readme#custom-reader) and [custom writers](https://arduinojson.org/v6/api/json/serializejson/?utm_source=github&utm_medium=readme#custom-writer)
|
||||
* Portable
|
||||
* Usable on any C++ project (not limited to Arduino)
|
||||
* Compatible with C++98
|
||||
* 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)...
|
||||
* 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)
|
||||
* [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/t7KP7I6dVuLhqzDl)
|
||||
* [CMake friendly](https://arduinojson.org/v6/how-to/use-arduinojson-with-cmake/?utm_source=github&utm_medium=readme)
|
||||
* Well designed
|
||||
* [Elegant API](http://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [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/?utm_source=github&utm_medium=readme)
|
||||
* [TMP friendly](https://en.wikipedia.org/wiki/Template_metaprogramming)
|
||||
* Handles [integer overflows](https://arduinojson.org/v6/api/jsonvariant/as/?utm_source=github&utm_medium=readme#integer-overflows)
|
||||
* Well tested
|
||||
* [Unit test coverage close to 100%](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
* Continuously tested on
|
||||
* [Visual Studio 2010, 2012, 2013, 2015, 2017, 2019](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||
* [GCC 4.4, 4.6, 4.7, 4.8, 4.9, 5, 6, 7, 8](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
* [Clang 3.5, 3.6, 3.7, 3.8, 3.9, 4.0, 5.0, 6.0, 7, 8](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
* [Continuously fuzzed with Google OSS Fuzz](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||
* Well documented
|
||||
* [Tutorials](https://arduinojson.org/v6/doc/deserialization/?utm_source=github&utm_medium=readme)
|
||||
* [Examples](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [How-tos](https://arduinojson.org/v6/example/?utm_source=github&utm_medium=readme)
|
||||
* [FAQ](https://arduinojson.org/v6/faq/?utm_source=github&utm_medium=readme)
|
||||
* [Book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme)
|
||||
* Vibrant user community
|
||||
* Most popular of all Arduino libraries on [GitHub](https://github.com/search?o=desc&q=arduino+library&s=stars&type=Repositories) and [PlatformIO](https://platformio.org/lib/search)
|
||||
* [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/doc/decoding/?utm_source=github&utm_medium=readme)
|
||||
|
||||
### 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/doc/encoding/?utm_source=github&utm_medium=readme)
|
||||
|
||||
## Support the project
|
||||
|
||||
Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)!
|
||||
|
||||
What? You don't like it but you *love* it?
|
||||
We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time.
|
||||
154
lib/ArduinoJson/examples/JsonConfigFile/JsonConfigFile.ino
Normal file
154
lib/ArduinoJson/examples/JsonConfigFile/JsonConfigFile.ino
Normal file
@@ -0,0 +1,154 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to store your project configuration in a file.
|
||||
// It uses the SD library but can be easily modified for any other file-system.
|
||||
//
|
||||
// The file contains a JSON document with the following content:
|
||||
// {
|
||||
// "hostname": "examples.com",
|
||||
// "port": 2731
|
||||
// }
|
||||
//
|
||||
// To run this program, you need an SD card connected to the SPI bus as follows:
|
||||
// * MOSI <-> pin 11
|
||||
// * MISO <-> pin 12
|
||||
// * CLK <-> pin 13
|
||||
// * CS <-> pin 4
|
||||
//
|
||||
// https://arduinojson.org/v6/example/config/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
// Our configuration structure.
|
||||
//
|
||||
// Never use a JsonDocument to store the configuration!
|
||||
// A JsonDocument is *not* a permanent storage; it's only a temporary storage
|
||||
// used during the serialization phase. See:
|
||||
// https://arduinojson.org/v6/faq/why-must-i-create-a-separate-config-object/
|
||||
struct Config {
|
||||
char hostname[64];
|
||||
int port;
|
||||
};
|
||||
|
||||
const char *filename = "/config.txt"; // <- SD library uses 8.3 filenames
|
||||
Config config; // <- global configuration object
|
||||
|
||||
// Loads the configuration from a file
|
||||
void loadConfiguration(const char *filename, Config &config) {
|
||||
// Open file for reading
|
||||
File file = SD.open(filename);
|
||||
|
||||
// Allocate a temporary JsonDocument
|
||||
// Don't forget to change the capacity to match your requirements.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<512> doc;
|
||||
|
||||
// Deserialize the JSON document
|
||||
DeserializationError error = deserializeJson(doc, file);
|
||||
if (error)
|
||||
Serial.println(F("Failed to read file, using default configuration"));
|
||||
|
||||
// Copy values from the JsonDocument to the Config
|
||||
config.port = doc["port"] | 2731;
|
||||
strlcpy(config.hostname, // <- destination
|
||||
doc["hostname"] | "example.com", // <- source
|
||||
sizeof(config.hostname)); // <- destination's capacity
|
||||
|
||||
// Close the file (Curiously, File's destructor doesn't close the file)
|
||||
file.close();
|
||||
}
|
||||
|
||||
// Saves the configuration to a file
|
||||
void saveConfiguration(const char *filename, const Config &config) {
|
||||
// Delete existing file, otherwise the configuration is appended to the file
|
||||
SD.remove(filename);
|
||||
|
||||
// Open file for writing
|
||||
File file = SD.open(filename, FILE_WRITE);
|
||||
if (!file) {
|
||||
Serial.println(F("Failed to create file"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate a temporary JsonDocument
|
||||
// Don't forget to change the capacity to match your requirements.
|
||||
// Use arduinojson.org/assistant to compute the capacity.
|
||||
StaticJsonDocument<256> doc;
|
||||
|
||||
// Set the values in the document
|
||||
doc["hostname"] = config.hostname;
|
||||
doc["port"] = config.port;
|
||||
|
||||
// Serialize JSON to file
|
||||
if (serializeJson(doc, file) == 0) {
|
||||
Serial.println(F("Failed to write to file"));
|
||||
}
|
||||
|
||||
// Close the file
|
||||
file.close();
|
||||
}
|
||||
|
||||
// Prints the content of a file to the Serial
|
||||
void printFile(const char *filename) {
|
||||
// Open file for reading
|
||||
File file = SD.open(filename);
|
||||
if (!file) {
|
||||
Serial.println(F("Failed to read file"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract each characters by one by one
|
||||
while (file.available()) {
|
||||
Serial.print((char)file.read());
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
// Close the file
|
||||
file.close();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
// Initialize serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// Initialize SD library
|
||||
const int chipSelect = 4;
|
||||
while (!SD.begin(chipSelect)) {
|
||||
Serial.println(F("Failed to initialize SD library"));
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// Should load default config if run for the first time
|
||||
Serial.println(F("Loading configuration..."));
|
||||
loadConfiguration(filename, config);
|
||||
|
||||
// Create configuration file
|
||||
Serial.println(F("Saving configuration..."));
|
||||
saveConfiguration(filename, config);
|
||||
|
||||
// Dump config file
|
||||
Serial.println(F("Print config file..."));
|
||||
printFile(filename);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any
|
||||
// serialization or deserialization problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a case study of a project that has
|
||||
// a complex configuration with nested members.
|
||||
// Contrary to this example, the project in the book uses the SPIFFS filesystem.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
@@ -0,0 +1,63 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to use DeserializationOpion::Filter
|
||||
//
|
||||
// https://arduinojson.org/v6/example/filter/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void setup() {
|
||||
// Initialize serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// The huge input: an extract from OpenWeatherMap response
|
||||
const __FlashStringHelper* input_json = F(
|
||||
"{\"cod\":\"200\",\"message\":0,\"list\":[{\"dt\":1581498000,\"main\":{"
|
||||
"\"temp\":3.23,\"feels_like\":-3.63,\"temp_min\":3.23,\"temp_max\":4.62,"
|
||||
"\"pressure\":1014,\"sea_level\":1014,\"grnd_level\":1010,\"humidity\":"
|
||||
"58,\"temp_kf\":-1.39},\"weather\":[{\"id\":800,\"main\":\"Clear\","
|
||||
"\"description\":\"clear "
|
||||
"sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":0},\"wind\":{\"speed\":6."
|
||||
"19,\"deg\":266},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 "
|
||||
"09:00:00\"},{\"dt\":1581508800,\"main\":{\"temp\":6.09,\"feels_like\":-"
|
||||
"1.07,\"temp_min\":6.09,\"temp_max\":7.13,\"pressure\":1015,\"sea_"
|
||||
"level\":1015,\"grnd_level\":1011,\"humidity\":48,\"temp_kf\":-1.04},"
|
||||
"\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear "
|
||||
"sky\",\"icon\":\"01d\"}],\"clouds\":{\"all\":9},\"wind\":{\"speed\":6."
|
||||
"64,\"deg\":268},\"sys\":{\"pod\":\"d\"},\"dt_txt\":\"2020-02-12 "
|
||||
"12:00:00\"}],\"city\":{\"id\":2643743,\"name\":\"London\",\"coord\":{"
|
||||
"\"lat\":51.5085,\"lon\":-0.1257},\"country\":\"GB\",\"population\":"
|
||||
"1000000,\"timezone\":0,\"sunrise\":1581492085,\"sunset\":1581527294}}");
|
||||
|
||||
// The filter: it contains "true" for each value we want to keep
|
||||
StaticJsonDocument<200> filter;
|
||||
filter["list"][0]["dt"] = true;
|
||||
filter["list"][0]["main"]["temp"] = true;
|
||||
|
||||
// Deserialize the document
|
||||
StaticJsonDocument<400> doc;
|
||||
deserializeJson(doc, input_json, DeserializationOption::Filter(filter));
|
||||
|
||||
// Print the result
|
||||
serializeJsonPretty(doc, Serial);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any
|
||||
// deserialization problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a tutorial on deserialization.
|
||||
// It begins with a simple example, like the one above, and then adds more
|
||||
// features like deserializing directly from a file or an HTTP request.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
@@ -1,60 +1,77 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to generate a JSON document with ArduinoJson.
|
||||
|
||||
#include <iostream>
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
int main() {
|
||||
// Allocate the JSON document
|
||||
//
|
||||
// Inside the brackets, 200 is the RAM allocated to this document.
|
||||
// Don't forget to change this value to match your requirement.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<200> doc;
|
||||
|
||||
// StaticJsonObject allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonDocument which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// StaticJsonObject allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonDocument which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// Add values in the document
|
||||
//
|
||||
doc["sensor"] = "gps";
|
||||
doc["time"] = 1351824120;
|
||||
|
||||
// Add an array.
|
||||
//
|
||||
JsonArray data = doc.createNestedArray("data");
|
||||
data.add(48.756080);
|
||||
data.add(2.302038);
|
||||
|
||||
// Generate the minified JSON and send it to STDOUT
|
||||
//
|
||||
serializeJson(doc, std::cout);
|
||||
// The above line prints:
|
||||
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
|
||||
// Start a new line
|
||||
std::cout << std::endl;
|
||||
|
||||
// Generate the prettified JSON and send it to STDOUT
|
||||
//
|
||||
serializeJsonPretty(doc, std::cout);
|
||||
// The above line prints:
|
||||
// {
|
||||
// "sensor": "gps",
|
||||
// "time": 1351824120,
|
||||
// "data": [
|
||||
// 48.756080,
|
||||
// 2.302038
|
||||
// ]
|
||||
// }
|
||||
}
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to generate a JSON document with ArduinoJson.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/generator/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void setup() {
|
||||
// Initialize Serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// Allocate the JSON document
|
||||
//
|
||||
// Inside the brackets, 200 is the RAM allocated to this document.
|
||||
// Don't forget to change this value to match your requirement.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<200> doc;
|
||||
|
||||
// StaticJsonObject allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonDocument which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// Add values in the document
|
||||
//
|
||||
doc["sensor"] = "gps";
|
||||
doc["time"] = 1351824120;
|
||||
|
||||
// Add an array.
|
||||
//
|
||||
JsonArray data = doc.createNestedArray("data");
|
||||
data.add(48.756080);
|
||||
data.add(2.302038);
|
||||
|
||||
// Generate the minified JSON and send it to the Serial port.
|
||||
//
|
||||
serializeJson(doc, Serial);
|
||||
// The above line prints:
|
||||
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
|
||||
// Start a new line
|
||||
Serial.println();
|
||||
|
||||
// Generate the prettified JSON and send it to the Serial port.
|
||||
//
|
||||
serializeJsonPretty(doc, Serial);
|
||||
// The above line prints:
|
||||
// {
|
||||
// "sensor": "gps",
|
||||
// "time": 1351824120,
|
||||
// "data": [
|
||||
// 48.756080,
|
||||
// 2.302038
|
||||
// ]
|
||||
// }
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any
|
||||
// serialization problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
|
||||
// It begins with a simple example, like the one above, and then adds more
|
||||
// features like serializing directly to a file or an HTTP request.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
116
lib/ArduinoJson/examples/JsonHttpClient/JsonHttpClient.ino
Normal file
116
lib/ArduinoJson/examples/JsonHttpClient/JsonHttpClient.ino
Normal file
@@ -0,0 +1,116 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to parse a JSON document in an HTTP response.
|
||||
// It uses the Ethernet library, but can be easily adapted for Wifi.
|
||||
//
|
||||
// It performs a GET resquest on arduinojson.org/example.json
|
||||
// Here is the expected response:
|
||||
// {
|
||||
// "sensor": "gps",
|
||||
// "time": 1351824120,
|
||||
// "data": [
|
||||
// 48.756080,
|
||||
// 2.302038
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// https://arduinojson.org/v6/example/http-client/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <Ethernet.h>
|
||||
#include <SPI.h>
|
||||
|
||||
void setup() {
|
||||
// Initialize Serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// Initialize Ethernet library
|
||||
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
if (!Ethernet.begin(mac)) {
|
||||
Serial.println(F("Failed to configure Ethernet"));
|
||||
return;
|
||||
}
|
||||
delay(1000);
|
||||
|
||||
Serial.println(F("Connecting..."));
|
||||
|
||||
// Connect to HTTP server
|
||||
EthernetClient client;
|
||||
client.setTimeout(10000);
|
||||
if (!client.connect("arduinojson.org", 80)) {
|
||||
Serial.println(F("Connection failed"));
|
||||
return;
|
||||
}
|
||||
|
||||
Serial.println(F("Connected!"));
|
||||
|
||||
// Send HTTP request
|
||||
client.println(F("GET /example.json HTTP/1.0"));
|
||||
client.println(F("Host: arduinojson.org"));
|
||||
client.println(F("Connection: close"));
|
||||
if (client.println() == 0) {
|
||||
Serial.println(F("Failed to send request"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check HTTP status
|
||||
char status[32] = {0};
|
||||
client.readBytesUntil('\r', status, sizeof(status));
|
||||
// It should be "HTTP/1.0 200 OK" or "HTTP/1.1 200 OK"
|
||||
if (strcmp(status + 9, "200 OK") != 0) {
|
||||
Serial.print(F("Unexpected response: "));
|
||||
Serial.println(status);
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip HTTP headers
|
||||
char endOfHeaders[] = "\r\n\r\n";
|
||||
if (!client.find(endOfHeaders)) {
|
||||
Serial.println(F("Invalid response"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate the JSON document
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
|
||||
DynamicJsonDocument doc(capacity);
|
||||
|
||||
// Parse JSON object
|
||||
DeserializationError error = deserializeJson(doc, client);
|
||||
if (error) {
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract values
|
||||
Serial.println(F("Response:"));
|
||||
Serial.println(doc["sensor"].as<char*>());
|
||||
Serial.println(doc["time"].as<long>());
|
||||
Serial.println(doc["data"][0].as<float>(), 6);
|
||||
Serial.println(doc["data"][1].as<float>(), 6);
|
||||
|
||||
// Disconnect
|
||||
client.stop();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any
|
||||
// serialization problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a tutorial on deserialization
|
||||
// showing how to parse the response from GitHub's API. In the last chapter,
|
||||
// it shows how to parse the huge documents from OpenWeatherMap
|
||||
// and Reddit.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
@@ -1,59 +1,80 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to deserialize a JSON document with ArduinoJson.
|
||||
|
||||
#include <iostream>
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
int main() {
|
||||
// Allocate the JSON document
|
||||
//
|
||||
// Inside the brackets, 200 is the capacity of the memory pool in bytes.
|
||||
// Don't forget to change this value to match your JSON document.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<300> doc;
|
||||
|
||||
// StaticJsonDocument<N> allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonDocument which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// JSON input string.
|
||||
//
|
||||
// Using a char[], as shown here, enables the "zero-copy" mode. This mode uses
|
||||
// the minimal amount of memory because the JsonDocument stores pointers to
|
||||
// the input buffer.
|
||||
// If you use another type of input, ArduinoJson must copy the strings from
|
||||
// the input to the JsonDocument, so you need to increase the capacity of the
|
||||
// JsonDocument.
|
||||
char json[] =
|
||||
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
|
||||
// Deserialize the JSON document
|
||||
DeserializationError error = deserializeJson(doc, json);
|
||||
|
||||
// Test if parsing succeeds.
|
||||
if (error) {
|
||||
std::cerr << "deserializeJson() failed: " << error.c_str() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Fetch values.
|
||||
//
|
||||
// Most of the time, you can rely on the implicit casts.
|
||||
// In other case, you can do doc["time"].as<long>();
|
||||
const char* sensor = doc["sensor"];
|
||||
long time = doc["time"];
|
||||
double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
|
||||
// Print values.
|
||||
std::cout << sensor << std::endl;
|
||||
std::cout << time << std::endl;
|
||||
std::cout << latitude << std::endl;
|
||||
std::cout << longitude << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to deserialize a JSON document with ArduinoJson.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/parser/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void setup() {
|
||||
// Initialize serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// Allocate the JSON document
|
||||
//
|
||||
// Inside the brackets, 200 is the capacity of the memory pool in bytes.
|
||||
// Don't forget to change this value to match your JSON document.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<200> doc;
|
||||
|
||||
// StaticJsonDocument<N> allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonDocument which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// JSON input string.
|
||||
//
|
||||
// Using a char[], as shown here, enables the "zero-copy" mode. This mode uses
|
||||
// the minimal amount of memory because the JsonDocument stores pointers to
|
||||
// the input buffer.
|
||||
// If you use another type of input, ArduinoJson must copy the strings from
|
||||
// the input to the JsonDocument, so you need to increase the capacity of the
|
||||
// JsonDocument.
|
||||
char json[] =
|
||||
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
|
||||
// Deserialize the JSON document
|
||||
DeserializationError error = deserializeJson(doc, json);
|
||||
|
||||
// Test if parsing succeeds.
|
||||
if (error) {
|
||||
Serial.print(F("deserializeJson() failed: "));
|
||||
Serial.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch values.
|
||||
//
|
||||
// Most of the time, you can rely on the implicit casts.
|
||||
// In other case, you can do doc["time"].as<long>();
|
||||
const char* sensor = doc["sensor"];
|
||||
long time = doc["time"];
|
||||
double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
|
||||
// Print values.
|
||||
Serial.println(sensor);
|
||||
Serial.println(time);
|
||||
Serial.println(latitude, 6);
|
||||
Serial.println(longitude, 6);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any
|
||||
// deserialization problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a tutorial on deserialization.
|
||||
// It begins with a simple example, like the one above, and then adds more
|
||||
// features like deserializing directly from a file or an HTTP request.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
110
lib/ArduinoJson/examples/JsonServer/JsonServer.ino
Normal file
110
lib/ArduinoJson/examples/JsonServer/JsonServer.ino
Normal file
@@ -0,0 +1,110 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to implement an HTTP server that sends a JSON document
|
||||
// in the response.
|
||||
// It uses the Ethernet library but can be easily adapted for Wifi.
|
||||
//
|
||||
// The JSON document contains the values of the analog and digital pins.
|
||||
// It looks like that:
|
||||
// {
|
||||
// "analog": [0, 76, 123, 158, 192, 205],
|
||||
// "digital": [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]
|
||||
// }
|
||||
//
|
||||
// https://arduinojson.org/v6/example/http-server/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <Ethernet.h>
|
||||
#include <SPI.h>
|
||||
|
||||
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
EthernetServer server(80);
|
||||
|
||||
void setup() {
|
||||
// Initialize serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// Initialize Ethernet libary
|
||||
if (!Ethernet.begin(mac)) {
|
||||
Serial.println(F("Failed to initialize Ethernet library"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Start to listen
|
||||
server.begin();
|
||||
|
||||
Serial.println(F("Server is ready."));
|
||||
Serial.print(F("Please connect to http://"));
|
||||
Serial.println(Ethernet.localIP());
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Wait for an incomming connection
|
||||
EthernetClient client = server.available();
|
||||
|
||||
// Do we have a client?
|
||||
if (!client) return;
|
||||
|
||||
Serial.println(F("New client"));
|
||||
|
||||
// Read the request (we ignore the content in this example)
|
||||
while (client.available()) client.read();
|
||||
|
||||
// Allocate a temporary JsonDocument
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<500> doc;
|
||||
|
||||
// Create the "analog" array
|
||||
JsonArray analogValues = doc.createNestedArray("analog");
|
||||
for (int pin = 0; pin < 6; pin++) {
|
||||
// Read the analog input
|
||||
int value = analogRead(pin);
|
||||
|
||||
// Add the value at the end of the array
|
||||
analogValues.add(value);
|
||||
}
|
||||
|
||||
// Create the "digital" array
|
||||
JsonArray digitalValues = doc.createNestedArray("digital");
|
||||
for (int pin = 0; pin < 14; pin++) {
|
||||
// Read the digital input
|
||||
int value = digitalRead(pin);
|
||||
|
||||
// Add the value at the end of the array
|
||||
digitalValues.add(value);
|
||||
}
|
||||
|
||||
Serial.print(F("Sending: "));
|
||||
serializeJson(doc, Serial);
|
||||
Serial.println();
|
||||
|
||||
// Write response headers
|
||||
client.println(F("HTTP/1.0 200 OK"));
|
||||
client.println(F("Content-Type: application/json"));
|
||||
client.println(F("Connection: close"));
|
||||
client.print(F("Content-Length: "));
|
||||
client.println(measureJsonPretty(doc));
|
||||
client.println();
|
||||
|
||||
// Write JSON document
|
||||
serializeJsonPretty(doc, client);
|
||||
|
||||
// Disconnect
|
||||
client.stop();
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any
|
||||
// serialization problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
|
||||
// It begins with a simple example, then adds more features like serializing
|
||||
// directly to a file or an HTTP client.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
100
lib/ArduinoJson/examples/JsonUdpBeacon/JsonUdpBeacon.ino
Normal file
100
lib/ArduinoJson/examples/JsonUdpBeacon/JsonUdpBeacon.ino
Normal file
@@ -0,0 +1,100 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to send a JSON document to a UDP socket.
|
||||
// At regular interval, it sends a UDP packet that contains the status of
|
||||
// analog and digital pins.
|
||||
// It looks like that:
|
||||
// {
|
||||
// "analog": [0, 76, 123, 158, 192, 205],
|
||||
// "digital": [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]
|
||||
// }
|
||||
//
|
||||
// If you want to test this program, you need to be able to receive the UDP
|
||||
// packets.
|
||||
// For example, you can run netcat on your computer
|
||||
// $ ncat -ulp 8888
|
||||
// See https://nmap.org/ncat/
|
||||
//
|
||||
// https://arduinojson.org/v6/example/udp-beacon/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <Ethernet.h>
|
||||
#include <SPI.h>
|
||||
|
||||
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
IPAddress remoteIp(192, 168, 0, 108); // <- EDIT!!!!
|
||||
unsigned short remotePort = 8888;
|
||||
unsigned short localPort = 8888;
|
||||
EthernetUDP udp;
|
||||
|
||||
void setup() {
|
||||
// Initialize serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// Initialize Ethernet libary
|
||||
if (!Ethernet.begin(mac)) {
|
||||
Serial.println(F("Failed to initialize Ethernet library"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Enable UDP
|
||||
udp.begin(localPort);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// Allocate a temporary JsonDocument
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<500> doc;
|
||||
|
||||
// Create the "analog" array
|
||||
JsonArray analogValues = doc.createNestedArray("analog");
|
||||
for (int pin = 0; pin < 6; pin++) {
|
||||
// Read the analog input
|
||||
int value = analogRead(pin);
|
||||
|
||||
// Add the value at the end of the array
|
||||
analogValues.add(value);
|
||||
}
|
||||
|
||||
// Create the "digital" array
|
||||
JsonArray digitalValues = doc.createNestedArray("digital");
|
||||
for (int pin = 0; pin < 14; pin++) {
|
||||
// Read the digital input
|
||||
int value = digitalRead(pin);
|
||||
|
||||
// Add the value at the end of the array
|
||||
digitalValues.add(value);
|
||||
}
|
||||
|
||||
// Log
|
||||
Serial.print(F("Sending to "));
|
||||
Serial.print(remoteIp);
|
||||
Serial.print(F(" on port "));
|
||||
Serial.println(remotePort);
|
||||
serializeJson(doc, Serial);
|
||||
|
||||
// Send UDP packet
|
||||
udp.beginPacket(remoteIp, remotePort);
|
||||
serializeJson(doc, udp);
|
||||
udp.println();
|
||||
udp.endPacket();
|
||||
|
||||
// Wait
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any
|
||||
// serialization problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
|
||||
// It begins with a simple example, then adds more features like serializing
|
||||
// directly to a file or any stream.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
@@ -1,68 +1,75 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to generate a JSON document with ArduinoJson.
|
||||
|
||||
#include <iostream>
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
int main() {
|
||||
// Allocate the JSON document
|
||||
//
|
||||
// Inside the brackets, 300 is the size of the memory pool in bytes.
|
||||
// Don't forget to change this value to match your JSON document.
|
||||
// Use arduinojson.org/assistant to compute the capacity.
|
||||
StaticJsonDocument<300> doc;
|
||||
|
||||
// StaticJsonObject allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonObject which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonObject doc(200);
|
||||
|
||||
// MessagePack input string.
|
||||
//
|
||||
// It's better to use a char[] as shown here.
|
||||
// If you use a const char* or a String, ArduinoJson will
|
||||
// have to make a copy of the input in the JsonBuffer.
|
||||
uint8_t input[] = {131, 166, 115, 101, 110, 115, 111, 114, 163, 103, 112, 115,
|
||||
164, 116, 105, 109, 101, 206, 80, 147, 50, 248, 164, 100,
|
||||
97, 116, 97, 146, 203, 64, 72, 96, 199, 58, 188, 148,
|
||||
112, 203, 64, 2, 106, 146, 230, 33, 49, 169};
|
||||
// This MessagePack document contains:
|
||||
// {
|
||||
// "sensor": "gps",
|
||||
// "time": 1351824120,
|
||||
// "data": [48.75608, 2.302038]
|
||||
// }
|
||||
|
||||
// doc of the object tree.
|
||||
//
|
||||
// It's a reference to the JsonObject, the actual bytes are inside the
|
||||
// JsonBuffer with all the other nodes of the object tree.
|
||||
// Memory is freed when jsonBuffer goes out of scope.
|
||||
DeserializationError error = deserializeMsgPack(doc, input);
|
||||
|
||||
// Test if parsing succeeds.
|
||||
if (error) {
|
||||
std::cerr << "deserializeMsgPack() failed: " << error.c_str() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Fetch values.
|
||||
//
|
||||
// Most of the time, you can rely on the implicit casts.
|
||||
// In other case, you can do doc["time"].as<long>();
|
||||
const char* sensor = doc["sensor"];
|
||||
long time = doc["time"];
|
||||
double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
|
||||
// Print values.
|
||||
std::cout << sensor << std::endl;
|
||||
std::cout << time << std::endl;
|
||||
std::cout << latitude << std::endl;
|
||||
std::cout << longitude << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to deserialize a MessagePack document with
|
||||
// ArduinoJson.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/msgpack-parser/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void setup() {
|
||||
// Initialize serial port
|
||||
Serial.begin(9600);
|
||||
while (!Serial) continue;
|
||||
|
||||
// Allocate the JSON document
|
||||
//
|
||||
// Inside the brackets, 200 is the capacity of the memory pool in bytes.
|
||||
// Don't forget to change this value to match your JSON document.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<200> doc;
|
||||
|
||||
// StaticJsonObject allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonObject which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonObject doc(200);
|
||||
|
||||
// MessagePack input string.
|
||||
//
|
||||
// Using a char[], as shown here, enables the "zero-copy" mode. This mode uses
|
||||
// the minimal amount of memory because the JsonDocument stores pointers to
|
||||
// the input buffer.
|
||||
// If you use another type of input, ArduinoJson must copy the strings from
|
||||
// the input to the JsonDocument, so you need to increase the capacity of the
|
||||
// JsonDocument.
|
||||
uint8_t input[] = {131, 166, 115, 101, 110, 115, 111, 114, 163, 103, 112, 115,
|
||||
164, 116, 105, 109, 101, 206, 80, 147, 50, 248, 164, 100,
|
||||
97, 116, 97, 146, 203, 64, 72, 96, 199, 58, 188, 148,
|
||||
112, 203, 64, 2, 106, 146, 230, 33, 49, 169};
|
||||
// This MessagePack document contains:
|
||||
// {
|
||||
// "sensor": "gps",
|
||||
// "time": 1351824120,
|
||||
// "data": [48.75608, 2.302038]
|
||||
// }
|
||||
|
||||
DeserializationError error = deserializeMsgPack(doc, input);
|
||||
|
||||
// Test if parsing succeeded.
|
||||
if (error) {
|
||||
Serial.print("deserializeMsgPack() failed: ");
|
||||
Serial.println(error.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch values.
|
||||
//
|
||||
// Most of the time, you can rely on the implicit casts.
|
||||
// In other case, you can do doc["time"].as<long>();
|
||||
const char* sensor = doc["sensor"];
|
||||
long time = doc["time"];
|
||||
double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
|
||||
// Print values.
|
||||
Serial.println(sensor);
|
||||
Serial.println(time);
|
||||
Serial.println(latitude, 6);
|
||||
Serial.println(longitude, 6);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
72
lib/ArduinoJson/examples/ProgmemExample/ProgmemExample.ino
Normal file
72
lib/ArduinoJson/examples/ProgmemExample/ProgmemExample.ino
Normal file
@@ -0,0 +1,72 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows the different ways you can use Flash strings with
|
||||
// ArduinoJson.
|
||||
//
|
||||
// Use Flash strings sparingly, because ArduinoJson duplicates them in the
|
||||
// JsonDocument. Prefer plain old char*, as they are more efficient in term of
|
||||
// code size, speed, and memory usage.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/progmem/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void setup() {
|
||||
#ifdef PROGMEM // <- check that Flash strings are supported
|
||||
|
||||
DynamicJsonDocument doc(1024);
|
||||
|
||||
// You can use a Flash String as your JSON input.
|
||||
// WARNING: the strings in the input will be duplicated in the JsonDocument.
|
||||
deserializeJson(doc, F("{\"sensor\":\"gps\",\"time\":1351824120,"
|
||||
"\"data\":[48.756080,2.302038]}"));
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
// You can use a Flash String to get an element of a JsonObject
|
||||
// No duplication is done.
|
||||
long time = obj[F("time")];
|
||||
|
||||
// You can use a Flash String to set an element of a JsonObject
|
||||
// WARNING: the content of the Flash String will be duplicated in the
|
||||
// JsonDocument.
|
||||
obj[F("time")] = time;
|
||||
|
||||
// You can set a Flash String to a JsonObject or JsonArray:
|
||||
// WARNING: the content of the Flash String will be duplicated in the
|
||||
// JsonDocument.
|
||||
obj["sensor"] = F("gps");
|
||||
|
||||
// It works with serialized() too:
|
||||
obj["sensor"] = serialized(F("\"gps\""));
|
||||
obj["sensor"] = serialized(F("\xA3gps"), 3);
|
||||
|
||||
// You can compare the content of a JsonVariant to a Flash String
|
||||
if (obj["sensor"] == F("gps")) {
|
||||
// ...
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#warning PROGMEM is not supported on this platform
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any memory
|
||||
// problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a quick C++ course that explains
|
||||
// how your microcontroller stores strings in memory. It also tells why you
|
||||
// should not abuse Flash strings with ArduinoJson.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
77
lib/ArduinoJson/examples/StringExample/StringExample.ino
Normal file
77
lib/ArduinoJson/examples/StringExample/StringExample.ino
Normal file
@@ -0,0 +1,77 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
//
|
||||
// This example shows the different ways you can use String with ArduinoJson.
|
||||
//
|
||||
// Use String objects sparingly, because ArduinoJson duplicates them in the
|
||||
// JsonDocument. Prefer plain old char[], as they are more efficient in term of
|
||||
// code size, speed, and memory usage.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/string/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
void setup() {
|
||||
DynamicJsonDocument doc(1024);
|
||||
|
||||
// You can use a String as your JSON input.
|
||||
// WARNING: the string in the input will be duplicated in the JsonDocument.
|
||||
String input =
|
||||
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
deserializeJson(doc, input);
|
||||
JsonObject obj = doc.as<JsonObject>();
|
||||
|
||||
// You can use a String to get an element of a JsonObject
|
||||
// No duplication is done.
|
||||
long time = obj[String("time")];
|
||||
|
||||
// You can use a String to set an element of a JsonObject
|
||||
// WARNING: the content of the String will be duplicated in the JsonDocument.
|
||||
obj[String("time")] = time;
|
||||
|
||||
// You can get a String from a JsonObject or JsonArray:
|
||||
// No duplication is done, at least not in the JsonDocument.
|
||||
String sensor = obj["sensor"];
|
||||
|
||||
// Unfortunately, the following doesn't work (issue #118):
|
||||
// sensor = obj["sensor"]; // <- error "ambiguous overload for 'operator='"
|
||||
// As a workaround, you need to replace by:
|
||||
sensor = obj["sensor"].as<String>();
|
||||
|
||||
// You can set a String to a JsonObject or JsonArray:
|
||||
// WARNING: the content of the String will be duplicated in the JsonDocument.
|
||||
obj["sensor"] = sensor;
|
||||
|
||||
// It works with serialized() too:
|
||||
obj["sensor"] = serialized(sensor);
|
||||
|
||||
// You can also concatenate strings
|
||||
// WARNING: the content of the String will be duplicated in the JsonDocument.
|
||||
obj[String("sen") + "sor"] = String("gp") + "s";
|
||||
|
||||
// You can compare the content of a JsonObject with a String
|
||||
if (obj["sensor"] == sensor) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Lastly, you can print the resulting JSON to a String
|
||||
String output;
|
||||
serializeJson(doc, output);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// See also
|
||||
// --------
|
||||
//
|
||||
// https://arduinojson.org/ contains the documentation for all the functions
|
||||
// used above. It also includes an FAQ that will help you solve any problem.
|
||||
//
|
||||
// The book "Mastering ArduinoJson" contains a quick C++ course that explains
|
||||
// how your microcontroller stores strings in memory. On several occasions, it
|
||||
// shows how you can avoid String in your program.
|
||||
// Learn more at https://arduinojson.org/book/
|
||||
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤
|
||||
@@ -1,39 +1,39 @@
|
||||
# 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
|
||||
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
|
||||
# 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
|
||||
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
|
||||
@@ -1,11 +1,11 @@
|
||||
name=ArduinoJson
|
||||
version=6.15.0
|
||||
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
|
||||
name=ArduinoJson
|
||||
version=6.16.1
|
||||
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
|
||||
@@ -1,17 +1,17 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "ArduinoJson.hpp"
|
||||
|
||||
using namespace ArduinoJson;
|
||||
|
||||
#else
|
||||
|
||||
#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp
|
||||
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "ArduinoJson.hpp"
|
||||
|
||||
using namespace ArduinoJson;
|
||||
|
||||
#else
|
||||
|
||||
#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp
|
||||
|
||||
#endif
|
||||
@@ -1,72 +1,73 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ArduinoJson/Configuration.hpp"
|
||||
|
||||
#if !ARDUINOJSON_DEBUG
|
||||
#ifdef __clang__
|
||||
#pragma clang system_header
|
||||
#elif defined __GNUC__
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ArduinoJson/Array/ArrayRef.hpp"
|
||||
#include "ArduinoJson/Object/ObjectRef.hpp"
|
||||
#include "ArduinoJson/Variant/VariantRef.hpp"
|
||||
|
||||
#include "ArduinoJson/Document/DynamicJsonDocument.hpp"
|
||||
#include "ArduinoJson/Document/StaticJsonDocument.hpp"
|
||||
|
||||
#include "ArduinoJson/Array/ArrayImpl.hpp"
|
||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||
#include "ArduinoJson/Array/Utilities.hpp"
|
||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||
#include "ArduinoJson/Variant/VariantAsImpl.hpp"
|
||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
||||
|
||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||
#include "ArduinoJson/Json/JsonSerializer.hpp"
|
||||
#include "ArduinoJson/Json/PrettyJsonSerializer.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp"
|
||||
|
||||
#include "ArduinoJson/compatibility.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray;
|
||||
typedef ARDUINOJSON_NAMESPACE::Float JsonFloat;
|
||||
typedef ARDUINOJSON_NAMESPACE::Integer JsonInteger;
|
||||
typedef ARDUINOJSON_NAMESPACE::ObjectConstRef JsonObjectConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::ObjectRef JsonObject;
|
||||
typedef ARDUINOJSON_NAMESPACE::Pair JsonPair;
|
||||
typedef ARDUINOJSON_NAMESPACE::PairConst JsonPairConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::String JsonString;
|
||||
typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant;
|
||||
using ARDUINOJSON_NAMESPACE::BasicJsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::copyArray;
|
||||
using ARDUINOJSON_NAMESPACE::DeserializationError;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeJson;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;
|
||||
using ARDUINOJSON_NAMESPACE::DynamicJsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::JsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::measureJson;
|
||||
using ARDUINOJSON_NAMESPACE::serialized;
|
||||
using ARDUINOJSON_NAMESPACE::serializeJson;
|
||||
using ARDUINOJSON_NAMESPACE::serializeJsonPretty;
|
||||
using ARDUINOJSON_NAMESPACE::serializeMsgPack;
|
||||
using ARDUINOJSON_NAMESPACE::StaticJsonDocument;
|
||||
|
||||
namespace DeserializationOption {
|
||||
using ARDUINOJSON_NAMESPACE::Filter;
|
||||
using ARDUINOJSON_NAMESPACE::NestingLimit;
|
||||
} // namespace DeserializationOption
|
||||
} // namespace ArduinoJson
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ArduinoJson/Configuration.hpp"
|
||||
|
||||
#if !ARDUINOJSON_DEBUG
|
||||
#ifdef __clang__
|
||||
#pragma clang system_header
|
||||
#elif defined __GNUC__
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ArduinoJson/Array/ArrayRef.hpp"
|
||||
#include "ArduinoJson/Object/ObjectRef.hpp"
|
||||
#include "ArduinoJson/Variant/VariantRef.hpp"
|
||||
|
||||
#include "ArduinoJson/Document/DynamicJsonDocument.hpp"
|
||||
#include "ArduinoJson/Document/StaticJsonDocument.hpp"
|
||||
|
||||
#include "ArduinoJson/Array/ArrayImpl.hpp"
|
||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||
#include "ArduinoJson/Array/Utilities.hpp"
|
||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||
#include "ArduinoJson/Variant/VariantAsImpl.hpp"
|
||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
||||
|
||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||
#include "ArduinoJson/Json/JsonSerializer.hpp"
|
||||
#include "ArduinoJson/Json/PrettyJsonSerializer.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp"
|
||||
|
||||
#include "ArduinoJson/compatibility.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray;
|
||||
typedef ARDUINOJSON_NAMESPACE::Float JsonFloat;
|
||||
typedef ARDUINOJSON_NAMESPACE::Integer JsonInteger;
|
||||
typedef ARDUINOJSON_NAMESPACE::ObjectConstRef JsonObjectConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::ObjectRef JsonObject;
|
||||
typedef ARDUINOJSON_NAMESPACE::Pair JsonPair;
|
||||
typedef ARDUINOJSON_NAMESPACE::PairConst JsonPairConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::String JsonString;
|
||||
typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant;
|
||||
using ARDUINOJSON_NAMESPACE::BasicJsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::copyArray;
|
||||
using ARDUINOJSON_NAMESPACE::DeserializationError;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeJson;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;
|
||||
using ARDUINOJSON_NAMESPACE::DynamicJsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::JsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::measureJson;
|
||||
using ARDUINOJSON_NAMESPACE::serialized;
|
||||
using ARDUINOJSON_NAMESPACE::serializeJson;
|
||||
using ARDUINOJSON_NAMESPACE::serializeJsonPretty;
|
||||
using ARDUINOJSON_NAMESPACE::serializeMsgPack;
|
||||
using ARDUINOJSON_NAMESPACE::StaticJsonDocument;
|
||||
|
||||
namespace DeserializationOption {
|
||||
using ARDUINOJSON_NAMESPACE::Filter;
|
||||
using ARDUINOJSON_NAMESPACE::NestingLimit;
|
||||
} // namespace DeserializationOption
|
||||
} // namespace ArduinoJson
|
||||
@@ -1,30 +1,30 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
|
||||
return arr ? arr->addElement(pool) : 0;
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
inline void arrayAccept(const CollectionData *arr, Visitor &visitor) {
|
||||
if (arr)
|
||||
visitor.visitArray(*arr);
|
||||
else
|
||||
visitor.visitNull();
|
||||
}
|
||||
|
||||
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||
if (lhs == rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return lhs->equalsArray(*rhs);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
|
||||
return arr ? arr->addElement(pool) : 0;
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
inline void arrayAccept(const CollectionData *arr, Visitor &visitor) {
|
||||
if (arr)
|
||||
visitor.visitArray(*arr);
|
||||
else
|
||||
visitor.visitNull();
|
||||
}
|
||||
|
||||
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||
if (lhs == rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return lhs->equalsArray(*rhs);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,28 +1,28 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TArray>
|
||||
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
|
||||
return impl()->addElement().template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TArray>
|
||||
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
|
||||
return impl()->addElement().template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TArray>
|
||||
inline ElementProxy<TArray> ArrayShortcuts<TArray>::operator[](
|
||||
size_t index) const {
|
||||
return ElementProxy<TArray>(*impl(), index);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TArray>
|
||||
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
|
||||
return impl()->addElement().template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TArray>
|
||||
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
|
||||
return impl()->addElement().template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TArray>
|
||||
inline ElementProxy<TArray> ArrayShortcuts<TArray>::operator[](
|
||||
size_t index) const {
|
||||
return ElementProxy<TArray>(*impl(), index);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,121 +1,121 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class VariantPtr {
|
||||
public:
|
||||
VariantPtr(MemoryPool *pool, VariantData *data) : _variant(pool, data) {}
|
||||
|
||||
VariantRef *operator->() {
|
||||
return &_variant;
|
||||
}
|
||||
|
||||
VariantRef &operator*() {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
private:
|
||||
VariantRef _variant;
|
||||
};
|
||||
|
||||
class ArrayIterator {
|
||||
public:
|
||||
ArrayIterator() : _slot(0) {}
|
||||
explicit ArrayIterator(MemoryPool *pool, VariantSlot *slot)
|
||||
: _pool(pool), _slot(slot) {}
|
||||
|
||||
VariantRef operator*() const {
|
||||
return VariantRef(_pool, _slot->data());
|
||||
}
|
||||
VariantPtr operator->() {
|
||||
return VariantPtr(_pool, _slot->data());
|
||||
}
|
||||
|
||||
bool operator==(const ArrayIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ArrayIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ArrayIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArrayIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool *_pool;
|
||||
VariantSlot *_slot;
|
||||
};
|
||||
|
||||
class VariantConstPtr {
|
||||
public:
|
||||
VariantConstPtr(const VariantData *data) : _variant(data) {}
|
||||
|
||||
VariantConstRef *operator->() {
|
||||
return &_variant;
|
||||
}
|
||||
|
||||
VariantConstRef &operator*() {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
private:
|
||||
VariantConstRef _variant;
|
||||
};
|
||||
|
||||
class ArrayConstRefIterator {
|
||||
public:
|
||||
ArrayConstRefIterator() : _slot(0) {}
|
||||
explicit ArrayConstRefIterator(const VariantSlot *slot) : _slot(slot) {}
|
||||
|
||||
VariantConstRef operator*() const {
|
||||
return VariantConstRef(_slot->data());
|
||||
}
|
||||
VariantConstPtr operator->() {
|
||||
return VariantConstPtr(_slot->data());
|
||||
}
|
||||
|
||||
bool operator==(const ArrayConstRefIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ArrayConstRefIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ArrayConstRefIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArrayConstRefIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
const VariantSlot *_slot;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class VariantPtr {
|
||||
public:
|
||||
VariantPtr(MemoryPool *pool, VariantData *data) : _variant(pool, data) {}
|
||||
|
||||
VariantRef *operator->() {
|
||||
return &_variant;
|
||||
}
|
||||
|
||||
VariantRef &operator*() {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
private:
|
||||
VariantRef _variant;
|
||||
};
|
||||
|
||||
class ArrayIterator {
|
||||
public:
|
||||
ArrayIterator() : _slot(0) {}
|
||||
explicit ArrayIterator(MemoryPool *pool, VariantSlot *slot)
|
||||
: _pool(pool), _slot(slot) {}
|
||||
|
||||
VariantRef operator*() const {
|
||||
return VariantRef(_pool, _slot->data());
|
||||
}
|
||||
VariantPtr operator->() {
|
||||
return VariantPtr(_pool, _slot->data());
|
||||
}
|
||||
|
||||
bool operator==(const ArrayIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ArrayIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ArrayIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArrayIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool *_pool;
|
||||
VariantSlot *_slot;
|
||||
};
|
||||
|
||||
class VariantConstPtr {
|
||||
public:
|
||||
VariantConstPtr(const VariantData *data) : _variant(data) {}
|
||||
|
||||
VariantConstRef *operator->() {
|
||||
return &_variant;
|
||||
}
|
||||
|
||||
VariantConstRef &operator*() {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
private:
|
||||
VariantConstRef _variant;
|
||||
};
|
||||
|
||||
class ArrayConstRefIterator {
|
||||
public:
|
||||
ArrayConstRefIterator() : _slot(0) {}
|
||||
explicit ArrayConstRefIterator(const VariantSlot *slot) : _slot(slot) {}
|
||||
|
||||
VariantConstRef operator*() const {
|
||||
return VariantConstRef(_slot->data());
|
||||
}
|
||||
VariantConstPtr operator->() {
|
||||
return VariantConstPtr(_slot->data());
|
||||
}
|
||||
|
||||
bool operator==(const ArrayConstRefIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ArrayConstRefIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ArrayConstRefIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ArrayConstRefIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
const VariantSlot *_slot;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,167 +1,167 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayFunctions.hpp>
|
||||
#include <ArduinoJson/Array/ArrayIterator.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
// Returns the size (in bytes) of an array with n elements.
|
||||
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
||||
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class ObjectRef;
|
||||
template <typename>
|
||||
class ElementProxy;
|
||||
|
||||
template <typename TData>
|
||||
class ArrayRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
const void* data = _data; // prevent warning cast-align
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
||||
arrayAccept(_data, visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return _data == 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE operator bool() const {
|
||||
return _data != 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t memoryUsage() const {
|
||||
return _data ? _data->memoryUsage() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t nesting() const {
|
||||
return _data ? _data->nesting() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return _data ? _data->size() : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
ArrayRefBase(TData* data) : _data(data) {}
|
||||
TData* _data;
|
||||
};
|
||||
|
||||
class ArrayConstRef : public ArrayRefBase<const CollectionData>,
|
||||
public Visitable {
|
||||
friend class ArrayRef;
|
||||
typedef ArrayRefBase<const CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ArrayConstRefIterator iterator;
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
FORCE_INLINE ArrayConstRef() : base_type(0) {}
|
||||
FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {}
|
||||
|
||||
FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data ? _data->getElement(index) : 0);
|
||||
}
|
||||
};
|
||||
|
||||
class ArrayRef : public ArrayRefBase<CollectionData>,
|
||||
public ArrayShortcuts<ArrayRef>,
|
||||
public Visitable {
|
||||
typedef ArrayRefBase<CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ArrayIterator iterator;
|
||||
|
||||
FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {}
|
||||
FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data)
|
||||
: base_type(data), _pool(pool) {}
|
||||
|
||||
operator VariantRef() {
|
||||
void* data = _data; // prevent warning cast-align
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||
}
|
||||
|
||||
operator ArrayConstRef() const {
|
||||
return ArrayConstRef(_data);
|
||||
}
|
||||
|
||||
VariantRef addElement() const {
|
||||
return VariantRef(_pool, arrayAdd(_data, _pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_pool, _data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
// Copy a ArrayRef
|
||||
FORCE_INLINE bool set(ArrayConstRef src) const {
|
||||
if (!_data || !src._data)
|
||||
return false;
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ArrayRef rhs) const {
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
// Internal use
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
|
||||
}
|
||||
|
||||
// Gets the value at the specified index.
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->getElement(index) : 0);
|
||||
}
|
||||
|
||||
// Removes element at specified position.
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeSlot(it.internal());
|
||||
}
|
||||
|
||||
// Removes element at specified index.
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeElement(index);
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool* _pool;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayFunctions.hpp>
|
||||
#include <ArduinoJson/Array/ArrayIterator.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
// Returns the size (in bytes) of an array with n elements.
|
||||
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
||||
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class ObjectRef;
|
||||
template <typename>
|
||||
class ElementProxy;
|
||||
|
||||
template <typename TData>
|
||||
class ArrayRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
const void* data = _data; // prevent warning cast-align
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
||||
arrayAccept(_data, visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return _data == 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE operator bool() const {
|
||||
return _data != 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t memoryUsage() const {
|
||||
return _data ? _data->memoryUsage() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t nesting() const {
|
||||
return _data ? _data->nesting() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return _data ? _data->size() : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
ArrayRefBase(TData* data) : _data(data) {}
|
||||
TData* _data;
|
||||
};
|
||||
|
||||
class ArrayConstRef : public ArrayRefBase<const CollectionData>,
|
||||
public Visitable {
|
||||
friend class ArrayRef;
|
||||
typedef ArrayRefBase<const CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ArrayConstRefIterator iterator;
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
FORCE_INLINE ArrayConstRef() : base_type(0) {}
|
||||
FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {}
|
||||
|
||||
FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data ? _data->getElement(index) : 0);
|
||||
}
|
||||
};
|
||||
|
||||
class ArrayRef : public ArrayRefBase<CollectionData>,
|
||||
public ArrayShortcuts<ArrayRef>,
|
||||
public Visitable {
|
||||
typedef ArrayRefBase<CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ArrayIterator iterator;
|
||||
|
||||
FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {}
|
||||
FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data)
|
||||
: base_type(data), _pool(pool) {}
|
||||
|
||||
operator VariantRef() {
|
||||
void* data = _data; // prevent warning cast-align
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||
}
|
||||
|
||||
operator ArrayConstRef() const {
|
||||
return ArrayConstRef(_data);
|
||||
}
|
||||
|
||||
VariantRef addElement() const {
|
||||
return VariantRef(_pool, arrayAdd(_data, _pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_pool, _data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
// Copy a ArrayRef
|
||||
FORCE_INLINE bool set(ArrayConstRef src) const {
|
||||
if (!_data || !src._data)
|
||||
return false;
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ArrayRef rhs) const {
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
// Internal use
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
|
||||
}
|
||||
|
||||
// Gets the value at the specified index.
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->getElement(index) : 0);
|
||||
}
|
||||
|
||||
// Removes element at specified position.
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeSlot(it.internal());
|
||||
}
|
||||
|
||||
// Removes element at specified index.
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeElement(index);
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool* _pool;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,47 +1,47 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
// Forward declarations.
|
||||
template <typename>
|
||||
class ElementProxy;
|
||||
|
||||
template <typename TArray>
|
||||
class ArrayShortcuts {
|
||||
public:
|
||||
// Returns the element at specified index if the variant is an array.
|
||||
FORCE_INLINE ElementProxy<TArray> operator[](size_t index) const;
|
||||
|
||||
FORCE_INLINE ObjectRef createNestedObject() const;
|
||||
|
||||
FORCE_INLINE ArrayRef createNestedArray() const;
|
||||
|
||||
// Adds the specified value at the end of the array.
|
||||
//
|
||||
// bool add(TValue);
|
||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||
// std::string, String, ObjectRef
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(const T &value) const {
|
||||
return impl()->addElement().set(value);
|
||||
}
|
||||
//
|
||||
// bool add(TValue);
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(T *value) const {
|
||||
return impl()->addElement().set(value);
|
||||
}
|
||||
|
||||
private:
|
||||
const TArray *impl() const {
|
||||
return static_cast<const TArray *>(this);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
// Forward declarations.
|
||||
template <typename>
|
||||
class ElementProxy;
|
||||
|
||||
template <typename TArray>
|
||||
class ArrayShortcuts {
|
||||
public:
|
||||
// Returns the element at specified index if the variant is an array.
|
||||
FORCE_INLINE ElementProxy<TArray> operator[](size_t index) const;
|
||||
|
||||
FORCE_INLINE ObjectRef createNestedObject() const;
|
||||
|
||||
FORCE_INLINE ArrayRef createNestedArray() const;
|
||||
|
||||
// Adds the specified value at the end of the array.
|
||||
//
|
||||
// bool add(TValue);
|
||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||
// std::string, String, ObjectRef
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(const T &value) const {
|
||||
return impl()->addElement().set(value);
|
||||
}
|
||||
//
|
||||
// bool add(TValue);
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(T *value) const {
|
||||
return impl()->addElement().set(value);
|
||||
}
|
||||
|
||||
private:
|
||||
const TArray *impl() const {
|
||||
return static_cast<const TArray *>(this);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,175 +1,178 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Operators/VariantOperators.hpp>
|
||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4522)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TArray>
|
||||
class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
public Visitable {
|
||||
typedef ElementProxy<TArray> this_type;
|
||||
|
||||
public:
|
||||
FORCE_INLINE ElementProxy(TArray array, size_t index)
|
||||
: _array(array), _index(index) {}
|
||||
|
||||
FORCE_INLINE ElementProxy(const ElementProxy& src)
|
||||
: _array(src._array), _index(src._index) {}
|
||||
|
||||
FORCE_INLINE this_type& operator=(const this_type& src) {
|
||||
getOrAddUpstreamElement().set(src.as<VariantConstRef>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Replaces the value
|
||||
//
|
||||
// operator=(const TValue&)
|
||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(const T& src) {
|
||||
getOrAddUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
//
|
||||
// operator=(TValue)
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(T* src) {
|
||||
getOrAddUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamElement()) == rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator!=(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamElement()) != rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamElement().clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return getUpstreamElement().isNull();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename VariantAs<T>::type as() const {
|
||||
return getUpstreamElement().template as<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE bool is() const {
|
||||
return getUpstreamElement().template is<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename VariantTo<T>::type to() const {
|
||||
return getOrAddUpstreamElement().template to<T>();
|
||||
}
|
||||
|
||||
// Replaces the value
|
||||
//
|
||||
// bool set(const TValue&)
|
||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue& value) const {
|
||||
return getOrAddUpstreamElement().set(value);
|
||||
}
|
||||
//
|
||||
// bool set(TValue)
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(TValue* value) const {
|
||||
return getOrAddUpstreamElement().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor& visitor) const {
|
||||
return getUpstreamElement().accept(visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return getUpstreamElement().size();
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getMember(TNestedKey* key) const {
|
||||
return getUpstreamElement().getMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getMember(const TNestedKey& key) const {
|
||||
return getUpstreamElement().getMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrAddMember(TNestedKey* key) const {
|
||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrAddMember(const TNestedKey& key) const {
|
||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
VariantRef addElement() const {
|
||||
return getOrAddUpstreamElement().addElement();
|
||||
}
|
||||
|
||||
VariantRef getElement(size_t index) const {
|
||||
return getOrAddUpstreamElement().getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
getUpstreamElement().remove(index);
|
||||
}
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||
TChar* key) const {
|
||||
getUpstreamElement().remove(key);
|
||||
}
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString& key) const {
|
||||
getUpstreamElement().remove(key);
|
||||
}
|
||||
|
||||
private:
|
||||
FORCE_INLINE VariantRef getUpstreamElement() const {
|
||||
return _array.getElement(_index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddUpstreamElement() const {
|
||||
return _array.getOrAddElement(_index);
|
||||
}
|
||||
|
||||
TArray _array;
|
||||
const size_t _index;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4522)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TArray>
|
||||
class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
public VariantShortcuts<ElementProxy<TArray> >,
|
||||
public Visitable {
|
||||
typedef ElementProxy<TArray> this_type;
|
||||
|
||||
public:
|
||||
FORCE_INLINE ElementProxy(TArray array, size_t index)
|
||||
: _array(array), _index(index) {}
|
||||
|
||||
FORCE_INLINE ElementProxy(const ElementProxy& src)
|
||||
: _array(src._array), _index(src._index) {}
|
||||
|
||||
FORCE_INLINE this_type& operator=(const this_type& src) {
|
||||
getOrAddUpstreamElement().set(src.as<VariantConstRef>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Replaces the value
|
||||
//
|
||||
// operator=(const TValue&)
|
||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(const T& src) {
|
||||
getOrAddUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
//
|
||||
// operator=(TValue)
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(T* src) {
|
||||
getOrAddUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamElement().clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return getUpstreamElement().isNull();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename VariantAs<T>::type as() const {
|
||||
return getUpstreamElement().template as<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE operator T() const {
|
||||
return getUpstreamElement();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE bool is() const {
|
||||
return getUpstreamElement().template is<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename VariantTo<T>::type to() const {
|
||||
return getOrAddUpstreamElement().template to<T>();
|
||||
}
|
||||
|
||||
// Replaces the value
|
||||
//
|
||||
// bool set(const TValue&)
|
||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue& value) const {
|
||||
return getOrAddUpstreamElement().set(value);
|
||||
}
|
||||
//
|
||||
// bool set(TValue)
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(TValue* value) const {
|
||||
return getOrAddUpstreamElement().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor& visitor) const {
|
||||
return getUpstreamElement().accept(visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return getUpstreamElement().size();
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getMember(TNestedKey* key) const {
|
||||
return getUpstreamElement().getMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getMember(const TNestedKey& key) const {
|
||||
return getUpstreamElement().getMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrAddMember(TNestedKey* key) const {
|
||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrAddMember(const TNestedKey& key) const {
|
||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
VariantRef addElement() const {
|
||||
return getOrAddUpstreamElement().addElement();
|
||||
}
|
||||
|
||||
VariantRef getElement(size_t index) const {
|
||||
return getOrAddUpstreamElement().getElement(index);
|
||||
}
|
||||
|
||||
VariantRef getOrAddElement(size_t index) const {
|
||||
return getOrAddUpstreamElement().getOrAddElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
getUpstreamElement().remove(index);
|
||||
}
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||
TChar* key) const {
|
||||
getUpstreamElement().remove(key);
|
||||
}
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString& key) const {
|
||||
getUpstreamElement().remove(key);
|
||||
}
|
||||
|
||||
private:
|
||||
FORCE_INLINE VariantRef getUpstreamElement() const {
|
||||
return _array.getElement(_index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddUpstreamElement() const {
|
||||
return _array.getOrAddElement(_index);
|
||||
}
|
||||
|
||||
TArray _array;
|
||||
const size_t _index;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
150
lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp
Normal file
150
lib/ArduinoJson/src/ArduinoJson/Array/Utilities.hpp
Normal file
@@ -0,0 +1,150 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Copy a 1D array to a JsonArray
|
||||
template <typename T, size_t N, typename TDestination>
|
||||
inline typename enable_if<!is_array<T>::value &&
|
||||
!is_base_of<JsonDocument, TDestination>::value,
|
||||
bool>::type
|
||||
copyArray(T (&src)[N], const TDestination& dst) {
|
||||
return copyArray(src, N, dst);
|
||||
}
|
||||
|
||||
// Copy a 1D array to a JsonDocument
|
||||
template <typename T, size_t N>
|
||||
inline bool copyArray(T (&src)[N], JsonDocument& dst) {
|
||||
return copyArray(src, dst.to<ArrayRef>());
|
||||
}
|
||||
|
||||
// Copy a 1D array to a JsonArray
|
||||
template <typename T, typename TDestination>
|
||||
inline typename enable_if<!is_array<T>::value &&
|
||||
!is_base_of<JsonDocument, TDestination>::value,
|
||||
bool>::type
|
||||
copyArray(T* src, size_t len, const TDestination& dst) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ok &= dst.add(src[i]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Copy a 1D array to a JsonDocument
|
||||
template <typename T>
|
||||
inline bool copyArray(T* src, size_t len, JsonDocument& dst) {
|
||||
return copyArray(src, len, dst.to<ArrayRef>());
|
||||
}
|
||||
|
||||
// Copy a 2D array to a JsonArray
|
||||
template <typename T, size_t N1, size_t N2, typename TDestination>
|
||||
inline typename enable_if<!is_base_of<JsonDocument, TDestination>::value,
|
||||
bool>::type
|
||||
copyArray(T (&src)[N1][N2], const TDestination& dst) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < N1; i++) {
|
||||
ArrayRef nestedArray = dst.createNestedArray();
|
||||
for (size_t j = 0; j < N2; j++) {
|
||||
ok &= nestedArray.add(src[i][j]);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Copy a 2D array to a JsonDocument
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) {
|
||||
return copyArray(src, dst.to<ArrayRef>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
class ArrayCopier1D {
|
||||
public:
|
||||
ArrayCopier1D(T* destination, size_t capacity)
|
||||
: _destination(destination), _capacity(capacity), _size(0) {}
|
||||
|
||||
void visitArray(const CollectionData& array) {
|
||||
VariantSlot* slot = array.head();
|
||||
|
||||
while (slot != 0 && _size < _capacity) {
|
||||
_destination[_size++] = variantAs<T>(slot->data());
|
||||
slot = slot->next();
|
||||
}
|
||||
}
|
||||
void visitObject(const CollectionData&) {}
|
||||
void visitFloat(Float) {}
|
||||
void visitString(const char*) {}
|
||||
void visitRawJson(const char*, size_t) {}
|
||||
void visitNegativeInteger(UInt) {}
|
||||
void visitPositiveInteger(UInt) {}
|
||||
void visitBoolean(bool) {}
|
||||
void visitNull() {}
|
||||
|
||||
size_t result() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
private:
|
||||
T* _destination;
|
||||
size_t _capacity;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
class ArrayCopier2D {
|
||||
public:
|
||||
ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {}
|
||||
|
||||
void visitArray(const CollectionData& array) {
|
||||
VariantSlot* slot = array.head();
|
||||
size_t n = 0;
|
||||
while (slot != 0 && n < N1) {
|
||||
ArrayCopier1D<T> copier((*_destination)[n++], N2);
|
||||
variantAccept(slot->data(), copier);
|
||||
slot = slot->next();
|
||||
}
|
||||
}
|
||||
void visitObject(const CollectionData&) {}
|
||||
void visitFloat(Float) {}
|
||||
void visitString(const char*) {}
|
||||
void visitRawJson(const char*, size_t) {}
|
||||
void visitNegativeInteger(UInt) {}
|
||||
void visitPositiveInteger(UInt) {}
|
||||
void visitBoolean(bool) {}
|
||||
void visitNull() {}
|
||||
|
||||
private:
|
||||
T (*_destination)[N1][N2];
|
||||
size_t _capacity1, _capacity2;
|
||||
};
|
||||
|
||||
// Copy a JsonArray to a 1D array
|
||||
template <typename TSource, typename T, size_t N>
|
||||
inline typename enable_if<!is_array<T>::value, size_t>::type copyArray(
|
||||
const TSource& src, T (&dst)[N]) {
|
||||
return copyArray(src, dst, N);
|
||||
}
|
||||
|
||||
// Copy a JsonArray to a 1D array
|
||||
template <typename TSource, typename T>
|
||||
inline size_t copyArray(const TSource& src, T* dst, size_t len) {
|
||||
ArrayCopier1D<T> copier(dst, len);
|
||||
src.accept(copier);
|
||||
return copier.result();
|
||||
}
|
||||
|
||||
// Copy a JsonArray to a 2D array
|
||||
template <typename TSource, typename T, size_t N1, size_t N2>
|
||||
inline void copyArray(const TSource& src, T (&dst)[N1][N2]) {
|
||||
ArrayCopier2D<T, N1, N2> copier(&dst);
|
||||
src.accept(copier);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,88 +1,88 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class MemoryPool;
|
||||
class VariantData;
|
||||
class VariantSlot;
|
||||
|
||||
class CollectionData {
|
||||
VariantSlot *_head;
|
||||
VariantSlot *_tail;
|
||||
|
||||
public:
|
||||
// Must be a POD!
|
||||
// - no constructor
|
||||
// - no destructor
|
||||
// - no virtual
|
||||
// - no inheritance
|
||||
|
||||
// Array only
|
||||
|
||||
VariantData *addElement(MemoryPool *pool);
|
||||
|
||||
VariantData *getElement(size_t index) const;
|
||||
|
||||
VariantData *getOrAddElement(size_t index, MemoryPool *pool);
|
||||
|
||||
void removeElement(size_t index);
|
||||
|
||||
bool equalsArray(const CollectionData &other) const;
|
||||
|
||||
// Object only
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *addMember(TAdaptedString key, MemoryPool *pool);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getMember(TAdaptedString key) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key) {
|
||||
removeSlot(getSlot(key));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
bool containsKey(const TAdaptedString &key) const;
|
||||
|
||||
bool equalsObject(const CollectionData &other) const;
|
||||
|
||||
// Generic
|
||||
|
||||
void clear();
|
||||
size_t memoryUsage() const;
|
||||
size_t nesting() const;
|
||||
size_t size() const;
|
||||
|
||||
VariantSlot *addSlot(MemoryPool *);
|
||||
void removeSlot(VariantSlot *slot);
|
||||
|
||||
bool copyFrom(const CollectionData &src, MemoryPool *pool);
|
||||
|
||||
VariantSlot *head() const {
|
||||
return _head;
|
||||
}
|
||||
|
||||
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance);
|
||||
|
||||
private:
|
||||
VariantSlot *getSlot(size_t index) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantSlot *getSlot(TAdaptedString key) const;
|
||||
|
||||
VariantSlot *getPreviousSlot(VariantSlot *) const;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class MemoryPool;
|
||||
class VariantData;
|
||||
class VariantSlot;
|
||||
|
||||
class CollectionData {
|
||||
VariantSlot *_head;
|
||||
VariantSlot *_tail;
|
||||
|
||||
public:
|
||||
// Must be a POD!
|
||||
// - no constructor
|
||||
// - no destructor
|
||||
// - no virtual
|
||||
// - no inheritance
|
||||
|
||||
// Array only
|
||||
|
||||
VariantData *addElement(MemoryPool *pool);
|
||||
|
||||
VariantData *getElement(size_t index) const;
|
||||
|
||||
VariantData *getOrAddElement(size_t index, MemoryPool *pool);
|
||||
|
||||
void removeElement(size_t index);
|
||||
|
||||
bool equalsArray(const CollectionData &other) const;
|
||||
|
||||
// Object only
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *addMember(TAdaptedString key, MemoryPool *pool);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getMember(TAdaptedString key) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool);
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void removeMember(TAdaptedString key) {
|
||||
removeSlot(getSlot(key));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
bool containsKey(const TAdaptedString &key) const;
|
||||
|
||||
bool equalsObject(const CollectionData &other) const;
|
||||
|
||||
// Generic
|
||||
|
||||
void clear();
|
||||
size_t memoryUsage() const;
|
||||
size_t nesting() const;
|
||||
size_t size() const;
|
||||
|
||||
VariantSlot *addSlot(MemoryPool *);
|
||||
void removeSlot(VariantSlot *slot);
|
||||
|
||||
bool copyFrom(const CollectionData &src, MemoryPool *pool);
|
||||
|
||||
VariantSlot *head() const {
|
||||
return _head;
|
||||
}
|
||||
|
||||
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance);
|
||||
|
||||
private:
|
||||
VariantSlot *getSlot(size_t index) const;
|
||||
|
||||
template <typename TAdaptedString>
|
||||
VariantSlot *getSlot(TAdaptedString key) const;
|
||||
|
||||
VariantSlot *getPreviousSlot(VariantSlot *) const;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,228 +1,232 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
|
||||
VariantSlot* slot = pool->allocVariant();
|
||||
if (!slot)
|
||||
return 0;
|
||||
|
||||
if (_tail) {
|
||||
_tail->setNextNotNull(slot);
|
||||
_tail = slot;
|
||||
} else {
|
||||
_head = slot;
|
||||
_tail = slot;
|
||||
}
|
||||
|
||||
slot->clear();
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::addElement(MemoryPool* pool) {
|
||||
return slotData(addSlot(pool));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
||||
MemoryPool* pool) {
|
||||
VariantSlot* slot = addSlot(pool);
|
||||
if (!slotSetKey(slot, key, pool)) {
|
||||
removeSlot(slot);
|
||||
return 0;
|
||||
}
|
||||
return slot->data();
|
||||
}
|
||||
|
||||
inline void CollectionData::clear() {
|
||||
_head = 0;
|
||||
_tail = 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline bool CollectionData::containsKey(const TAdaptedString& key) const {
|
||||
return getSlot(key) != 0;
|
||||
}
|
||||
|
||||
inline bool CollectionData::copyFrom(const CollectionData& src,
|
||||
MemoryPool* pool) {
|
||||
clear();
|
||||
for (VariantSlot* s = src._head; s; s = s->next()) {
|
||||
VariantData* var;
|
||||
if (s->key() != 0) {
|
||||
if (s->ownsKey())
|
||||
var = addMember(RamStringAdapter(s->key()), pool);
|
||||
else
|
||||
var = addMember(ConstRamStringAdapter(s->key()), pool);
|
||||
} else {
|
||||
var = addElement(pool);
|
||||
}
|
||||
if (!var)
|
||||
return false;
|
||||
if (!var->copyFrom(*s->data(), pool))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool CollectionData::equalsObject(const CollectionData& other) const {
|
||||
size_t count = 0;
|
||||
for (VariantSlot* slot = _head; slot; slot = slot->next()) {
|
||||
VariantData* v1 = slot->data();
|
||||
VariantData* v2 = other.getMember(adaptString(slot->key()));
|
||||
if (!variantEquals(v1, v2))
|
||||
return false;
|
||||
count++;
|
||||
}
|
||||
return count == other.size();
|
||||
}
|
||||
|
||||
inline bool CollectionData::equalsArray(const CollectionData& other) const {
|
||||
VariantSlot* s1 = _head;
|
||||
VariantSlot* s2 = other._head;
|
||||
for (;;) {
|
||||
if (s1 == s2)
|
||||
return true;
|
||||
if (!s1 || !s2)
|
||||
return false;
|
||||
if (!variantEquals(s1->data(), s2->data()))
|
||||
return false;
|
||||
s1 = s1->next();
|
||||
s2 = s2->next();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
||||
VariantSlot* slot = _head;
|
||||
while (slot) {
|
||||
if (key.equals(slot->key()))
|
||||
break;
|
||||
slot = slot->next();
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline VariantSlot* CollectionData::getSlot(size_t index) const {
|
||||
return _head->next(index);
|
||||
}
|
||||
|
||||
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
||||
VariantSlot* current = _head;
|
||||
while (current) {
|
||||
VariantSlot* next = current->next();
|
||||
if (next == target)
|
||||
return current;
|
||||
current = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
||||
VariantSlot* slot = getSlot(key);
|
||||
return slot ? slot->data() : 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
||||
MemoryPool* pool) {
|
||||
// ignore null key
|
||||
if (key.isNull())
|
||||
return 0;
|
||||
|
||||
// search a matching key
|
||||
VariantSlot* slot = getSlot(key);
|
||||
if (slot)
|
||||
return slot->data();
|
||||
|
||||
return addMember(key, pool);
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::getElement(size_t index) const {
|
||||
VariantSlot* slot = getSlot(index);
|
||||
return slot ? slot->data() : 0;
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::getOrAddElement(size_t index,
|
||||
MemoryPool* pool) {
|
||||
VariantSlot* slot = _head;
|
||||
while (slot && index > 0) {
|
||||
slot = slot->next();
|
||||
index--;
|
||||
}
|
||||
if (!slot)
|
||||
index++;
|
||||
while (index > 0) {
|
||||
slot = addSlot(pool);
|
||||
index--;
|
||||
}
|
||||
return slotData(slot);
|
||||
}
|
||||
|
||||
inline void CollectionData::removeSlot(VariantSlot* slot) {
|
||||
if (!slot)
|
||||
return;
|
||||
VariantSlot* prev = getPreviousSlot(slot);
|
||||
VariantSlot* next = slot->next();
|
||||
if (prev)
|
||||
prev->setNext(next);
|
||||
else
|
||||
_head = next;
|
||||
if (!next)
|
||||
_tail = prev;
|
||||
}
|
||||
|
||||
inline void CollectionData::removeElement(size_t index) {
|
||||
removeSlot(getSlot(index));
|
||||
}
|
||||
|
||||
inline size_t CollectionData::memoryUsage() const {
|
||||
size_t total = 0;
|
||||
for (VariantSlot* s = _head; s; s = s->next()) {
|
||||
total += sizeof(VariantSlot) + s->data()->memoryUsage();
|
||||
if (s->ownsKey())
|
||||
total += strlen(s->key()) + 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
inline size_t CollectionData::nesting() const {
|
||||
size_t maxChildNesting = 0;
|
||||
for (VariantSlot* s = _head; s; s = s->next()) {
|
||||
size_t childNesting = s->data()->nesting();
|
||||
if (childNesting > maxChildNesting)
|
||||
maxChildNesting = childNesting;
|
||||
}
|
||||
return maxChildNesting + 1;
|
||||
}
|
||||
|
||||
inline size_t CollectionData::size() const {
|
||||
return slotSize(_head);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void movePointer(T*& p, ptrdiff_t offset) {
|
||||
if (!p)
|
||||
return;
|
||||
p = reinterpret_cast<T*>(
|
||||
reinterpret_cast<void*>(reinterpret_cast<char*>(p) + offset));
|
||||
ARDUINOJSON_ASSERT(isAligned(p));
|
||||
}
|
||||
|
||||
inline void CollectionData::movePointers(ptrdiff_t stringDistance,
|
||||
ptrdiff_t variantDistance) {
|
||||
movePointer(_head, variantDistance);
|
||||
movePointer(_tail, variantDistance);
|
||||
for (VariantSlot* slot = _head; slot; slot = slot->next())
|
||||
slot->movePointers(stringDistance, variantDistance);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline bool variantEquals(const VariantData* a, const VariantData* b) {
|
||||
return variantCompare(a, b) == COMPARE_RESULT_EQUAL;
|
||||
}
|
||||
|
||||
inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
|
||||
VariantSlot* slot = pool->allocVariant();
|
||||
if (!slot)
|
||||
return 0;
|
||||
|
||||
if (_tail) {
|
||||
_tail->setNextNotNull(slot);
|
||||
_tail = slot;
|
||||
} else {
|
||||
_head = slot;
|
||||
_tail = slot;
|
||||
}
|
||||
|
||||
slot->clear();
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::addElement(MemoryPool* pool) {
|
||||
return slotData(addSlot(pool));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
||||
MemoryPool* pool) {
|
||||
VariantSlot* slot = addSlot(pool);
|
||||
if (!slotSetKey(slot, key, pool)) {
|
||||
removeSlot(slot);
|
||||
return 0;
|
||||
}
|
||||
return slot->data();
|
||||
}
|
||||
|
||||
inline void CollectionData::clear() {
|
||||
_head = 0;
|
||||
_tail = 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline bool CollectionData::containsKey(const TAdaptedString& key) const {
|
||||
return getSlot(key) != 0;
|
||||
}
|
||||
|
||||
inline bool CollectionData::copyFrom(const CollectionData& src,
|
||||
MemoryPool* pool) {
|
||||
clear();
|
||||
for (VariantSlot* s = src._head; s; s = s->next()) {
|
||||
VariantData* var;
|
||||
if (s->key() != 0) {
|
||||
if (s->ownsKey())
|
||||
var = addMember(RamStringAdapter(s->key()), pool);
|
||||
else
|
||||
var = addMember(ConstRamStringAdapter(s->key()), pool);
|
||||
} else {
|
||||
var = addElement(pool);
|
||||
}
|
||||
if (!var)
|
||||
return false;
|
||||
if (!var->copyFrom(*s->data(), pool))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool CollectionData::equalsObject(const CollectionData& other) const {
|
||||
size_t count = 0;
|
||||
for (VariantSlot* slot = _head; slot; slot = slot->next()) {
|
||||
VariantData* v1 = slot->data();
|
||||
VariantData* v2 = other.getMember(adaptString(slot->key()));
|
||||
if (!variantEquals(v1, v2))
|
||||
return false;
|
||||
count++;
|
||||
}
|
||||
return count == other.size();
|
||||
}
|
||||
|
||||
inline bool CollectionData::equalsArray(const CollectionData& other) const {
|
||||
VariantSlot* s1 = _head;
|
||||
VariantSlot* s2 = other._head;
|
||||
for (;;) {
|
||||
if (s1 == s2)
|
||||
return true;
|
||||
if (!s1 || !s2)
|
||||
return false;
|
||||
if (!variantEquals(s1->data(), s2->data()))
|
||||
return false;
|
||||
s1 = s1->next();
|
||||
s2 = s2->next();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
||||
VariantSlot* slot = _head;
|
||||
while (slot) {
|
||||
if (key.equals(slot->key()))
|
||||
break;
|
||||
slot = slot->next();
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
|
||||
inline VariantSlot* CollectionData::getSlot(size_t index) const {
|
||||
return _head->next(index);
|
||||
}
|
||||
|
||||
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
||||
VariantSlot* current = _head;
|
||||
while (current) {
|
||||
VariantSlot* next = current->next();
|
||||
if (next == target)
|
||||
return current;
|
||||
current = next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
||||
VariantSlot* slot = getSlot(key);
|
||||
return slot ? slot->data() : 0;
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
||||
MemoryPool* pool) {
|
||||
// ignore null key
|
||||
if (key.isNull())
|
||||
return 0;
|
||||
|
||||
// search a matching key
|
||||
VariantSlot* slot = getSlot(key);
|
||||
if (slot)
|
||||
return slot->data();
|
||||
|
||||
return addMember(key, pool);
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::getElement(size_t index) const {
|
||||
VariantSlot* slot = getSlot(index);
|
||||
return slot ? slot->data() : 0;
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::getOrAddElement(size_t index,
|
||||
MemoryPool* pool) {
|
||||
VariantSlot* slot = _head;
|
||||
while (slot && index > 0) {
|
||||
slot = slot->next();
|
||||
index--;
|
||||
}
|
||||
if (!slot)
|
||||
index++;
|
||||
while (index > 0) {
|
||||
slot = addSlot(pool);
|
||||
index--;
|
||||
}
|
||||
return slotData(slot);
|
||||
}
|
||||
|
||||
inline void CollectionData::removeSlot(VariantSlot* slot) {
|
||||
if (!slot)
|
||||
return;
|
||||
VariantSlot* prev = getPreviousSlot(slot);
|
||||
VariantSlot* next = slot->next();
|
||||
if (prev)
|
||||
prev->setNext(next);
|
||||
else
|
||||
_head = next;
|
||||
if (!next)
|
||||
_tail = prev;
|
||||
}
|
||||
|
||||
inline void CollectionData::removeElement(size_t index) {
|
||||
removeSlot(getSlot(index));
|
||||
}
|
||||
|
||||
inline size_t CollectionData::memoryUsage() const {
|
||||
size_t total = 0;
|
||||
for (VariantSlot* s = _head; s; s = s->next()) {
|
||||
total += sizeof(VariantSlot) + s->data()->memoryUsage();
|
||||
if (s->ownsKey())
|
||||
total += strlen(s->key()) + 1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
inline size_t CollectionData::nesting() const {
|
||||
size_t maxChildNesting = 0;
|
||||
for (VariantSlot* s = _head; s; s = s->next()) {
|
||||
size_t childNesting = s->data()->nesting();
|
||||
if (childNesting > maxChildNesting)
|
||||
maxChildNesting = childNesting;
|
||||
}
|
||||
return maxChildNesting + 1;
|
||||
}
|
||||
|
||||
inline size_t CollectionData::size() const {
|
||||
return slotSize(_head);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void movePointer(T*& p, ptrdiff_t offset) {
|
||||
if (!p)
|
||||
return;
|
||||
p = reinterpret_cast<T*>(
|
||||
reinterpret_cast<void*>(reinterpret_cast<char*>(p) + offset));
|
||||
ARDUINOJSON_ASSERT(isAligned(p));
|
||||
}
|
||||
|
||||
inline void CollectionData::movePointers(ptrdiff_t stringDistance,
|
||||
ptrdiff_t variantDistance) {
|
||||
movePointer(_head, variantDistance);
|
||||
movePointer(_tail, variantDistance);
|
||||
for (VariantSlot* slot = _head; slot; slot = slot->next())
|
||||
slot->movePointers(stringDistance, variantDistance);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,220 +1,232 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define ARDUINOJSON_HAS_INT64 1
|
||||
#else
|
||||
#define ARDUINOJSON_HAS_INT64 0
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define ARDUINOJSON_HAS_LONG_LONG 1
|
||||
#define ARDUINOJSON_HAS_NULLPTR 1
|
||||
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
|
||||
#else
|
||||
#define ARDUINOJSON_HAS_LONG_LONG 0
|
||||
#define ARDUINOJSON_HAS_NULLPTR 0
|
||||
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
|
||||
#endif
|
||||
|
||||
// Small or big machine?
|
||||
#ifndef ARDUINOJSON_EMBEDDED_MODE
|
||||
#if defined(ARDUINO) /* Arduino*/ \
|
||||
|| defined(__IAR_SYSTEMS_ICC__) /* IAR Embedded Workbench */ \
|
||||
|| defined(__XC) /* MPLAB XC compiler */ \
|
||||
|| defined(__ARMCC_VERSION) /* Keil ARM Compiler */ \
|
||||
|| defined(__AVR) /* Atmel AVR8/GNU C Compiler */
|
||||
#define ARDUINOJSON_EMBEDDED_MODE 1
|
||||
#else
|
||||
#define ARDUINOJSON_EMBEDDED_MODE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Auto enable std::stream if the right headers are here and no conflicting
|
||||
// macro is defined
|
||||
#if !defined(ARDUINOJSON_ENABLE_STD_STREAM) && defined(__has_include)
|
||||
#if __has_include(<istream>) && \
|
||||
__has_include(<ostream>) && \
|
||||
!defined(min) && \
|
||||
!defined(max)
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Auto enable std::string if the right header is here and no conflicting
|
||||
// macro is defined
|
||||
#if !defined(ARDUINOJSON_ENABLE_STD_STRING) && defined(__has_include)
|
||||
#if __has_include(<string>) && !defined(min) && !defined(max)
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_EMBEDDED_MODE
|
||||
|
||||
// Store floats by default to reduce the memory usage (issue #134)
|
||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||
#define ARDUINOJSON_USE_DOUBLE 0
|
||||
#endif
|
||||
|
||||
// Store longs by default, because they usually match the size of a float.
|
||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#endif
|
||||
|
||||
// Embedded systems usually don't have std::string
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
||||
#endif
|
||||
|
||||
// Embedded systems usually don't have std::stream
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||
#endif
|
||||
|
||||
// Limit nesting as the stack is likely to be small
|
||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
|
||||
#endif
|
||||
|
||||
#else // ARDUINOJSON_EMBEDDED_MODE
|
||||
|
||||
// On a computer we have plenty of memory so we can use doubles
|
||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||
#define ARDUINOJSON_USE_DOUBLE 1
|
||||
#endif
|
||||
|
||||
// Use long long when available
|
||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||
#if ARDUINOJSON_HAS_LONG_LONG || ARDUINOJSON_HAS_INT64
|
||||
#define ARDUINOJSON_USE_LONG_LONG 1
|
||||
#else
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// On a computer, we can use std::string
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||
#endif
|
||||
|
||||
// On a computer, we can assume std::stream
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||
#endif
|
||||
|
||||
// On a computer, the stack is large so we can increase nesting limit
|
||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
|
||||
#endif
|
||||
|
||||
#endif // ARDUINOJSON_EMBEDDED_MODE
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// Enable support for Arduino's String class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||
#endif
|
||||
|
||||
// Enable support for Arduino's Stream class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
||||
#endif
|
||||
|
||||
// Enable support for Arduino's Print class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
|
||||
#endif
|
||||
|
||||
#else // ARDUINO
|
||||
|
||||
// Disable support for Arduino's String class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
||||
#endif
|
||||
|
||||
// Disable support for Arduino's Stream class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
|
||||
#endif
|
||||
|
||||
// Disable support for Arduino's Print class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
|
||||
#endif
|
||||
|
||||
#endif // ARDUINO
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_PROGMEM
|
||||
#ifdef PROGMEM
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Convert unicode escape sequence (\u0123) to UTF-8
|
||||
#ifndef ARDUINOJSON_DECODE_UNICODE
|
||||
#define ARDUINOJSON_DECODE_UNICODE 0
|
||||
#endif
|
||||
|
||||
// Ignore comments in input
|
||||
#ifndef ARDUINOJSON_ENABLE_COMMENTS
|
||||
#define ARDUINOJSON_ENABLE_COMMENTS 0
|
||||
#endif
|
||||
|
||||
// Support NaN in JSON
|
||||
#ifndef ARDUINOJSON_ENABLE_NAN
|
||||
#define ARDUINOJSON_ENABLE_NAN 0
|
||||
#endif
|
||||
|
||||
// Support Infinity in JSON
|
||||
#ifndef ARDUINOJSON_ENABLE_INFINITY
|
||||
#define ARDUINOJSON_ENABLE_INFINITY 0
|
||||
#endif
|
||||
|
||||
// Control the exponentiation threshold for big numbers
|
||||
// CAUTION: cannot be more that 1e9 !!!!
|
||||
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
|
||||
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
|
||||
#endif
|
||||
|
||||
// Control the exponentiation threshold for small numbers
|
||||
#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
|
||||
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
||||
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
|
||||
#define ARDUINOJSON_LITTLE_ENDIAN 1
|
||||
#else
|
||||
#define ARDUINOJSON_LITTLE_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_TAB
|
||||
#define ARDUINOJSON_TAB " "
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_STRING_BUFFER_SIZE
|
||||
#define ARDUINOJSON_STRING_BUFFER_SIZE 32
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_DEBUG
|
||||
#ifdef __PLATFORMIO_BUILD_DEBUG__
|
||||
#define ARDUINOJSON_DEBUG 1
|
||||
#else
|
||||
#define ARDUINOJSON_DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define ARDUINOJSON_HAS_LONG_LONG 1
|
||||
#define ARDUINOJSON_HAS_NULLPTR 1
|
||||
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
|
||||
#else
|
||||
#define ARDUINOJSON_HAS_LONG_LONG 0
|
||||
#define ARDUINOJSON_HAS_NULLPTR 0
|
||||
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !ARDUINOJSON_HAS_LONG_LONG
|
||||
#define ARDUINOJSON_HAS_INT64 1
|
||||
#else
|
||||
#define ARDUINOJSON_HAS_INT64 0
|
||||
#endif
|
||||
|
||||
// Small or big machine?
|
||||
#ifndef ARDUINOJSON_EMBEDDED_MODE
|
||||
#if defined(ARDUINO) /* Arduino*/ \
|
||||
|| defined(__IAR_SYSTEMS_ICC__) /* IAR Embedded Workbench */ \
|
||||
|| defined(__XC) /* MPLAB XC compiler */ \
|
||||
|| defined(__ARMCC_VERSION) /* Keil ARM Compiler */ \
|
||||
|| defined(__AVR) /* Atmel AVR8/GNU C Compiler */
|
||||
#define ARDUINOJSON_EMBEDDED_MODE 1
|
||||
#else
|
||||
#define ARDUINOJSON_EMBEDDED_MODE 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Auto enable std::stream if the right headers are here and no conflicting
|
||||
// macro is defined
|
||||
#if !defined(ARDUINOJSON_ENABLE_STD_STREAM) && defined(__has_include)
|
||||
#if __has_include(<istream>) && \
|
||||
__has_include(<ostream>) && \
|
||||
!defined(min) && \
|
||||
!defined(max)
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Auto enable std::string if the right header is here and no conflicting
|
||||
// macro is defined
|
||||
#if !defined(ARDUINOJSON_ENABLE_STD_STRING) && defined(__has_include)
|
||||
#if __has_include(<string>) && !defined(min) && !defined(max)
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_EMBEDDED_MODE
|
||||
|
||||
// Store floats by default to reduce the memory usage (issue #134)
|
||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||
#define ARDUINOJSON_USE_DOUBLE 0
|
||||
#endif
|
||||
|
||||
// Store longs by default, because they usually match the size of a float.
|
||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#endif
|
||||
|
||||
// Embedded systems usually don't have std::string
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
||||
#endif
|
||||
|
||||
// Embedded systems usually don't have std::stream
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||
#endif
|
||||
|
||||
// Limit nesting as the stack is likely to be small
|
||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
|
||||
#endif
|
||||
|
||||
#else // ARDUINOJSON_EMBEDDED_MODE
|
||||
|
||||
// On a computer we have plenty of memory so we can use doubles
|
||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||
#define ARDUINOJSON_USE_DOUBLE 1
|
||||
#endif
|
||||
|
||||
// Use long long when available
|
||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||
#if ARDUINOJSON_HAS_LONG_LONG || ARDUINOJSON_HAS_INT64
|
||||
#define ARDUINOJSON_USE_LONG_LONG 1
|
||||
#else
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// On a computer, we can use std::string
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||
#endif
|
||||
|
||||
// On a computer, we can assume std::stream
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||
#endif
|
||||
|
||||
// On a computer, the stack is large so we can increase nesting limit
|
||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
|
||||
#endif
|
||||
|
||||
#endif // ARDUINOJSON_EMBEDDED_MODE
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// Enable support for Arduino's String class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||
#endif
|
||||
|
||||
// Enable support for Arduino's Stream class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
||||
#endif
|
||||
|
||||
// Enable support for Arduino's Print class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
|
||||
#endif
|
||||
|
||||
#else // ARDUINO
|
||||
|
||||
// Disable support for Arduino's String class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
||||
#endif
|
||||
|
||||
// Disable support for Arduino's Stream class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
|
||||
#endif
|
||||
|
||||
// Disable support for Arduino's Print class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
|
||||
#endif
|
||||
|
||||
#endif // ARDUINO
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_PROGMEM
|
||||
#ifdef PROGMEM
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Convert unicode escape sequence (\u0123) to UTF-8
|
||||
#ifndef ARDUINOJSON_DECODE_UNICODE
|
||||
#define ARDUINOJSON_DECODE_UNICODE 1
|
||||
#endif
|
||||
|
||||
// Ignore comments in input
|
||||
#ifndef ARDUINOJSON_ENABLE_COMMENTS
|
||||
#define ARDUINOJSON_ENABLE_COMMENTS 0
|
||||
#endif
|
||||
|
||||
// Support NaN in JSON
|
||||
#ifndef ARDUINOJSON_ENABLE_NAN
|
||||
#define ARDUINOJSON_ENABLE_NAN 0
|
||||
#endif
|
||||
|
||||
// Support Infinity in JSON
|
||||
#ifndef ARDUINOJSON_ENABLE_INFINITY
|
||||
#define ARDUINOJSON_ENABLE_INFINITY 0
|
||||
#endif
|
||||
|
||||
// Control the exponentiation threshold for big numbers
|
||||
// CAUTION: cannot be more that 1e9 !!!!
|
||||
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
|
||||
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
|
||||
#endif
|
||||
|
||||
// Control the exponentiation threshold for small numbers
|
||||
#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
|
||||
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
||||
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
|
||||
#define ARDUINOJSON_LITTLE_ENDIAN 1
|
||||
#else
|
||||
#define ARDUINOJSON_LITTLE_ENDIAN 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
|
||||
#if defined(__AVR)
|
||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_TAB
|
||||
#define ARDUINOJSON_TAB " "
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_STRING_BUFFER_SIZE
|
||||
#define ARDUINOJSON_STRING_BUFFER_SIZE 32
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_DEBUG
|
||||
#ifdef __PLATFORMIO_BUILD_DEBUG__
|
||||
#define ARDUINOJSON_DEBUG 1
|
||||
#else
|
||||
#define ARDUINOJSON_DEBUG 0
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,115 +1,115 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class DeserializationError {
|
||||
// safe bool idiom
|
||||
typedef void (DeserializationError::*bool_type)() const;
|
||||
void safeBoolHelper() const {}
|
||||
|
||||
public:
|
||||
enum Code {
|
||||
Ok,
|
||||
IncompleteInput,
|
||||
InvalidInput,
|
||||
NoMemory,
|
||||
NotSupported,
|
||||
TooDeep
|
||||
};
|
||||
|
||||
DeserializationError() {}
|
||||
DeserializationError(Code c) : _code(c) {}
|
||||
|
||||
// Compare with DeserializationError
|
||||
friend bool operator==(const DeserializationError& lhs,
|
||||
const DeserializationError& rhs) {
|
||||
return lhs._code == rhs._code;
|
||||
}
|
||||
friend bool operator!=(const DeserializationError& lhs,
|
||||
const DeserializationError& rhs) {
|
||||
return lhs._code != rhs._code;
|
||||
}
|
||||
|
||||
// Compare with Code
|
||||
friend bool operator==(const DeserializationError& lhs, Code rhs) {
|
||||
return lhs._code == rhs;
|
||||
}
|
||||
friend bool operator==(Code lhs, const DeserializationError& rhs) {
|
||||
return lhs == rhs._code;
|
||||
}
|
||||
friend bool operator!=(const DeserializationError& lhs, Code rhs) {
|
||||
return lhs._code != rhs;
|
||||
}
|
||||
friend bool operator!=(Code lhs, const DeserializationError& rhs) {
|
||||
return lhs != rhs._code;
|
||||
}
|
||||
|
||||
// Behaves like a bool
|
||||
operator bool_type() const {
|
||||
return _code != Ok ? &DeserializationError::safeBoolHelper : 0;
|
||||
}
|
||||
friend bool operator==(bool value, const DeserializationError& err) {
|
||||
return static_cast<bool>(err) == value;
|
||||
}
|
||||
friend bool operator==(const DeserializationError& err, bool value) {
|
||||
return static_cast<bool>(err) == value;
|
||||
}
|
||||
friend bool operator!=(bool value, const DeserializationError& err) {
|
||||
return static_cast<bool>(err) != value;
|
||||
}
|
||||
friend bool operator!=(const DeserializationError& err, bool value) {
|
||||
return static_cast<bool>(err) != value;
|
||||
}
|
||||
|
||||
// Returns internal enum, useful for switch statement
|
||||
Code code() const {
|
||||
return _code;
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
switch (_code) {
|
||||
case Ok:
|
||||
return "Ok";
|
||||
case TooDeep:
|
||||
return "TooDeep";
|
||||
case NoMemory:
|
||||
return "NoMemory";
|
||||
case InvalidInput:
|
||||
return "InvalidInput";
|
||||
case IncompleteInput:
|
||||
return "IncompleteInput";
|
||||
case NotSupported:
|
||||
return "NotSupported";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Code _code;
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream& operator<<(std::ostream& s,
|
||||
const DeserializationError& e) {
|
||||
s << e.c_str();
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& s, DeserializationError::Code c) {
|
||||
s << DeserializationError(c).c_str();
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class DeserializationError {
|
||||
// safe bool idiom
|
||||
typedef void (DeserializationError::*bool_type)() const;
|
||||
void safeBoolHelper() const {}
|
||||
|
||||
public:
|
||||
enum Code {
|
||||
Ok,
|
||||
IncompleteInput,
|
||||
InvalidInput,
|
||||
NoMemory,
|
||||
NotSupported,
|
||||
TooDeep
|
||||
};
|
||||
|
||||
DeserializationError() {}
|
||||
DeserializationError(Code c) : _code(c) {}
|
||||
|
||||
// Compare with DeserializationError
|
||||
friend bool operator==(const DeserializationError& lhs,
|
||||
const DeserializationError& rhs) {
|
||||
return lhs._code == rhs._code;
|
||||
}
|
||||
friend bool operator!=(const DeserializationError& lhs,
|
||||
const DeserializationError& rhs) {
|
||||
return lhs._code != rhs._code;
|
||||
}
|
||||
|
||||
// Compare with Code
|
||||
friend bool operator==(const DeserializationError& lhs, Code rhs) {
|
||||
return lhs._code == rhs;
|
||||
}
|
||||
friend bool operator==(Code lhs, const DeserializationError& rhs) {
|
||||
return lhs == rhs._code;
|
||||
}
|
||||
friend bool operator!=(const DeserializationError& lhs, Code rhs) {
|
||||
return lhs._code != rhs;
|
||||
}
|
||||
friend bool operator!=(Code lhs, const DeserializationError& rhs) {
|
||||
return lhs != rhs._code;
|
||||
}
|
||||
|
||||
// Behaves like a bool
|
||||
operator bool_type() const {
|
||||
return _code != Ok ? &DeserializationError::safeBoolHelper : 0;
|
||||
}
|
||||
friend bool operator==(bool value, const DeserializationError& err) {
|
||||
return static_cast<bool>(err) == value;
|
||||
}
|
||||
friend bool operator==(const DeserializationError& err, bool value) {
|
||||
return static_cast<bool>(err) == value;
|
||||
}
|
||||
friend bool operator!=(bool value, const DeserializationError& err) {
|
||||
return static_cast<bool>(err) != value;
|
||||
}
|
||||
friend bool operator!=(const DeserializationError& err, bool value) {
|
||||
return static_cast<bool>(err) != value;
|
||||
}
|
||||
|
||||
// Returns internal enum, useful for switch statement
|
||||
Code code() const {
|
||||
return _code;
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
switch (_code) {
|
||||
case Ok:
|
||||
return "Ok";
|
||||
case TooDeep:
|
||||
return "TooDeep";
|
||||
case NoMemory:
|
||||
return "NoMemory";
|
||||
case InvalidInput:
|
||||
return "InvalidInput";
|
||||
case IncompleteInput:
|
||||
return "IncompleteInput";
|
||||
case NotSupported:
|
||||
return "NotSupported";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Code _code;
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream& operator<<(std::ostream& s,
|
||||
const DeserializationError& e) {
|
||||
s << e.c_str();
|
||||
return s;
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& s, DeserializationError::Code c) {
|
||||
s << DeserializationError(c).c_str();
|
||||
return s;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,66 +1,66 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class Filter {
|
||||
public:
|
||||
explicit Filter(VariantConstRef v) : _variant(v) {}
|
||||
|
||||
bool allow() const {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
bool allowArray() const {
|
||||
return _variant == true || _variant.is<ArrayRef>();
|
||||
}
|
||||
|
||||
bool allowObject() const {
|
||||
return _variant == true || _variant.is<ObjectRef>();
|
||||
}
|
||||
|
||||
bool allowValue() const {
|
||||
return _variant == true;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
Filter operator[](const TKey& key) const {
|
||||
if (_variant == true) // "true" means "allow recursively"
|
||||
return *this;
|
||||
else
|
||||
return Filter(_variant[key]);
|
||||
}
|
||||
|
||||
private:
|
||||
VariantConstRef _variant;
|
||||
};
|
||||
|
||||
struct AllowAllFilter {
|
||||
bool allow() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowArray() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowObject() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowValue() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
AllowAllFilter operator[](const TKey&) const {
|
||||
return AllowAllFilter();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class Filter {
|
||||
public:
|
||||
explicit Filter(VariantConstRef v) : _variant(v) {}
|
||||
|
||||
bool allow() const {
|
||||
return _variant;
|
||||
}
|
||||
|
||||
bool allowArray() const {
|
||||
return _variant == true || _variant.is<ArrayRef>();
|
||||
}
|
||||
|
||||
bool allowObject() const {
|
||||
return _variant == true || _variant.is<ObjectRef>();
|
||||
}
|
||||
|
||||
bool allowValue() const {
|
||||
return _variant == true;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
Filter operator[](const TKey& key) const {
|
||||
if (_variant == true) // "true" means "allow recursively"
|
||||
return *this;
|
||||
else
|
||||
return Filter(_variant[key]);
|
||||
}
|
||||
|
||||
private:
|
||||
VariantConstRef _variant;
|
||||
};
|
||||
|
||||
struct AllowAllFilter {
|
||||
bool allow() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowArray() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowObject() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allowValue() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
AllowAllFilter operator[](const TKey&) const {
|
||||
return AllowAllFilter();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,29 +1,29 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class NestingLimit {
|
||||
public:
|
||||
NestingLimit() : _value(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
||||
explicit NestingLimit(uint8_t n) : _value(n) {}
|
||||
|
||||
NestingLimit decrement() const {
|
||||
ARDUINOJSON_ASSERT(_value > 0);
|
||||
return NestingLimit(static_cast<uint8_t>(_value - 1));
|
||||
}
|
||||
|
||||
bool reached() const {
|
||||
return _value == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t _value;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class NestingLimit {
|
||||
public:
|
||||
NestingLimit() : _value(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
||||
explicit NestingLimit(uint8_t n) : _value(n) {}
|
||||
|
||||
NestingLimit decrement() const {
|
||||
ARDUINOJSON_ASSERT(_value > 0);
|
||||
return NestingLimit(static_cast<uint8_t>(_value - 1));
|
||||
}
|
||||
|
||||
bool reached() const {
|
||||
return _value == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t _value;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,55 +1,56 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stdlib.h> // for size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// The default reader is a simple wrapper for Readers that are not copiable
|
||||
template <typename TSource, typename Enable = void>
|
||||
struct Reader {
|
||||
public:
|
||||
Reader(TSource& source) : _source(&source) {}
|
||||
|
||||
int read() {
|
||||
return _source->read();
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
return _source->readBytes(buffer, length);
|
||||
}
|
||||
|
||||
private:
|
||||
TSource* _source;
|
||||
};
|
||||
|
||||
template <typename TSource, typename Enable = void>
|
||||
struct BoundedReader {
|
||||
// no default implementation because we need to pass the size to the
|
||||
// constructor
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#include <ArduinoJson/Deserialization/Readers/IteratorReader.hpp>
|
||||
#include <ArduinoJson/Deserialization/Readers/RamReader.hpp>
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#include <ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp>
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#include <ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp>
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||
#include <ArduinoJson/Deserialization/Readers/FlashReader.hpp>
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp>
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stdlib.h> // for size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// The default reader is a simple wrapper for Readers that are not copiable
|
||||
template <typename TSource, typename Enable = void>
|
||||
struct Reader {
|
||||
public:
|
||||
Reader(TSource& source) : _source(&source) {}
|
||||
|
||||
int read() {
|
||||
return _source->read();
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
return _source->readBytes(buffer, length);
|
||||
}
|
||||
|
||||
private:
|
||||
TSource* _source;
|
||||
};
|
||||
|
||||
template <typename TSource, typename Enable = void>
|
||||
struct BoundedReader {
|
||||
// no default implementation because we need to pass the size to the
|
||||
// constructor
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#include <ArduinoJson/Deserialization/Readers/IteratorReader.hpp>
|
||||
#include <ArduinoJson/Deserialization/Readers/RamReader.hpp>
|
||||
#include <ArduinoJson/Deserialization/Readers/VariantReader.hpp>
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#include <ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp>
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#include <ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp>
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||
#include <ArduinoJson/Deserialization/Readers/FlashReader.hpp>
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp>
|
||||
#endif
|
||||
@@ -1,31 +1,31 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource,
|
||||
typename enable_if<is_base_of<Stream, TSource>::value>::type> {
|
||||
public:
|
||||
explicit Reader(Stream& stream) : _stream(&stream) {}
|
||||
|
||||
int read() {
|
||||
// don't use _stream.read() as it ignores the timeout
|
||||
char c;
|
||||
return _stream->readBytes(&c, 1) ? static_cast<unsigned char>(c) : -1;
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
return _stream->readBytes(buffer, length);
|
||||
}
|
||||
|
||||
private:
|
||||
Stream* _stream;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource,
|
||||
typename enable_if<is_base_of<Stream, TSource>::value>::type> {
|
||||
public:
|
||||
explicit Reader(Stream& stream) : _stream(&stream) {}
|
||||
|
||||
int read() {
|
||||
// don't use _stream.read() as it ignores the timeout
|
||||
char c;
|
||||
return _stream->readBytes(&c, 1) ? static_cast<unsigned char>(c) : -1;
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
return _stream->readBytes(buffer, length);
|
||||
}
|
||||
|
||||
private:
|
||||
Stream* _stream;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,17 +1,17 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource,
|
||||
typename enable_if<is_base_of< ::String, TSource>::value>::type>
|
||||
: BoundedReader<const char*> {
|
||||
explicit Reader(const ::String& s)
|
||||
: BoundedReader<const char*>(s.c_str(), s.length()) {}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource,
|
||||
typename enable_if<is_base_of< ::String, TSource>::value>::type>
|
||||
: BoundedReader<const char*> {
|
||||
explicit Reader(const ::String& s)
|
||||
: BoundedReader<const char*>(s.c_str(), s.length()) {}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,53 +1,53 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <>
|
||||
struct Reader<const __FlashStringHelper*, void> {
|
||||
const char* _ptr;
|
||||
|
||||
public:
|
||||
explicit Reader(const __FlashStringHelper* ptr)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
||||
|
||||
int read() {
|
||||
return pgm_read_byte(_ptr++);
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
memcpy_P(buffer, _ptr, length);
|
||||
_ptr += length;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BoundedReader<const __FlashStringHelper*, void> {
|
||||
const char* _ptr;
|
||||
const char* _end;
|
||||
|
||||
public:
|
||||
explicit BoundedReader(const __FlashStringHelper* ptr, size_t size)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {}
|
||||
|
||||
int read() {
|
||||
if (_ptr < _end)
|
||||
return pgm_read_byte(_ptr++);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
size_t available = static_cast<size_t>(_end - _ptr);
|
||||
if (available < length)
|
||||
length = available;
|
||||
memcpy_P(buffer, _ptr, length);
|
||||
_ptr += length;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <>
|
||||
struct Reader<const __FlashStringHelper*, void> {
|
||||
const char* _ptr;
|
||||
|
||||
public:
|
||||
explicit Reader(const __FlashStringHelper* ptr)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
||||
|
||||
int read() {
|
||||
return pgm_read_byte(_ptr++);
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
memcpy_P(buffer, _ptr, length);
|
||||
_ptr += length;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BoundedReader<const __FlashStringHelper*, void> {
|
||||
const char* _ptr;
|
||||
const char* _end;
|
||||
|
||||
public:
|
||||
explicit BoundedReader(const __FlashStringHelper* ptr, size_t size)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {}
|
||||
|
||||
int read() {
|
||||
if (_ptr < _end)
|
||||
return pgm_read_byte(_ptr++);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
size_t available = static_cast<size_t>(_end - _ptr);
|
||||
if (available < length)
|
||||
length = available;
|
||||
memcpy_P(buffer, _ptr, length);
|
||||
_ptr += length;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,43 +1,43 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TIterator>
|
||||
class IteratorReader {
|
||||
TIterator _ptr, _end;
|
||||
|
||||
public:
|
||||
explicit IteratorReader(TIterator begin, TIterator end)
|
||||
: _ptr(begin), _end(end) {}
|
||||
|
||||
int read() {
|
||||
if (_ptr < _end)
|
||||
return static_cast<unsigned char>(*_ptr++);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
size_t i = 0;
|
||||
while (i < length && _ptr < _end) buffer[i++] = *_ptr++;
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct void_ {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource, typename void_<typename TSource::const_iterator>::type>
|
||||
: IteratorReader<typename TSource::const_iterator> {
|
||||
explicit Reader(const TSource& source)
|
||||
: IteratorReader<typename TSource::const_iterator>(source.begin(),
|
||||
source.end()) {}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TIterator>
|
||||
class IteratorReader {
|
||||
TIterator _ptr, _end;
|
||||
|
||||
public:
|
||||
explicit IteratorReader(TIterator begin, TIterator end)
|
||||
: _ptr(begin), _end(end) {}
|
||||
|
||||
int read() {
|
||||
if (_ptr < _end)
|
||||
return static_cast<unsigned char>(*_ptr++);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
size_t i = 0;
|
||||
while (i < length && _ptr < _end) buffer[i++] = *_ptr++;
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct void_ {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource, typename void_<typename TSource::const_iterator>::type>
|
||||
: IteratorReader<typename TSource::const_iterator> {
|
||||
explicit Reader(const TSource& source)
|
||||
: IteratorReader<typename TSource::const_iterator>(source.begin(),
|
||||
source.end()) {}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,50 +1,50 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct IsCharOrVoid {
|
||||
static const bool value =
|
||||
is_same<T, void>::value || is_same<T, char>::value ||
|
||||
is_same<T, unsigned char>::value || is_same<T, signed char>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsCharOrVoid<const T> : IsCharOrVoid<T> {};
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource*,
|
||||
typename enable_if<IsCharOrVoid<TSource>::value>::type> {
|
||||
const char* _ptr;
|
||||
|
||||
public:
|
||||
explicit Reader(const void* ptr)
|
||||
: _ptr(ptr ? reinterpret_cast<const char*>(ptr) : "") {}
|
||||
|
||||
int read() {
|
||||
return static_cast<unsigned char>(*_ptr++);
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
for (size_t i = 0; i < length; i++) buffer[i] = *_ptr++;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TSource>
|
||||
struct BoundedReader<TSource*,
|
||||
typename enable_if<IsCharOrVoid<TSource>::value>::type>
|
||||
: public IteratorReader<const char*> {
|
||||
public:
|
||||
explicit BoundedReader(const void* ptr, size_t len)
|
||||
: IteratorReader<const char*>(reinterpret_cast<const char*>(ptr),
|
||||
reinterpret_cast<const char*>(ptr) + len) {}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct IsCharOrVoid {
|
||||
static const bool value =
|
||||
is_same<T, void>::value || is_same<T, char>::value ||
|
||||
is_same<T, unsigned char>::value || is_same<T, signed char>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsCharOrVoid<const T> : IsCharOrVoid<T> {};
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource*,
|
||||
typename enable_if<IsCharOrVoid<TSource>::value>::type> {
|
||||
const char* _ptr;
|
||||
|
||||
public:
|
||||
explicit Reader(const void* ptr)
|
||||
: _ptr(ptr ? reinterpret_cast<const char*>(ptr) : "") {}
|
||||
|
||||
int read() {
|
||||
return static_cast<unsigned char>(*_ptr++);
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
for (size_t i = 0; i < length; i++) buffer[i] = *_ptr++;
|
||||
return length;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TSource>
|
||||
struct BoundedReader<TSource*,
|
||||
typename enable_if<IsCharOrVoid<TSource>::value>::type>
|
||||
: public IteratorReader<const char*> {
|
||||
public:
|
||||
explicit BoundedReader(const void* ptr, size_t len)
|
||||
: IteratorReader<const char*>(reinterpret_cast<const char*>(ptr),
|
||||
reinterpret_cast<const char*>(ptr) + len) {}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,29 +1,29 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource, typename enable_if<
|
||||
is_base_of<std::istream, TSource>::value>::type> {
|
||||
public:
|
||||
explicit Reader(std::istream& stream) : _stream(&stream) {}
|
||||
|
||||
int read() {
|
||||
return _stream->get();
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
_stream->read(buffer, static_cast<std::streamsize>(length));
|
||||
return static_cast<size_t>(_stream->gcount());
|
||||
}
|
||||
|
||||
private:
|
||||
std::istream* _stream;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TSource>
|
||||
struct Reader<TSource, typename enable_if<
|
||||
is_base_of<std::istream, TSource>::value>::type> {
|
||||
public:
|
||||
explicit Reader(std::istream& stream) : _stream(&stream) {}
|
||||
|
||||
int read() {
|
||||
return _stream->get();
|
||||
}
|
||||
|
||||
size_t readBytes(char* buffer, size_t length) {
|
||||
_stream->read(buffer, static_cast<std::streamsize>(length));
|
||||
return static_cast<size_t>(_stream->gcount());
|
||||
}
|
||||
|
||||
private:
|
||||
std::istream* _stream;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -0,0 +1,34 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Object/MemberProxy.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TArray>
|
||||
struct Reader<ElementProxy<TArray>, void> : Reader<char*, void> {
|
||||
explicit Reader(const ElementProxy<TArray>& x)
|
||||
: Reader<char*, void>(x.template as<const char*>()) {}
|
||||
};
|
||||
|
||||
template <typename TObject, typename TStringRef>
|
||||
struct Reader<MemberProxy<TObject, TStringRef>, void> : Reader<char*, void> {
|
||||
explicit Reader(const MemberProxy<TObject, TStringRef>& x)
|
||||
: Reader<char*, void>(x.template as<const char*>()) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Reader<VariantRef, void> : Reader<char*, void> {
|
||||
explicit Reader(VariantRef x) : Reader<char*, void>(x.as<const char*>()) {}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Reader<VariantConstRef, void> : Reader<char*, void> {
|
||||
explicit Reader(VariantConstRef x)
|
||||
: Reader<char*, void>(x.as<const char*>()) {}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,71 +1,68 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Deserialization/DeserializationError.hpp>
|
||||
#include <ArduinoJson/Deserialization/Filter.hpp>
|
||||
#include <ArduinoJson/Deserialization/NestingLimit.hpp>
|
||||
#include <ArduinoJson/Deserialization/Reader.hpp>
|
||||
#include <ArduinoJson/StringStorage/StringStorage.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <template <typename, typename> class TDeserializer, typename TReader,
|
||||
typename TWriter>
|
||||
TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool &pool,
|
||||
TReader reader,
|
||||
TWriter writer) {
|
||||
return TDeserializer<TReader, TWriter>(pool, reader, writer);
|
||||
}
|
||||
|
||||
// deserialize(JsonDocument&, const std::string&, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const String&, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, char*, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const char*, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const __FlashStringHelper*, NestingLimit, Filter);
|
||||
template <template <typename, typename> class TDeserializer, typename TString,
|
||||
typename TFilter>
|
||||
typename enable_if<!is_array<TString>::value, DeserializationError>::type
|
||||
deserialize(JsonDocument &doc, const TString &input, NestingLimit nestingLimit,
|
||||
TFilter filter) {
|
||||
Reader<TString> reader(input);
|
||||
doc.clear();
|
||||
return makeDeserializer<TDeserializer>(
|
||||
doc.memoryPool(), reader,
|
||||
makeStringStorage(doc.memoryPool(), input))
|
||||
.parse(doc.data(), filter, nestingLimit);
|
||||
}
|
||||
//
|
||||
// deserialize(JsonDocument&, char*, size_t, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const char*, size_t, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const __FlashStringHelper*, size_t, NL, Filter);
|
||||
template <template <typename, typename> class TDeserializer, typename TChar,
|
||||
typename TFilter>
|
||||
DeserializationError deserialize(JsonDocument &doc, TChar *input,
|
||||
size_t inputSize, NestingLimit nestingLimit,
|
||||
TFilter filter) {
|
||||
BoundedReader<TChar *> reader(input, inputSize);
|
||||
doc.clear();
|
||||
return makeDeserializer<TDeserializer>(
|
||||
doc.memoryPool(), reader,
|
||||
makeStringStorage(doc.memoryPool(), input))
|
||||
.parse(doc.data(), filter, nestingLimit);
|
||||
}
|
||||
//
|
||||
// deserialize(JsonDocument&, std::istream&, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, Stream&, NestingLimit, Filter);
|
||||
template <template <typename, typename> class TDeserializer, typename TStream,
|
||||
typename TFilter>
|
||||
DeserializationError deserialize(JsonDocument &doc, TStream &input,
|
||||
NestingLimit nestingLimit, TFilter filter) {
|
||||
Reader<TStream> reader(input);
|
||||
doc.clear();
|
||||
return makeDeserializer<TDeserializer>(
|
||||
doc.memoryPool(), reader,
|
||||
makeStringStorage(doc.memoryPool(), input))
|
||||
.parse(doc.data(), filter, nestingLimit);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Deserialization/DeserializationError.hpp>
|
||||
#include <ArduinoJson/Deserialization/Filter.hpp>
|
||||
#include <ArduinoJson/Deserialization/NestingLimit.hpp>
|
||||
#include <ArduinoJson/Deserialization/Reader.hpp>
|
||||
#include <ArduinoJson/StringStorage/StringStorage.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <template <typename, typename> class TDeserializer, typename TReader,
|
||||
typename TWriter>
|
||||
TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool &pool,
|
||||
TReader reader,
|
||||
TWriter writer) {
|
||||
return TDeserializer<TReader, TWriter>(pool, reader, writer);
|
||||
}
|
||||
|
||||
// deserialize(JsonDocument&, const std::string&, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const String&, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, char*, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const char*, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const __FlashStringHelper*, NestingLimit, Filter);
|
||||
template <template <typename, typename> class TDeserializer, typename TString,
|
||||
typename TFilter>
|
||||
typename enable_if<!is_array<TString>::value, DeserializationError>::type
|
||||
deserialize(JsonDocument &doc, const TString &input, NestingLimit nestingLimit,
|
||||
TFilter filter) {
|
||||
Reader<TString> reader(input);
|
||||
doc.clear();
|
||||
return makeDeserializer<TDeserializer>(doc.memoryPool(), reader,
|
||||
makeStringStorage(input))
|
||||
.parse(doc.data(), filter, nestingLimit);
|
||||
}
|
||||
//
|
||||
// deserialize(JsonDocument&, char*, size_t, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const char*, size_t, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, const __FlashStringHelper*, size_t, NL, Filter);
|
||||
template <template <typename, typename> class TDeserializer, typename TChar,
|
||||
typename TFilter>
|
||||
DeserializationError deserialize(JsonDocument &doc, TChar *input,
|
||||
size_t inputSize, NestingLimit nestingLimit,
|
||||
TFilter filter) {
|
||||
BoundedReader<TChar *> reader(input, inputSize);
|
||||
doc.clear();
|
||||
return makeDeserializer<TDeserializer>(doc.memoryPool(), reader,
|
||||
makeStringStorage(input))
|
||||
.parse(doc.data(), filter, nestingLimit);
|
||||
}
|
||||
//
|
||||
// deserialize(JsonDocument&, std::istream&, NestingLimit, Filter);
|
||||
// deserialize(JsonDocument&, Stream&, NestingLimit, Filter);
|
||||
template <template <typename, typename> class TDeserializer, typename TStream,
|
||||
typename TFilter>
|
||||
DeserializationError deserialize(JsonDocument &doc, TStream &input,
|
||||
NestingLimit nestingLimit, TFilter filter) {
|
||||
Reader<TStream> reader(input);
|
||||
doc.clear();
|
||||
return makeDeserializer<TDeserializer>(doc.memoryPool(), reader,
|
||||
makeStringStorage(input))
|
||||
.parse(doc.data(), filter, nestingLimit);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,164 +1,164 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Helper to implement the "base-from-member" idiom
|
||||
// (we need to store the allocator before constructing JsonDocument)
|
||||
template <typename TAllocator>
|
||||
class AllocatorOwner {
|
||||
public:
|
||||
AllocatorOwner() {}
|
||||
AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {}
|
||||
AllocatorOwner(TAllocator a) : _allocator(a) {}
|
||||
|
||||
void* allocate(size_t size) {
|
||||
return _allocator.allocate(size);
|
||||
}
|
||||
|
||||
void deallocate(void* ptr) {
|
||||
if (ptr)
|
||||
_allocator.deallocate(ptr);
|
||||
}
|
||||
|
||||
void* reallocate(void* ptr, size_t new_size) {
|
||||
return _allocator.reallocate(ptr, new_size);
|
||||
}
|
||||
|
||||
TAllocator& allocator() {
|
||||
return _allocator;
|
||||
}
|
||||
|
||||
private:
|
||||
TAllocator _allocator;
|
||||
};
|
||||
|
||||
template <typename TAllocator>
|
||||
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
|
||||
public:
|
||||
explicit BasicJsonDocument(size_t capa, TAllocator alloc = TAllocator())
|
||||
: AllocatorOwner<TAllocator>(alloc), JsonDocument(allocPool(capa)) {}
|
||||
|
||||
// Copy-constructor
|
||||
BasicJsonDocument(const BasicJsonDocument& src)
|
||||
: AllocatorOwner<TAllocator>(src), JsonDocument() {
|
||||
copyAssignFrom(src);
|
||||
}
|
||||
|
||||
// Move-constructor
|
||||
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
||||
BasicJsonDocument(BasicJsonDocument&& src) : AllocatorOwner<TAllocator>(src) {
|
||||
moveAssignFrom(src);
|
||||
}
|
||||
#endif
|
||||
|
||||
BasicJsonDocument(const JsonDocument& src) {
|
||||
copyAssignFrom(src);
|
||||
}
|
||||
|
||||
// Construct from variant, array, or object
|
||||
template <typename T>
|
||||
BasicJsonDocument(
|
||||
const T& src,
|
||||
typename enable_if<
|
||||
is_same<T, VariantRef>::value || is_same<T, VariantConstRef>::value ||
|
||||
is_same<T, ArrayRef>::value || is_same<T, ArrayConstRef>::value ||
|
||||
is_same<T, ObjectRef>::value ||
|
||||
is_same<T, ObjectConstRef>::value>::type* = 0)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
// disambiguate
|
||||
BasicJsonDocument(VariantRef src)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
~BasicJsonDocument() {
|
||||
freePool();
|
||||
}
|
||||
|
||||
BasicJsonDocument& operator=(const BasicJsonDocument& src) {
|
||||
copyAssignFrom(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
||||
BasicJsonDocument& operator=(BasicJsonDocument&& src) {
|
||||
moveAssignFrom(src);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
BasicJsonDocument& operator=(const T& src) {
|
||||
reallocPoolIfTooSmall(src.memoryUsage());
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void shrinkToFit() {
|
||||
ptrdiff_t bytes_reclaimed = _pool.squash();
|
||||
if (bytes_reclaimed == 0)
|
||||
return;
|
||||
|
||||
void* old_ptr = _pool.buffer();
|
||||
void* new_ptr = this->reallocate(old_ptr, _pool.capacity());
|
||||
|
||||
ptrdiff_t ptr_offset =
|
||||
static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr);
|
||||
|
||||
_pool.movePointers(ptr_offset);
|
||||
_data.movePointers(ptr_offset, ptr_offset - bytes_reclaimed);
|
||||
}
|
||||
|
||||
bool garbageCollect() {
|
||||
// make a temporary clone and move assign
|
||||
BasicJsonDocument tmp(*this);
|
||||
if (!tmp.capacity())
|
||||
return false;
|
||||
tmp.set(*this);
|
||||
moveAssignFrom(tmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
using AllocatorOwner<TAllocator>::allocator;
|
||||
|
||||
private:
|
||||
MemoryPool allocPool(size_t requiredSize) {
|
||||
size_t capa = addPadding(requiredSize);
|
||||
return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa);
|
||||
}
|
||||
|
||||
void reallocPoolIfTooSmall(size_t requiredSize) {
|
||||
if (requiredSize <= capacity())
|
||||
return;
|
||||
freePool();
|
||||
replacePool(allocPool(addPadding(requiredSize)));
|
||||
}
|
||||
|
||||
void freePool() {
|
||||
this->deallocate(memoryPool().buffer());
|
||||
}
|
||||
|
||||
void copyAssignFrom(const JsonDocument& src) {
|
||||
reallocPoolIfTooSmall(src.capacity());
|
||||
set(src);
|
||||
}
|
||||
|
||||
void moveAssignFrom(BasicJsonDocument& src) {
|
||||
freePool();
|
||||
_data = src._data;
|
||||
_pool = src._pool;
|
||||
src._data.setNull();
|
||||
src._pool = MemoryPool(0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Helper to implement the "base-from-member" idiom
|
||||
// (we need to store the allocator before constructing JsonDocument)
|
||||
template <typename TAllocator>
|
||||
class AllocatorOwner {
|
||||
public:
|
||||
AllocatorOwner() {}
|
||||
AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {}
|
||||
AllocatorOwner(TAllocator a) : _allocator(a) {}
|
||||
|
||||
void* allocate(size_t size) {
|
||||
return _allocator.allocate(size);
|
||||
}
|
||||
|
||||
void deallocate(void* ptr) {
|
||||
if (ptr)
|
||||
_allocator.deallocate(ptr);
|
||||
}
|
||||
|
||||
void* reallocate(void* ptr, size_t new_size) {
|
||||
return _allocator.reallocate(ptr, new_size);
|
||||
}
|
||||
|
||||
TAllocator& allocator() {
|
||||
return _allocator;
|
||||
}
|
||||
|
||||
private:
|
||||
TAllocator _allocator;
|
||||
};
|
||||
|
||||
template <typename TAllocator>
|
||||
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
|
||||
public:
|
||||
explicit BasicJsonDocument(size_t capa, TAllocator alloc = TAllocator())
|
||||
: AllocatorOwner<TAllocator>(alloc), JsonDocument(allocPool(capa)) {}
|
||||
|
||||
// Copy-constructor
|
||||
BasicJsonDocument(const BasicJsonDocument& src)
|
||||
: AllocatorOwner<TAllocator>(src), JsonDocument() {
|
||||
copyAssignFrom(src);
|
||||
}
|
||||
|
||||
// Move-constructor
|
||||
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
||||
BasicJsonDocument(BasicJsonDocument&& src) : AllocatorOwner<TAllocator>(src) {
|
||||
moveAssignFrom(src);
|
||||
}
|
||||
#endif
|
||||
|
||||
BasicJsonDocument(const JsonDocument& src) {
|
||||
copyAssignFrom(src);
|
||||
}
|
||||
|
||||
// Construct from variant, array, or object
|
||||
template <typename T>
|
||||
BasicJsonDocument(
|
||||
const T& src,
|
||||
typename enable_if<
|
||||
is_same<T, VariantRef>::value || is_same<T, VariantConstRef>::value ||
|
||||
is_same<T, ArrayRef>::value || is_same<T, ArrayConstRef>::value ||
|
||||
is_same<T, ObjectRef>::value ||
|
||||
is_same<T, ObjectConstRef>::value>::type* = 0)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
// disambiguate
|
||||
BasicJsonDocument(VariantRef src)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
~BasicJsonDocument() {
|
||||
freePool();
|
||||
}
|
||||
|
||||
BasicJsonDocument& operator=(const BasicJsonDocument& src) {
|
||||
copyAssignFrom(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
||||
BasicJsonDocument& operator=(BasicJsonDocument&& src) {
|
||||
moveAssignFrom(src);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
BasicJsonDocument& operator=(const T& src) {
|
||||
reallocPoolIfTooSmall(src.memoryUsage());
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void shrinkToFit() {
|
||||
ptrdiff_t bytes_reclaimed = _pool.squash();
|
||||
if (bytes_reclaimed == 0)
|
||||
return;
|
||||
|
||||
void* old_ptr = _pool.buffer();
|
||||
void* new_ptr = this->reallocate(old_ptr, _pool.capacity());
|
||||
|
||||
ptrdiff_t ptr_offset =
|
||||
static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr);
|
||||
|
||||
_pool.movePointers(ptr_offset);
|
||||
_data.movePointers(ptr_offset, ptr_offset - bytes_reclaimed);
|
||||
}
|
||||
|
||||
bool garbageCollect() {
|
||||
// make a temporary clone and move assign
|
||||
BasicJsonDocument tmp(*this);
|
||||
if (!tmp.capacity())
|
||||
return false;
|
||||
tmp.set(*this);
|
||||
moveAssignFrom(tmp);
|
||||
return true;
|
||||
}
|
||||
|
||||
using AllocatorOwner<TAllocator>::allocator;
|
||||
|
||||
private:
|
||||
MemoryPool allocPool(size_t requiredSize) {
|
||||
size_t capa = addPadding(requiredSize);
|
||||
return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa);
|
||||
}
|
||||
|
||||
void reallocPoolIfTooSmall(size_t requiredSize) {
|
||||
if (requiredSize <= capacity())
|
||||
return;
|
||||
freePool();
|
||||
replacePool(allocPool(addPadding(requiredSize)));
|
||||
}
|
||||
|
||||
void freePool() {
|
||||
this->deallocate(memoryPool().buffer());
|
||||
}
|
||||
|
||||
void copyAssignFrom(const JsonDocument& src) {
|
||||
reallocPoolIfTooSmall(src.capacity());
|
||||
set(src);
|
||||
}
|
||||
|
||||
void moveAssignFrom(BasicJsonDocument& src) {
|
||||
freePool();
|
||||
_data = src._data;
|
||||
_pool = src._pool;
|
||||
src._data.setNull();
|
||||
src._pool = MemoryPool(0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,29 +1,29 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Document/BasicJsonDocument.hpp>
|
||||
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
struct DefaultAllocator {
|
||||
void* allocate(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void* ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void* reallocate(void* ptr, size_t new_size) {
|
||||
return realloc(ptr, new_size);
|
||||
}
|
||||
};
|
||||
|
||||
typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument;
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Document/BasicJsonDocument.hpp>
|
||||
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
struct DefaultAllocator {
|
||||
void* allocate(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void deallocate(void* ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void* reallocate(void* ptr, size_t new_size) {
|
||||
return realloc(ptr, new_size);
|
||||
}
|
||||
};
|
||||
|
||||
typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument;
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,328 +1,328 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ElementProxy.hpp>
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/Object/MemberProxy.hpp>
|
||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class JsonDocument : public Visitable {
|
||||
public:
|
||||
template <typename Visitor>
|
||||
void accept(Visitor& visitor) const {
|
||||
return getVariant().accept(visitor);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename VariantAs<T>::type as() {
|
||||
return getVariant().template as<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename VariantConstAs<T>::type as() const {
|
||||
return getVariant().template as<T>();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_pool.clear();
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return getVariant().template is<T>();
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return getVariant().isNull();
|
||||
}
|
||||
|
||||
size_t memoryUsage() const {
|
||||
return _pool.size();
|
||||
}
|
||||
|
||||
size_t nesting() const {
|
||||
return _data.nesting();
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
return _pool.capacity();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
bool set(const JsonDocument& src) {
|
||||
return to<VariantRef>().set(src.as<VariantRef>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<!is_base_of<JsonDocument, T>::value, bool>::type set(
|
||||
const T& src) {
|
||||
return to<VariantRef>().set(src);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename VariantTo<T>::type to() {
|
||||
clear();
|
||||
return getVariant().template to<T>();
|
||||
}
|
||||
|
||||
// for internal use only
|
||||
MemoryPool& memoryPool() {
|
||||
return _pool;
|
||||
}
|
||||
|
||||
VariantData& data() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
ArrayRef createNestedArray() {
|
||||
return addElement().to<ArrayRef>();
|
||||
}
|
||||
|
||||
// createNestedArray(char*)
|
||||
// createNestedArray(const char*)
|
||||
// createNestedArray(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
ArrayRef createNestedArray(TChar* key) {
|
||||
return getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
// createNestedArray(const std::string&)
|
||||
// createNestedArray(const String&)
|
||||
template <typename TString>
|
||||
ArrayRef createNestedArray(const TString& key) {
|
||||
return getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
ObjectRef createNestedObject() {
|
||||
return addElement().to<ObjectRef>();
|
||||
}
|
||||
|
||||
// createNestedObject(char*)
|
||||
// createNestedObject(const char*)
|
||||
// createNestedObject(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
ObjectRef createNestedObject(TChar* key) {
|
||||
return getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
// createNestedObject(const std::string&)
|
||||
// createNestedObject(const String&)
|
||||
template <typename TString>
|
||||
ObjectRef createNestedObject(const TString& key) {
|
||||
return getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
bool containsKey(TChar* key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
bool containsKey(const TString& key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// operator[](const std::string&)
|
||||
// operator[](const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<JsonDocument&, TString> >::type
|
||||
operator[](const TString& key) {
|
||||
return MemberProxy<JsonDocument&, TString>(*this, key);
|
||||
}
|
||||
|
||||
// operator[](char*)
|
||||
// operator[](const char*)
|
||||
// operator[](const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value,
|
||||
MemberProxy<JsonDocument&, TChar*> >::type
|
||||
operator[](TChar* key) {
|
||||
return MemberProxy<JsonDocument&, TChar*>(*this, key);
|
||||
}
|
||||
|
||||
// operator[](const std::string&) const
|
||||
// operator[](const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
operator[](const TString& key) const {
|
||||
return getMember(key);
|
||||
}
|
||||
|
||||
// operator[](char*) const
|
||||
// operator[](const char*) const
|
||||
// operator[](const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
||||
operator[](TChar* key) const {
|
||||
return getMember(key);
|
||||
}
|
||||
|
||||
FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
|
||||
return ElementProxy<JsonDocument&>(*this, index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getElement(size_t index) {
|
||||
return VariantRef(&_pool, _data.getElement(index));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data.getElement(index));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) {
|
||||
return VariantRef(&_pool, _data.getOrAddElement(index, &_pool));
|
||||
}
|
||||
|
||||
// JsonVariantConst getMember(char*) const
|
||||
// JsonVariantConst getMember(const char*) const
|
||||
// JsonVariantConst getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariantConst getMember(const std::string&) const
|
||||
// JsonVariantConst getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
getMember(const TString& key) const {
|
||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariant getMember(char*)
|
||||
// JsonVariant getMember(const char*)
|
||||
// JsonVariant getMember(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getMember(TChar* key) {
|
||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariant getMember(const std::string&)
|
||||
// JsonVariant getMember(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
|
||||
getMember(const TString& key) {
|
||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// getOrAddMember(char*)
|
||||
// getOrAddMember(const char*)
|
||||
// getOrAddMember(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) {
|
||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||
}
|
||||
|
||||
// getOrAddMember(const std::string&)
|
||||
// getOrAddMember(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) {
|
||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef addElement() {
|
||||
return VariantRef(&_pool, _data.addElement(&_pool));
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool add(const TValue& value) {
|
||||
return addElement().set(value);
|
||||
}
|
||||
|
||||
// add(char*) const
|
||||
// add(const char*) const
|
||||
// add(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool add(TChar* value) {
|
||||
return addElement().set(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) {
|
||||
_data.remove(index);
|
||||
}
|
||||
// remove(char*)
|
||||
// remove(const char*)
|
||||
// remove(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||
TChar* key) {
|
||||
_data.remove(adaptString(key));
|
||||
}
|
||||
// remove(const std::string&)
|
||||
// remove(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString& key) {
|
||||
_data.remove(adaptString(key));
|
||||
}
|
||||
|
||||
FORCE_INLINE operator VariantConstRef() const {
|
||||
return VariantConstRef(&_data);
|
||||
}
|
||||
|
||||
bool operator==(VariantConstRef rhs) const {
|
||||
return getVariant() == rhs;
|
||||
}
|
||||
|
||||
bool operator!=(VariantConstRef rhs) const {
|
||||
return getVariant() != rhs;
|
||||
}
|
||||
|
||||
protected:
|
||||
JsonDocument() : _pool(0, 0) {
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
JsonDocument(MemoryPool pool) : _pool(pool) {
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
void replacePool(MemoryPool pool) {
|
||||
_pool = pool;
|
||||
}
|
||||
|
||||
VariantRef getVariant() {
|
||||
return VariantRef(&_pool, &_data);
|
||||
}
|
||||
|
||||
VariantConstRef getVariant() const {
|
||||
return VariantConstRef(&_data);
|
||||
}
|
||||
|
||||
MemoryPool _pool;
|
||||
VariantData _data;
|
||||
|
||||
private:
|
||||
JsonDocument(const JsonDocument&);
|
||||
JsonDocument& operator=(const JsonDocument&);
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ElementProxy.hpp>
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/Object/MemberProxy.hpp>
|
||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class JsonDocument : public Visitable {
|
||||
public:
|
||||
template <typename Visitor>
|
||||
void accept(Visitor& visitor) const {
|
||||
return getVariant().accept(visitor);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename VariantAs<T>::type as() {
|
||||
return getVariant().template as<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename VariantConstAs<T>::type as() const {
|
||||
return getVariant().template as<T>();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_pool.clear();
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return getVariant().template is<T>();
|
||||
}
|
||||
|
||||
bool isNull() const {
|
||||
return getVariant().isNull();
|
||||
}
|
||||
|
||||
size_t memoryUsage() const {
|
||||
return _pool.size();
|
||||
}
|
||||
|
||||
size_t nesting() const {
|
||||
return _data.nesting();
|
||||
}
|
||||
|
||||
size_t capacity() const {
|
||||
return _pool.capacity();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
bool set(const JsonDocument& src) {
|
||||
return to<VariantRef>().set(src.as<VariantRef>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<!is_base_of<JsonDocument, T>::value, bool>::type set(
|
||||
const T& src) {
|
||||
return to<VariantRef>().set(src);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename VariantTo<T>::type to() {
|
||||
clear();
|
||||
return getVariant().template to<T>();
|
||||
}
|
||||
|
||||
// for internal use only
|
||||
MemoryPool& memoryPool() {
|
||||
return _pool;
|
||||
}
|
||||
|
||||
VariantData& data() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
ArrayRef createNestedArray() {
|
||||
return addElement().to<ArrayRef>();
|
||||
}
|
||||
|
||||
// createNestedArray(char*)
|
||||
// createNestedArray(const char*)
|
||||
// createNestedArray(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
ArrayRef createNestedArray(TChar* key) {
|
||||
return getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
// createNestedArray(const std::string&)
|
||||
// createNestedArray(const String&)
|
||||
template <typename TString>
|
||||
ArrayRef createNestedArray(const TString& key) {
|
||||
return getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
ObjectRef createNestedObject() {
|
||||
return addElement().to<ObjectRef>();
|
||||
}
|
||||
|
||||
// createNestedObject(char*)
|
||||
// createNestedObject(const char*)
|
||||
// createNestedObject(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
ObjectRef createNestedObject(TChar* key) {
|
||||
return getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
// createNestedObject(const std::string&)
|
||||
// createNestedObject(const String&)
|
||||
template <typename TString>
|
||||
ObjectRef createNestedObject(const TString& key) {
|
||||
return getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
bool containsKey(TChar* key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
bool containsKey(const TString& key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// operator[](const std::string&)
|
||||
// operator[](const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<JsonDocument&, TString> >::type
|
||||
operator[](const TString& key) {
|
||||
return MemberProxy<JsonDocument&, TString>(*this, key);
|
||||
}
|
||||
|
||||
// operator[](char*)
|
||||
// operator[](const char*)
|
||||
// operator[](const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value,
|
||||
MemberProxy<JsonDocument&, TChar*> >::type
|
||||
operator[](TChar* key) {
|
||||
return MemberProxy<JsonDocument&, TChar*>(*this, key);
|
||||
}
|
||||
|
||||
// operator[](const std::string&) const
|
||||
// operator[](const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
operator[](const TString& key) const {
|
||||
return getMember(key);
|
||||
}
|
||||
|
||||
// operator[](char*) const
|
||||
// operator[](const char*) const
|
||||
// operator[](const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
||||
operator[](TChar* key) const {
|
||||
return getMember(key);
|
||||
}
|
||||
|
||||
FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
|
||||
return ElementProxy<JsonDocument&>(*this, index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getElement(size_t index) {
|
||||
return VariantRef(&_pool, _data.getElement(index));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data.getElement(index));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) {
|
||||
return VariantRef(&_pool, _data.getOrAddElement(index, &_pool));
|
||||
}
|
||||
|
||||
// JsonVariantConst getMember(char*) const
|
||||
// JsonVariantConst getMember(const char*) const
|
||||
// JsonVariantConst getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariantConst getMember(const std::string&) const
|
||||
// JsonVariantConst getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
getMember(const TString& key) const {
|
||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariant getMember(char*)
|
||||
// JsonVariant getMember(const char*)
|
||||
// JsonVariant getMember(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getMember(TChar* key) {
|
||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariant getMember(const std::string&)
|
||||
// JsonVariant getMember(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
|
||||
getMember(const TString& key) {
|
||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// getOrAddMember(char*)
|
||||
// getOrAddMember(const char*)
|
||||
// getOrAddMember(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) {
|
||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||
}
|
||||
|
||||
// getOrAddMember(const std::string&)
|
||||
// getOrAddMember(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) {
|
||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef addElement() {
|
||||
return VariantRef(&_pool, _data.addElement(&_pool));
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool add(const TValue& value) {
|
||||
return addElement().set(value);
|
||||
}
|
||||
|
||||
// add(char*) const
|
||||
// add(const char*) const
|
||||
// add(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool add(TChar* value) {
|
||||
return addElement().set(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) {
|
||||
_data.remove(index);
|
||||
}
|
||||
// remove(char*)
|
||||
// remove(const char*)
|
||||
// remove(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||
TChar* key) {
|
||||
_data.remove(adaptString(key));
|
||||
}
|
||||
// remove(const std::string&)
|
||||
// remove(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString& key) {
|
||||
_data.remove(adaptString(key));
|
||||
}
|
||||
|
||||
FORCE_INLINE operator VariantConstRef() const {
|
||||
return VariantConstRef(&_data);
|
||||
}
|
||||
|
||||
bool operator==(VariantConstRef rhs) const {
|
||||
return getVariant() == rhs;
|
||||
}
|
||||
|
||||
bool operator!=(VariantConstRef rhs) const {
|
||||
return getVariant() != rhs;
|
||||
}
|
||||
|
||||
protected:
|
||||
JsonDocument() : _pool(0, 0) {
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
JsonDocument(MemoryPool pool) : _pool(pool) {
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
|
||||
_data.setNull();
|
||||
}
|
||||
|
||||
void replacePool(MemoryPool pool) {
|
||||
_pool = pool;
|
||||
}
|
||||
|
||||
VariantRef getVariant() {
|
||||
return VariantRef(&_pool, &_data);
|
||||
}
|
||||
|
||||
VariantConstRef getVariant() const {
|
||||
return VariantConstRef(&_data);
|
||||
}
|
||||
|
||||
MemoryPool _pool;
|
||||
VariantData _data;
|
||||
|
||||
private:
|
||||
JsonDocument(const JsonDocument&);
|
||||
JsonDocument& operator=(const JsonDocument&);
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,56 +1,56 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <size_t desiredCapacity>
|
||||
class StaticJsonDocument : public JsonDocument {
|
||||
static const size_t _capacity =
|
||||
AddPadding<Max<1, desiredCapacity>::value>::value;
|
||||
|
||||
public:
|
||||
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {}
|
||||
|
||||
StaticJsonDocument(const StaticJsonDocument& src)
|
||||
: JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StaticJsonDocument(const T& src,
|
||||
typename enable_if<IsVisitable<T>::value>::type* = 0)
|
||||
: JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
// disambiguate
|
||||
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
StaticJsonDocument operator=(const StaticJsonDocument& src) {
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StaticJsonDocument operator=(const T& src) {
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void garbageCollect() {
|
||||
StaticJsonDocument tmp(*this);
|
||||
set(tmp);
|
||||
}
|
||||
|
||||
private:
|
||||
char _buffer[_capacity];
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <size_t desiredCapacity>
|
||||
class StaticJsonDocument : public JsonDocument {
|
||||
static const size_t _capacity =
|
||||
AddPadding<Max<1, desiredCapacity>::value>::value;
|
||||
|
||||
public:
|
||||
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {}
|
||||
|
||||
StaticJsonDocument(const StaticJsonDocument& src)
|
||||
: JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StaticJsonDocument(const T& src,
|
||||
typename enable_if<IsVisitable<T>::value>::type* = 0)
|
||||
: JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
// disambiguate
|
||||
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
StaticJsonDocument operator=(const StaticJsonDocument& src) {
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StaticJsonDocument operator=(const T& src) {
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void garbageCollect() {
|
||||
StaticJsonDocument tmp(*this);
|
||||
set(tmp);
|
||||
}
|
||||
|
||||
private:
|
||||
char _buffer[_capacity];
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,39 +1,39 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class EscapeSequence {
|
||||
public:
|
||||
// Optimized for code size on a 8-bit AVR
|
||||
static char escapeChar(char c) {
|
||||
const char *p = escapeTable(true);
|
||||
while (p[0] && p[1] != c) {
|
||||
p += 2;
|
||||
}
|
||||
return p[0];
|
||||
}
|
||||
|
||||
// Optimized for code size on a 8-bit AVR
|
||||
static char unescapeChar(char c) {
|
||||
const char *p = escapeTable(false);
|
||||
for (;;) {
|
||||
if (p[0] == '\0')
|
||||
return 0;
|
||||
if (p[0] == c)
|
||||
return p[1];
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static const char *escapeTable(bool excludeSolidus) {
|
||||
return &"//\"\"\\\\b\bf\fn\nr\rt\t"[excludeSolidus ? 2 : 0];
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class EscapeSequence {
|
||||
public:
|
||||
// Optimized for code size on a 8-bit AVR
|
||||
static char escapeChar(char c) {
|
||||
const char *p = escapeTable(true);
|
||||
while (p[0] && p[1] != c) {
|
||||
p += 2;
|
||||
}
|
||||
return p[0];
|
||||
}
|
||||
|
||||
// Optimized for code size on a 8-bit AVR
|
||||
static char unescapeChar(char c) {
|
||||
const char *p = escapeTable(false);
|
||||
for (;;) {
|
||||
if (p[0] == '\0')
|
||||
return 0;
|
||||
if (p[0] == c)
|
||||
return p[1];
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static const char *escapeTable(bool excludeSolidus) {
|
||||
return &"//\"\"\\\\b\bf\fn\nr\rt\t"[excludeSolidus ? 2 : 0];
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,126 +1,126 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Json/TextFormatter.hpp>
|
||||
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||
#include <ArduinoJson/Serialization/measure.hpp>
|
||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class JsonSerializer {
|
||||
public:
|
||||
JsonSerializer(TWriter writer) : _formatter(writer) {}
|
||||
|
||||
FORCE_INLINE void visitArray(const CollectionData &array) {
|
||||
write('[');
|
||||
|
||||
VariantSlot *slot = array.head();
|
||||
|
||||
while (slot != 0) {
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
if (slot == 0)
|
||||
break;
|
||||
|
||||
write(',');
|
||||
}
|
||||
|
||||
write(']');
|
||||
}
|
||||
|
||||
void visitObject(const CollectionData &object) {
|
||||
write('{');
|
||||
|
||||
VariantSlot *slot = object.head();
|
||||
|
||||
while (slot != 0) {
|
||||
_formatter.writeString(slot->key());
|
||||
write(':');
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
if (slot == 0)
|
||||
break;
|
||||
|
||||
write(',');
|
||||
}
|
||||
|
||||
write('}');
|
||||
}
|
||||
|
||||
void visitFloat(Float value) {
|
||||
_formatter.writeFloat(value);
|
||||
}
|
||||
|
||||
void visitString(const char *value) {
|
||||
_formatter.writeString(value);
|
||||
}
|
||||
|
||||
void visitRawJson(const char *data, size_t n) {
|
||||
_formatter.writeRaw(data, n);
|
||||
}
|
||||
|
||||
void visitNegativeInteger(UInt value) {
|
||||
_formatter.writeNegativeInteger(value);
|
||||
}
|
||||
|
||||
void visitPositiveInteger(UInt value) {
|
||||
_formatter.writePositiveInteger(value);
|
||||
}
|
||||
|
||||
void visitBoolean(bool value) {
|
||||
_formatter.writeBoolean(value);
|
||||
}
|
||||
|
||||
void visitNull() {
|
||||
_formatter.writeRaw("null");
|
||||
}
|
||||
|
||||
size_t bytesWritten() const {
|
||||
return _formatter.bytesWritten();
|
||||
}
|
||||
|
||||
protected:
|
||||
void write(char c) {
|
||||
_formatter.writeRaw(c);
|
||||
}
|
||||
|
||||
void write(const char *s) {
|
||||
_formatter.writeRaw(s);
|
||||
}
|
||||
|
||||
private:
|
||||
TextFormatter<TWriter> _formatter;
|
||||
};
|
||||
|
||||
template <typename TSource, typename TDestination>
|
||||
size_t serializeJson(const TSource &source, TDestination &destination) {
|
||||
return serialize<JsonSerializer>(source, destination);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t serializeJson(const TSource &source, void *buffer, size_t bufferSize) {
|
||||
return serialize<JsonSerializer>(source, buffer, bufferSize);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t measureJson(const TSource &source) {
|
||||
return measure<JsonSerializer>(source);
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
template <typename T>
|
||||
inline typename enable_if<IsVisitable<T>::value, std::ostream &>::type
|
||||
operator<<(std::ostream &os, const T &source) {
|
||||
serializeJson(source, os);
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Json/TextFormatter.hpp>
|
||||
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||
#include <ArduinoJson/Serialization/measure.hpp>
|
||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class JsonSerializer {
|
||||
public:
|
||||
JsonSerializer(TWriter writer) : _formatter(writer) {}
|
||||
|
||||
FORCE_INLINE void visitArray(const CollectionData &array) {
|
||||
write('[');
|
||||
|
||||
VariantSlot *slot = array.head();
|
||||
|
||||
while (slot != 0) {
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
if (slot == 0)
|
||||
break;
|
||||
|
||||
write(',');
|
||||
}
|
||||
|
||||
write(']');
|
||||
}
|
||||
|
||||
void visitObject(const CollectionData &object) {
|
||||
write('{');
|
||||
|
||||
VariantSlot *slot = object.head();
|
||||
|
||||
while (slot != 0) {
|
||||
_formatter.writeString(slot->key());
|
||||
write(':');
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
if (slot == 0)
|
||||
break;
|
||||
|
||||
write(',');
|
||||
}
|
||||
|
||||
write('}');
|
||||
}
|
||||
|
||||
void visitFloat(Float value) {
|
||||
_formatter.writeFloat(value);
|
||||
}
|
||||
|
||||
void visitString(const char *value) {
|
||||
_formatter.writeString(value);
|
||||
}
|
||||
|
||||
void visitRawJson(const char *data, size_t n) {
|
||||
_formatter.writeRaw(data, n);
|
||||
}
|
||||
|
||||
void visitNegativeInteger(UInt value) {
|
||||
_formatter.writeNegativeInteger(value);
|
||||
}
|
||||
|
||||
void visitPositiveInteger(UInt value) {
|
||||
_formatter.writePositiveInteger(value);
|
||||
}
|
||||
|
||||
void visitBoolean(bool value) {
|
||||
_formatter.writeBoolean(value);
|
||||
}
|
||||
|
||||
void visitNull() {
|
||||
_formatter.writeRaw("null");
|
||||
}
|
||||
|
||||
size_t bytesWritten() const {
|
||||
return _formatter.bytesWritten();
|
||||
}
|
||||
|
||||
protected:
|
||||
void write(char c) {
|
||||
_formatter.writeRaw(c);
|
||||
}
|
||||
|
||||
void write(const char *s) {
|
||||
_formatter.writeRaw(s);
|
||||
}
|
||||
|
||||
private:
|
||||
TextFormatter<TWriter> _formatter;
|
||||
};
|
||||
|
||||
template <typename TSource, typename TDestination>
|
||||
size_t serializeJson(const TSource &source, TDestination &destination) {
|
||||
return serialize<JsonSerializer>(source, destination);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t serializeJson(const TSource &source, void *buffer, size_t bufferSize) {
|
||||
return serialize<JsonSerializer>(source, buffer, bufferSize);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t measureJson(const TSource &source) {
|
||||
return measure<JsonSerializer>(source);
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
template <typename T>
|
||||
inline typename enable_if<IsVisitable<T>::value, std::ostream &>::type
|
||||
operator<<(std::ostream &os, const T &source) {
|
||||
serializeJson(source, os);
|
||||
return os;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,55 +1,55 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TReader>
|
||||
class Latch {
|
||||
public:
|
||||
Latch(TReader reader) : _reader(reader), _loaded(false) {
|
||||
#if ARDUINOJSON_DEBUG
|
||||
_ended = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_loaded = false;
|
||||
}
|
||||
|
||||
int last() const {
|
||||
return _current;
|
||||
}
|
||||
|
||||
FORCE_INLINE char current() {
|
||||
if (!_loaded) {
|
||||
load();
|
||||
}
|
||||
return _current;
|
||||
}
|
||||
|
||||
private:
|
||||
void load() {
|
||||
ARDUINOJSON_ASSERT(!_ended);
|
||||
int c = _reader.read();
|
||||
#if ARDUINOJSON_DEBUG
|
||||
if (c <= 0)
|
||||
_ended = true;
|
||||
#endif
|
||||
_current = static_cast<char>(c > 0 ? c : 0);
|
||||
_loaded = true;
|
||||
}
|
||||
|
||||
TReader _reader;
|
||||
char _current;
|
||||
bool _loaded;
|
||||
#if ARDUINOJSON_DEBUG
|
||||
bool _ended;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TReader>
|
||||
class Latch {
|
||||
public:
|
||||
Latch(TReader reader) : _reader(reader), _loaded(false) {
|
||||
#if ARDUINOJSON_DEBUG
|
||||
_ended = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_loaded = false;
|
||||
}
|
||||
|
||||
int last() const {
|
||||
return _current;
|
||||
}
|
||||
|
||||
FORCE_INLINE char current() {
|
||||
if (!_loaded) {
|
||||
load();
|
||||
}
|
||||
return _current;
|
||||
}
|
||||
|
||||
private:
|
||||
void load() {
|
||||
ARDUINOJSON_ASSERT(!_ended);
|
||||
int c = _reader.read();
|
||||
#if ARDUINOJSON_DEBUG
|
||||
if (c <= 0)
|
||||
_ended = true;
|
||||
#endif
|
||||
_current = static_cast<char>(c > 0 ? c : 0);
|
||||
_loaded = true;
|
||||
}
|
||||
|
||||
TReader _reader;
|
||||
char _current;
|
||||
bool _loaded;
|
||||
#if ARDUINOJSON_DEBUG
|
||||
bool _ended;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,85 +1,85 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Json/JsonSerializer.hpp>
|
||||
#include <ArduinoJson/Serialization/measure.hpp>
|
||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||
typedef JsonSerializer<TWriter> base;
|
||||
|
||||
public:
|
||||
PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {}
|
||||
|
||||
void visitArray(const CollectionData &array) {
|
||||
VariantSlot *slot = array.head();
|
||||
if (!slot)
|
||||
return base::write("[]");
|
||||
|
||||
base::write("[\r\n");
|
||||
_nesting++;
|
||||
while (slot != 0) {
|
||||
indent();
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
base::write(slot ? ",\r\n" : "\r\n");
|
||||
}
|
||||
_nesting--;
|
||||
indent();
|
||||
base::write("]");
|
||||
}
|
||||
|
||||
void visitObject(const CollectionData &object) {
|
||||
VariantSlot *slot = object.head();
|
||||
if (!slot)
|
||||
return base::write("{}");
|
||||
|
||||
base::write("{\r\n");
|
||||
_nesting++;
|
||||
while (slot != 0) {
|
||||
indent();
|
||||
base::visitString(slot->key());
|
||||
base::write(": ");
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
base::write(slot ? ",\r\n" : "\r\n");
|
||||
}
|
||||
_nesting--;
|
||||
indent();
|
||||
base::write("}");
|
||||
}
|
||||
|
||||
private:
|
||||
void indent() {
|
||||
for (uint8_t i = 0; i < _nesting; i++) base::write(ARDUINOJSON_TAB);
|
||||
}
|
||||
|
||||
uint8_t _nesting;
|
||||
};
|
||||
|
||||
template <typename TSource, typename TDestination>
|
||||
size_t serializeJsonPretty(const TSource &source, TDestination &destination) {
|
||||
return serialize<PrettyJsonSerializer>(source, destination);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t serializeJsonPretty(const TSource &source, void *buffer,
|
||||
size_t bufferSize) {
|
||||
return serialize<PrettyJsonSerializer>(source, buffer, bufferSize);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t measureJsonPretty(const TSource &source) {
|
||||
return measure<PrettyJsonSerializer>(source);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Json/JsonSerializer.hpp>
|
||||
#include <ArduinoJson/Serialization/measure.hpp>
|
||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||
typedef JsonSerializer<TWriter> base;
|
||||
|
||||
public:
|
||||
PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {}
|
||||
|
||||
void visitArray(const CollectionData &array) {
|
||||
VariantSlot *slot = array.head();
|
||||
if (!slot)
|
||||
return base::write("[]");
|
||||
|
||||
base::write("[\r\n");
|
||||
_nesting++;
|
||||
while (slot != 0) {
|
||||
indent();
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
base::write(slot ? ",\r\n" : "\r\n");
|
||||
}
|
||||
_nesting--;
|
||||
indent();
|
||||
base::write("]");
|
||||
}
|
||||
|
||||
void visitObject(const CollectionData &object) {
|
||||
VariantSlot *slot = object.head();
|
||||
if (!slot)
|
||||
return base::write("{}");
|
||||
|
||||
base::write("{\r\n");
|
||||
_nesting++;
|
||||
while (slot != 0) {
|
||||
indent();
|
||||
base::visitString(slot->key());
|
||||
base::write(": ");
|
||||
slot->data()->accept(*this);
|
||||
|
||||
slot = slot->next();
|
||||
base::write(slot ? ",\r\n" : "\r\n");
|
||||
}
|
||||
_nesting--;
|
||||
indent();
|
||||
base::write("}");
|
||||
}
|
||||
|
||||
private:
|
||||
void indent() {
|
||||
for (uint8_t i = 0; i < _nesting; i++) base::write(ARDUINOJSON_TAB);
|
||||
}
|
||||
|
||||
uint8_t _nesting;
|
||||
};
|
||||
|
||||
template <typename TSource, typename TDestination>
|
||||
size_t serializeJsonPretty(const TSource &source, TDestination &destination) {
|
||||
return serialize<PrettyJsonSerializer>(source, destination);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t serializeJsonPretty(const TSource &source, void *buffer,
|
||||
size_t bufferSize) {
|
||||
return serialize<PrettyJsonSerializer>(source, buffer, bufferSize);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
size_t measureJsonPretty(const TSource &source) {
|
||||
return measure<PrettyJsonSerializer>(source);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,158 +1,158 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for strlen
|
||||
|
||||
#include <ArduinoJson/Json/EscapeSequence.hpp>
|
||||
#include <ArduinoJson/Numbers/FloatParts.hpp>
|
||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class TextFormatter {
|
||||
public:
|
||||
explicit TextFormatter(TWriter writer) : _writer(writer), _length(0) {}
|
||||
|
||||
// Returns the number of bytes sent to the TWriter implementation.
|
||||
size_t bytesWritten() const {
|
||||
return _length;
|
||||
}
|
||||
|
||||
void writeBoolean(bool value) {
|
||||
if (value)
|
||||
writeRaw("true");
|
||||
else
|
||||
writeRaw("false");
|
||||
}
|
||||
|
||||
void writeString(const char *value) {
|
||||
ARDUINOJSON_ASSERT(value != NULL);
|
||||
writeRaw('\"');
|
||||
while (*value) writeChar(*value++);
|
||||
writeRaw('\"');
|
||||
}
|
||||
|
||||
void writeChar(char c) {
|
||||
char specialChar = EscapeSequence::escapeChar(c);
|
||||
if (specialChar) {
|
||||
writeRaw('\\');
|
||||
writeRaw(specialChar);
|
||||
} else {
|
||||
writeRaw(c);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writeFloat(T value) {
|
||||
if (isnan(value))
|
||||
return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null");
|
||||
|
||||
#if ARDUINOJSON_ENABLE_INFINITY
|
||||
if (value < 0.0) {
|
||||
writeRaw('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
if (isinf(value))
|
||||
return writeRaw("Infinity");
|
||||
#else
|
||||
if (isinf(value))
|
||||
return writeRaw("null");
|
||||
|
||||
if (value < 0.0) {
|
||||
writeRaw('-');
|
||||
value = -value;
|
||||
}
|
||||
#endif
|
||||
|
||||
FloatParts<T> parts(value);
|
||||
|
||||
writePositiveInteger(parts.integral);
|
||||
if (parts.decimalPlaces)
|
||||
writeDecimals(parts.decimal, parts.decimalPlaces);
|
||||
|
||||
if (parts.exponent < 0) {
|
||||
writeRaw("e-");
|
||||
writePositiveInteger(-parts.exponent);
|
||||
}
|
||||
|
||||
if (parts.exponent > 0) {
|
||||
writeRaw('e');
|
||||
writePositiveInteger(parts.exponent);
|
||||
}
|
||||
}
|
||||
|
||||
void writeNegativeInteger(UInt value) {
|
||||
writeRaw('-');
|
||||
writePositiveInteger(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writePositiveInteger(T value) {
|
||||
char buffer[22];
|
||||
char *end = buffer + sizeof(buffer);
|
||||
char *begin = end;
|
||||
|
||||
// write the string in reverse order
|
||||
do {
|
||||
*--begin = char(value % 10 + '0');
|
||||
value = T(value / 10);
|
||||
} while (value);
|
||||
|
||||
// and dump it in the right order
|
||||
writeRaw(begin, end);
|
||||
}
|
||||
|
||||
void writeDecimals(uint32_t value, int8_t width) {
|
||||
// buffer should be big enough for all digits and the dot
|
||||
char buffer[16];
|
||||
char *end = buffer + sizeof(buffer);
|
||||
char *begin = end;
|
||||
|
||||
// write the string in reverse order
|
||||
while (width--) {
|
||||
*--begin = char(value % 10 + '0');
|
||||
value /= 10;
|
||||
}
|
||||
*--begin = '.';
|
||||
|
||||
// and dump it in the right order
|
||||
writeRaw(begin, end);
|
||||
}
|
||||
|
||||
void writeRaw(const char *s) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s));
|
||||
}
|
||||
|
||||
void writeRaw(const char *s, size_t n) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), n);
|
||||
}
|
||||
|
||||
void writeRaw(const char *begin, const char *end) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(begin),
|
||||
static_cast<size_t>(end - begin));
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void writeRaw(const char (&s)[N]) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1);
|
||||
}
|
||||
void writeRaw(char c) {
|
||||
_length += _writer.write(static_cast<uint8_t>(c));
|
||||
}
|
||||
|
||||
protected:
|
||||
TWriter _writer;
|
||||
size_t _length;
|
||||
|
||||
private:
|
||||
TextFormatter &operator=(const TextFormatter &); // cannot be assigned
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h> // for strlen
|
||||
|
||||
#include <ArduinoJson/Json/EscapeSequence.hpp>
|
||||
#include <ArduinoJson/Numbers/FloatParts.hpp>
|
||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class TextFormatter {
|
||||
public:
|
||||
explicit TextFormatter(TWriter writer) : _writer(writer), _length(0) {}
|
||||
|
||||
// Returns the number of bytes sent to the TWriter implementation.
|
||||
size_t bytesWritten() const {
|
||||
return _length;
|
||||
}
|
||||
|
||||
void writeBoolean(bool value) {
|
||||
if (value)
|
||||
writeRaw("true");
|
||||
else
|
||||
writeRaw("false");
|
||||
}
|
||||
|
||||
void writeString(const char *value) {
|
||||
ARDUINOJSON_ASSERT(value != NULL);
|
||||
writeRaw('\"');
|
||||
while (*value) writeChar(*value++);
|
||||
writeRaw('\"');
|
||||
}
|
||||
|
||||
void writeChar(char c) {
|
||||
char specialChar = EscapeSequence::escapeChar(c);
|
||||
if (specialChar) {
|
||||
writeRaw('\\');
|
||||
writeRaw(specialChar);
|
||||
} else {
|
||||
writeRaw(c);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writeFloat(T value) {
|
||||
if (isnan(value))
|
||||
return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null");
|
||||
|
||||
#if ARDUINOJSON_ENABLE_INFINITY
|
||||
if (value < 0.0) {
|
||||
writeRaw('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
if (isinf(value))
|
||||
return writeRaw("Infinity");
|
||||
#else
|
||||
if (isinf(value))
|
||||
return writeRaw("null");
|
||||
|
||||
if (value < 0.0) {
|
||||
writeRaw('-');
|
||||
value = -value;
|
||||
}
|
||||
#endif
|
||||
|
||||
FloatParts<T> parts(value);
|
||||
|
||||
writePositiveInteger(parts.integral);
|
||||
if (parts.decimalPlaces)
|
||||
writeDecimals(parts.decimal, parts.decimalPlaces);
|
||||
|
||||
if (parts.exponent < 0) {
|
||||
writeRaw("e-");
|
||||
writePositiveInteger(-parts.exponent);
|
||||
}
|
||||
|
||||
if (parts.exponent > 0) {
|
||||
writeRaw('e');
|
||||
writePositiveInteger(parts.exponent);
|
||||
}
|
||||
}
|
||||
|
||||
void writeNegativeInteger(UInt value) {
|
||||
writeRaw('-');
|
||||
writePositiveInteger(value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writePositiveInteger(T value) {
|
||||
char buffer[22];
|
||||
char *end = buffer + sizeof(buffer);
|
||||
char *begin = end;
|
||||
|
||||
// write the string in reverse order
|
||||
do {
|
||||
*--begin = char(value % 10 + '0');
|
||||
value = T(value / 10);
|
||||
} while (value);
|
||||
|
||||
// and dump it in the right order
|
||||
writeRaw(begin, end);
|
||||
}
|
||||
|
||||
void writeDecimals(uint32_t value, int8_t width) {
|
||||
// buffer should be big enough for all digits and the dot
|
||||
char buffer[16];
|
||||
char *end = buffer + sizeof(buffer);
|
||||
char *begin = end;
|
||||
|
||||
// write the string in reverse order
|
||||
while (width--) {
|
||||
*--begin = char(value % 10 + '0');
|
||||
value /= 10;
|
||||
}
|
||||
*--begin = '.';
|
||||
|
||||
// and dump it in the right order
|
||||
writeRaw(begin, end);
|
||||
}
|
||||
|
||||
void writeRaw(const char *s) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s));
|
||||
}
|
||||
|
||||
void writeRaw(const char *s, size_t n) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), n);
|
||||
}
|
||||
|
||||
void writeRaw(const char *begin, const char *end) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(begin),
|
||||
static_cast<size_t>(end - begin));
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
void writeRaw(const char (&s)[N]) {
|
||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1);
|
||||
}
|
||||
void writeRaw(char c) {
|
||||
_length += _writer.write(static_cast<uint8_t>(c));
|
||||
}
|
||||
|
||||
protected:
|
||||
TWriter _writer;
|
||||
size_t _length;
|
||||
|
||||
private:
|
||||
TextFormatter &operator=(const TextFormatter &); // cannot be assigned
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,65 +1,67 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stdint.h> // uint16_t, uint32_t
|
||||
|
||||
// The high surrogate may be uninitialized if the pair is invalid,
|
||||
// we choose to ignore the problem to reduce the size of the code
|
||||
// Garbage in => Garbage out
|
||||
#if defined(__GNUC__)
|
||||
#if __GNUC__ >= 7
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
namespace Utf16 {
|
||||
inline bool isHighSurrogate(uint16_t codeunit) {
|
||||
return codeunit >= 0xD800 && codeunit < 0xDC00;
|
||||
}
|
||||
|
||||
inline bool isLowSurrogate(uint16_t codeunit) {
|
||||
return codeunit >= 0xDC00 && codeunit < 0xE000;
|
||||
}
|
||||
|
||||
class Codepoint {
|
||||
public:
|
||||
bool append(uint16_t codeunit) {
|
||||
if (isHighSurrogate(codeunit)) {
|
||||
_highSurrogate = codeunit & 0x3FF;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLowSurrogate(codeunit)) {
|
||||
_codepoint =
|
||||
uint32_t(0x10000 + ((_highSurrogate << 10) | (codeunit & 0x3FF)));
|
||||
return true;
|
||||
}
|
||||
|
||||
_codepoint = codeunit;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t value() const {
|
||||
return _codepoint;
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t _highSurrogate;
|
||||
uint32_t _codepoint;
|
||||
};
|
||||
} // namespace Utf16
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if __GNUC__ >= 8
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stdint.h> // uint16_t, uint32_t
|
||||
|
||||
// The high surrogate may be uninitialized if the pair is invalid,
|
||||
// we choose to ignore the problem to reduce the size of the code
|
||||
// Garbage in => Garbage out
|
||||
#if defined(__GNUC__)
|
||||
#if __GNUC__ >= 7
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
namespace Utf16 {
|
||||
inline bool isHighSurrogate(uint16_t codeunit) {
|
||||
return codeunit >= 0xD800 && codeunit < 0xDC00;
|
||||
}
|
||||
|
||||
inline bool isLowSurrogate(uint16_t codeunit) {
|
||||
return codeunit >= 0xDC00 && codeunit < 0xE000;
|
||||
}
|
||||
|
||||
class Codepoint {
|
||||
public:
|
||||
Codepoint() : _highSurrogate(0) {}
|
||||
|
||||
bool append(uint16_t codeunit) {
|
||||
if (isHighSurrogate(codeunit)) {
|
||||
_highSurrogate = codeunit & 0x3FF;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isLowSurrogate(codeunit)) {
|
||||
_codepoint =
|
||||
uint32_t(0x10000 + ((_highSurrogate << 10) | (codeunit & 0x3FF)));
|
||||
return true;
|
||||
}
|
||||
|
||||
_codepoint = codeunit;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t value() const {
|
||||
return _codepoint;
|
||||
}
|
||||
|
||||
private:
|
||||
uint16_t _highSurrogate;
|
||||
uint32_t _codepoint;
|
||||
};
|
||||
} // namespace Utf16
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if __GNUC__ >= 8
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,46 +1,46 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
namespace Utf8 {
|
||||
template <typename TStringBuilder>
|
||||
inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) {
|
||||
// this function was optimize for code size on AVR
|
||||
|
||||
// a buffer to store the string in reverse
|
||||
char buf[5];
|
||||
char* p = buf;
|
||||
|
||||
*(p++) = 0;
|
||||
if (codepoint32 < 0x80) {
|
||||
*(p++) = char((codepoint32));
|
||||
} else {
|
||||
*(p++) = char((codepoint32 | 0x80) & 0xBF);
|
||||
uint16_t codepoint16 = uint16_t(codepoint32 >> 6);
|
||||
if (codepoint16 < 0x20) { // 0x800
|
||||
*(p++) = char(codepoint16 | 0xC0);
|
||||
} else {
|
||||
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
||||
codepoint16 = uint16_t(codepoint16 >> 6);
|
||||
if (codepoint16 < 0x10) { // 0x10000
|
||||
*(p++) = char(codepoint16 | 0xE0);
|
||||
} else {
|
||||
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
||||
codepoint16 = uint16_t(codepoint16 >> 6);
|
||||
*(p++) = char(codepoint16 | 0xF0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (*(--p)) {
|
||||
str.append(*p);
|
||||
}
|
||||
}
|
||||
} // namespace Utf8
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
namespace Utf8 {
|
||||
template <typename TStringBuilder>
|
||||
inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) {
|
||||
// this function was optimize for code size on AVR
|
||||
|
||||
// a buffer to store the string in reverse
|
||||
char buf[5];
|
||||
char* p = buf;
|
||||
|
||||
*(p++) = 0;
|
||||
if (codepoint32 < 0x80) {
|
||||
*(p++) = char((codepoint32));
|
||||
} else {
|
||||
*(p++) = char((codepoint32 | 0x80) & 0xBF);
|
||||
uint16_t codepoint16 = uint16_t(codepoint32 >> 6);
|
||||
if (codepoint16 < 0x20) { // 0x800
|
||||
*(p++) = char(codepoint16 | 0xC0);
|
||||
} else {
|
||||
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
||||
codepoint16 = uint16_t(codepoint16 >> 6);
|
||||
if (codepoint16 < 0x10) { // 0x10000
|
||||
*(p++) = char(codepoint16 | 0xE0);
|
||||
} else {
|
||||
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
||||
codepoint16 = uint16_t(codepoint16 >> 6);
|
||||
*(p++) = char(codepoint16 | 0xF0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (*(--p)) {
|
||||
str.append(*p);
|
||||
}
|
||||
}
|
||||
} // namespace Utf8
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,36 +1,60 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline bool isAligned(void *ptr) {
|
||||
const size_t mask = sizeof(void *) - 1;
|
||||
size_t addr = reinterpret_cast<size_t>(ptr);
|
||||
return (addr & mask) == 0;
|
||||
}
|
||||
|
||||
inline size_t addPadding(size_t bytes) {
|
||||
const size_t mask = sizeof(void *) - 1;
|
||||
return (bytes + mask) & ~mask;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T *addPadding(T *p) {
|
||||
size_t address = addPadding(reinterpret_cast<size_t>(p));
|
||||
return reinterpret_cast<T *>(address);
|
||||
}
|
||||
|
||||
template <size_t bytes>
|
||||
struct AddPadding {
|
||||
static const size_t mask = sizeof(void *) - 1;
|
||||
static const size_t value = (bytes + mask) & ~mask;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ALIGNMENT
|
||||
|
||||
inline bool isAligned(size_t value) {
|
||||
const size_t mask = sizeof(void *) - 1;
|
||||
size_t addr = value;
|
||||
return (addr & mask) == 0;
|
||||
}
|
||||
|
||||
inline size_t addPadding(size_t bytes) {
|
||||
const size_t mask = sizeof(void *) - 1;
|
||||
return (bytes + mask) & ~mask;
|
||||
}
|
||||
|
||||
template <size_t bytes>
|
||||
struct AddPadding {
|
||||
static const size_t mask = sizeof(void *) - 1;
|
||||
static const size_t value = (bytes + mask) & ~mask;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
inline bool isAligned(size_t) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline size_t addPadding(size_t bytes) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
template <size_t bytes>
|
||||
struct AddPadding {
|
||||
static const size_t value = bytes;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline bool isAligned(T *ptr) {
|
||||
return isAligned(reinterpret_cast<size_t>(ptr));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T *addPadding(T *p) {
|
||||
size_t address = addPadding(reinterpret_cast<size_t>(p));
|
||||
return reinterpret_cast<T *>(address);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,161 +1,200 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/StringSlot.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/mpl/max.hpp>
|
||||
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
||||
|
||||
#include <string.h> // memmove
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// _begin _end
|
||||
// v v
|
||||
// +-------------+--------------+--------------+
|
||||
// | strings... | (free) | ...variants |
|
||||
// +-------------+--------------+--------------+
|
||||
// ^ ^
|
||||
// _left _right
|
||||
|
||||
class MemoryPool {
|
||||
public:
|
||||
MemoryPool(char* buf, size_t capa)
|
||||
: _begin(buf),
|
||||
_left(buf),
|
||||
_right(buf ? buf + capa : 0),
|
||||
_end(buf ? buf + capa : 0) {
|
||||
ARDUINOJSON_ASSERT(isAligned(_begin));
|
||||
ARDUINOJSON_ASSERT(isAligned(_right));
|
||||
ARDUINOJSON_ASSERT(isAligned(_end));
|
||||
}
|
||||
|
||||
void* buffer() {
|
||||
return _begin;
|
||||
}
|
||||
|
||||
// Gets the capacity of the memoryPool in bytes
|
||||
size_t capacity() const {
|
||||
return size_t(_end - _begin);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return size_t(_left - _begin + _end - _right);
|
||||
}
|
||||
|
||||
VariantSlot* allocVariant() {
|
||||
return allocRight<VariantSlot>();
|
||||
}
|
||||
|
||||
char* allocFrozenString(size_t n) {
|
||||
if (!canAlloc(n))
|
||||
return 0;
|
||||
char* s = _left;
|
||||
_left += n;
|
||||
checkInvariants();
|
||||
return s;
|
||||
}
|
||||
|
||||
StringSlot allocExpandableString() {
|
||||
StringSlot s;
|
||||
s.value = _left;
|
||||
s.size = size_t(_right - _left);
|
||||
_left = _right;
|
||||
checkInvariants();
|
||||
return s;
|
||||
}
|
||||
|
||||
void freezeString(StringSlot& s, size_t newSize) {
|
||||
_left -= (s.size - newSize);
|
||||
s.size = newSize;
|
||||
checkInvariants();
|
||||
}
|
||||
|
||||
void reclaimLastString(const char* s) {
|
||||
_left = const_cast<char*>(s);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_left = _begin;
|
||||
_right = _end;
|
||||
}
|
||||
|
||||
bool canAlloc(size_t bytes) const {
|
||||
return _left + bytes <= _right;
|
||||
}
|
||||
|
||||
bool owns(void* p) const {
|
||||
return _begin <= p && p < _end;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* allocRight() {
|
||||
return reinterpret_cast<T*>(allocRight(sizeof(T)));
|
||||
}
|
||||
|
||||
void* allocRight(size_t bytes) {
|
||||
if (!canAlloc(bytes))
|
||||
return 0;
|
||||
_right -= bytes;
|
||||
return _right;
|
||||
}
|
||||
|
||||
// Workaround for missing placement new
|
||||
void* operator new(size_t, void* p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
// Squash the free space between strings and variants
|
||||
//
|
||||
// _begin _end
|
||||
// v v
|
||||
// +-------------+--------------+
|
||||
// | strings... | ...variants |
|
||||
// +-------------+--------------+
|
||||
// ^
|
||||
// _left _right
|
||||
//
|
||||
// This funcion is called before a realloc.
|
||||
ptrdiff_t squash() {
|
||||
char* new_right = addPadding(_left);
|
||||
if (new_right >= _right)
|
||||
return 0;
|
||||
|
||||
size_t right_size = static_cast<size_t>(_end - _right);
|
||||
memmove(new_right, _right, right_size);
|
||||
|
||||
ptrdiff_t bytes_reclaimed = _right - new_right;
|
||||
_right = new_right;
|
||||
_end = new_right + right_size;
|
||||
return bytes_reclaimed;
|
||||
}
|
||||
|
||||
// Move all pointers together
|
||||
// This funcion is called after a realloc.
|
||||
void movePointers(ptrdiff_t offset) {
|
||||
_begin += offset;
|
||||
_left += offset;
|
||||
_right += offset;
|
||||
_end += offset;
|
||||
}
|
||||
|
||||
private:
|
||||
StringSlot* allocStringSlot() {
|
||||
return allocRight<StringSlot>();
|
||||
}
|
||||
|
||||
void checkInvariants() {
|
||||
ARDUINOJSON_ASSERT(_begin <= _left);
|
||||
ARDUINOJSON_ASSERT(_left <= _right);
|
||||
ARDUINOJSON_ASSERT(_right <= _end);
|
||||
ARDUINOJSON_ASSERT(isAligned(_right));
|
||||
}
|
||||
|
||||
char *_begin, *_left, *_right, *_end;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||
#include <ArduinoJson/Memory/StringSlot.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/mpl/max.hpp>
|
||||
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
||||
|
||||
#include <string.h> // memmove
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// _begin _end
|
||||
// v v
|
||||
// +-------------+--------------+--------------+
|
||||
// | strings... | (free) | ...variants |
|
||||
// +-------------+--------------+--------------+
|
||||
// ^ ^
|
||||
// _left _right
|
||||
|
||||
class MemoryPool {
|
||||
public:
|
||||
MemoryPool(char* buf, size_t capa)
|
||||
: _begin(buf),
|
||||
_left(buf),
|
||||
_right(buf ? buf + capa : 0),
|
||||
_end(buf ? buf + capa : 0) {
|
||||
ARDUINOJSON_ASSERT(isAligned(_begin));
|
||||
ARDUINOJSON_ASSERT(isAligned(_right));
|
||||
ARDUINOJSON_ASSERT(isAligned(_end));
|
||||
}
|
||||
|
||||
void* buffer() {
|
||||
return _begin;
|
||||
}
|
||||
|
||||
// Gets the capacity of the memoryPool in bytes
|
||||
size_t capacity() const {
|
||||
return size_t(_end - _begin);
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return size_t(_left - _begin + _end - _right);
|
||||
}
|
||||
|
||||
VariantSlot* allocVariant() {
|
||||
return allocRight<VariantSlot>();
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
const char* saveString(const TAdaptedString& str) {
|
||||
if (str.isNull())
|
||||
return 0;
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||
const char* existingCopy = findString(str.begin());
|
||||
if (existingCopy)
|
||||
return existingCopy;
|
||||
#endif
|
||||
|
||||
size_t n = str.size();
|
||||
|
||||
char* newCopy = allocString(n + 1);
|
||||
if (newCopy) {
|
||||
str.copyTo(newCopy, n);
|
||||
newCopy[n] = 0; // force null-terminator
|
||||
}
|
||||
return newCopy;
|
||||
}
|
||||
|
||||
void getFreeZone(char** zoneStart, size_t* zoneSize) const {
|
||||
*zoneStart = _left;
|
||||
*zoneSize = size_t(_right - _left);
|
||||
}
|
||||
|
||||
const char* saveStringFromFreeZone(size_t len) {
|
||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||
const char* dup = findString(_left);
|
||||
if (dup)
|
||||
return dup;
|
||||
#endif
|
||||
|
||||
const char* str = _left;
|
||||
_left += len;
|
||||
checkInvariants();
|
||||
return str;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
_left = _begin;
|
||||
_right = _end;
|
||||
}
|
||||
|
||||
bool canAlloc(size_t bytes) const {
|
||||
return _left + bytes <= _right;
|
||||
}
|
||||
|
||||
bool owns(void* p) const {
|
||||
return _begin <= p && p < _end;
|
||||
}
|
||||
|
||||
// Workaround for missing placement new
|
||||
void* operator new(size_t, void* p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
// Squash the free space between strings and variants
|
||||
//
|
||||
// _begin _end
|
||||
// v v
|
||||
// +-------------+--------------+
|
||||
// | strings... | ...variants |
|
||||
// +-------------+--------------+
|
||||
// ^
|
||||
// _left _right
|
||||
//
|
||||
// This funcion is called before a realloc.
|
||||
ptrdiff_t squash() {
|
||||
char* new_right = addPadding(_left);
|
||||
if (new_right >= _right)
|
||||
return 0;
|
||||
|
||||
size_t right_size = static_cast<size_t>(_end - _right);
|
||||
memmove(new_right, _right, right_size);
|
||||
|
||||
ptrdiff_t bytes_reclaimed = _right - new_right;
|
||||
_right = new_right;
|
||||
_end = new_right + right_size;
|
||||
return bytes_reclaimed;
|
||||
}
|
||||
|
||||
// Move all pointers together
|
||||
// This funcion is called after a realloc.
|
||||
void movePointers(ptrdiff_t offset) {
|
||||
_begin += offset;
|
||||
_left += offset;
|
||||
_right += offset;
|
||||
_end += offset;
|
||||
}
|
||||
|
||||
private:
|
||||
StringSlot* allocStringSlot() {
|
||||
return allocRight<StringSlot>();
|
||||
}
|
||||
|
||||
void checkInvariants() {
|
||||
ARDUINOJSON_ASSERT(_begin <= _left);
|
||||
ARDUINOJSON_ASSERT(_left <= _right);
|
||||
ARDUINOJSON_ASSERT(_right <= _end);
|
||||
ARDUINOJSON_ASSERT(isAligned(_right));
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||
template <typename TIterator>
|
||||
const char* findString(TIterator str) {
|
||||
for (char* next = _begin; next < _left; ++next) {
|
||||
char* begin = next;
|
||||
|
||||
// try to match
|
||||
for (TIterator it = str; *it == *next; ++it) {
|
||||
if (*next++ == 0)
|
||||
return begin;
|
||||
}
|
||||
|
||||
// jump to next terminator
|
||||
while (*next) ++next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
char* allocString(size_t n) {
|
||||
if (!canAlloc(n))
|
||||
return 0;
|
||||
char* s = _left;
|
||||
_left += n;
|
||||
checkInvariants();
|
||||
return s;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T* allocRight() {
|
||||
return reinterpret_cast<T*>(allocRight(sizeof(T)));
|
||||
}
|
||||
|
||||
void* allocRight(size_t bytes) {
|
||||
if (!canAlloc(bytes))
|
||||
return 0;
|
||||
_right -= bytes;
|
||||
return _right;
|
||||
}
|
||||
|
||||
char *_begin, *_left, *_right, *_end;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,19 +1,19 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#define JSON_STRING_SIZE(SIZE) (SIZE)
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
struct StringSlot {
|
||||
char *value;
|
||||
size_t size;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#define JSON_STRING_SIZE(SIZE) (SIZE + 1)
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
struct StringSlot {
|
||||
char *value;
|
||||
size_t size;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,68 +1,68 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A special type of data that can be used to insert pregenerated JSON portions.
|
||||
template <typename T>
|
||||
class SerializedValue {
|
||||
public:
|
||||
explicit SerializedValue(T str) : _str(str) {}
|
||||
operator T() const {
|
||||
return _str;
|
||||
}
|
||||
|
||||
const char* data() const {
|
||||
return _str.c_str();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
// CAUTION: the old Arduino String doesn't have size()
|
||||
return _str.length();
|
||||
}
|
||||
|
||||
private:
|
||||
T _str;
|
||||
};
|
||||
|
||||
template <typename TChar>
|
||||
class SerializedValue<TChar*> {
|
||||
public:
|
||||
explicit SerializedValue(TChar* p, size_t n) : _data(p), _size(n) {}
|
||||
operator TChar*() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
TChar* data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
private:
|
||||
TChar* _data;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline SerializedValue<T> serialized(T str) {
|
||||
return SerializedValue<T>(str);
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
inline SerializedValue<TChar*> serialized(TChar* p) {
|
||||
return SerializedValue<TChar*>(p, adaptString(p).size());
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
inline SerializedValue<TChar*> serialized(TChar* p, size_t n) {
|
||||
return SerializedValue<TChar*>(p, n);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A special type of data that can be used to insert pregenerated JSON portions.
|
||||
template <typename T>
|
||||
class SerializedValue {
|
||||
public:
|
||||
explicit SerializedValue(T str) : _str(str) {}
|
||||
operator T() const {
|
||||
return _str;
|
||||
}
|
||||
|
||||
const char* data() const {
|
||||
return _str.c_str();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
// CAUTION: the old Arduino String doesn't have size()
|
||||
return _str.length();
|
||||
}
|
||||
|
||||
private:
|
||||
T _str;
|
||||
};
|
||||
|
||||
template <typename TChar>
|
||||
class SerializedValue<TChar*> {
|
||||
public:
|
||||
explicit SerializedValue(TChar* p, size_t n) : _data(p), _size(n) {}
|
||||
operator TChar*() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
TChar* data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
private:
|
||||
TChar* _data;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline SerializedValue<T> serialized(T str) {
|
||||
return SerializedValue<T>(str);
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
inline SerializedValue<TChar*> serialized(TChar* p) {
|
||||
return SerializedValue<TChar*>(p, adaptString(p).size());
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
inline SerializedValue<TChar*> serialized(TChar* p, size_t n) {
|
||||
return SerializedValue<TChar*>(p, n);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,21 +1,21 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
struct Visitable {
|
||||
// template<Visitor>
|
||||
// void accept(Visitor&) const;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsVisitable : is_base_of<Visitable, T> {};
|
||||
|
||||
template <typename T>
|
||||
struct IsVisitable<T&> : IsVisitable<T> {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
struct Visitable {
|
||||
// template<Visitor>
|
||||
// void accept(Visitor&) const;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsVisitable : is_base_of<Visitable, T> {};
|
||||
|
||||
template <typename T>
|
||||
struct IsVisitable<T&> : IsVisitable<T> {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,374 +1,382 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Deserialization/deserialize.hpp>
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||
#include <ArduinoJson/MsgPack/ieee754.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TReader, typename TStringStorage>
|
||||
class MsgPackDeserializer {
|
||||
typedef typename remove_reference<TStringStorage>::type::StringBuilder
|
||||
StringBuilder;
|
||||
|
||||
public:
|
||||
MsgPackDeserializer(MemoryPool &pool, TReader reader,
|
||||
TStringStorage stringStorage)
|
||||
: _pool(&pool), _reader(reader), _stringStorage(stringStorage) {}
|
||||
|
||||
DeserializationError parse(VariantData &variant, AllowAllFilter,
|
||||
NestingLimit nestingLimit) {
|
||||
return parse(variant, nestingLimit);
|
||||
}
|
||||
|
||||
DeserializationError parse(VariantData &variant, NestingLimit nestingLimit) {
|
||||
uint8_t code;
|
||||
if (!readByte(code))
|
||||
return DeserializationError::IncompleteInput;
|
||||
|
||||
if ((code & 0x80) == 0) {
|
||||
variant.setUnsignedInteger(code);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
if ((code & 0xe0) == 0xe0) {
|
||||
variant.setSignedInteger(static_cast<int8_t>(code));
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
if ((code & 0xe0) == 0xa0) {
|
||||
return readString(variant, code & 0x1f);
|
||||
}
|
||||
|
||||
if ((code & 0xf0) == 0x90) {
|
||||
return readArray(variant.toArray(), code & 0x0F, nestingLimit);
|
||||
}
|
||||
|
||||
if ((code & 0xf0) == 0x80) {
|
||||
return readObject(variant.toObject(), code & 0x0F, nestingLimit);
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case 0xc0:
|
||||
// already null
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xc2:
|
||||
variant.setBoolean(false);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xc3:
|
||||
variant.setBoolean(true);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xcc:
|
||||
return readInteger<uint8_t>(variant);
|
||||
|
||||
case 0xcd:
|
||||
return readInteger<uint16_t>(variant);
|
||||
|
||||
case 0xce:
|
||||
return readInteger<uint32_t>(variant);
|
||||
|
||||
case 0xcf:
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
return readInteger<uint64_t>(variant);
|
||||
#else
|
||||
return DeserializationError::NotSupported;
|
||||
#endif
|
||||
|
||||
case 0xd0:
|
||||
return readInteger<int8_t>(variant);
|
||||
|
||||
case 0xd1:
|
||||
return readInteger<int16_t>(variant);
|
||||
|
||||
case 0xd2:
|
||||
return readInteger<int32_t>(variant);
|
||||
|
||||
case 0xd3:
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
return readInteger<int64_t>(variant);
|
||||
#else
|
||||
return DeserializationError::NotSupported;
|
||||
#endif
|
||||
|
||||
case 0xca:
|
||||
return readFloat<float>(variant);
|
||||
|
||||
case 0xcb:
|
||||
return readDouble<double>(variant);
|
||||
|
||||
case 0xd9:
|
||||
return readString<uint8_t>(variant);
|
||||
|
||||
case 0xda:
|
||||
return readString<uint16_t>(variant);
|
||||
|
||||
case 0xdb:
|
||||
return readString<uint32_t>(variant);
|
||||
|
||||
case 0xdc:
|
||||
return readArray<uint16_t>(variant.toArray(), nestingLimit);
|
||||
|
||||
case 0xdd:
|
||||
return readArray<uint32_t>(variant.toArray(), nestingLimit);
|
||||
|
||||
case 0xde:
|
||||
return readObject<uint16_t>(variant.toObject(), nestingLimit);
|
||||
|
||||
case 0xdf:
|
||||
return readObject<uint32_t>(variant.toObject(), nestingLimit);
|
||||
|
||||
default:
|
||||
return DeserializationError::NotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Prevent VS warning "assignment operator could not be generated"
|
||||
MsgPackDeserializer &operator=(const MsgPackDeserializer &);
|
||||
|
||||
bool readByte(uint8_t &value) {
|
||||
int c = _reader.read();
|
||||
if (c < 0)
|
||||
return false;
|
||||
value = static_cast<uint8_t>(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readBytes(uint8_t *p, size_t n) {
|
||||
return _reader.readBytes(reinterpret_cast<char *>(p), n) == n;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool readBytes(T &value) {
|
||||
return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T readInteger() {
|
||||
T value;
|
||||
readBytes(value);
|
||||
fixEndianess(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool readInteger(T &value) {
|
||||
if (!readBytes(value))
|
||||
return false;
|
||||
fixEndianess(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError readInteger(VariantData &variant) {
|
||||
T value;
|
||||
if (!readInteger(value))
|
||||
return DeserializationError::IncompleteInput;
|
||||
variant.setInteger(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, DeserializationError>::type readFloat(
|
||||
VariantData &variant) {
|
||||
T value;
|
||||
if (!readBytes(value))
|
||||
return DeserializationError::IncompleteInput;
|
||||
fixEndianess(value);
|
||||
variant.setFloat(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 8, DeserializationError>::type readDouble(
|
||||
VariantData &variant) {
|
||||
T value;
|
||||
if (!readBytes(value))
|
||||
return DeserializationError::IncompleteInput;
|
||||
fixEndianess(value);
|
||||
variant.setFloat(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, DeserializationError>::type readDouble(
|
||||
VariantData &variant) {
|
||||
uint8_t i[8]; // input is 8 bytes
|
||||
T value; // output is 4 bytes
|
||||
uint8_t *o = reinterpret_cast<uint8_t *>(&value);
|
||||
if (!readBytes(i, 8))
|
||||
return DeserializationError::IncompleteInput;
|
||||
doubleToFloat(i, o);
|
||||
fixEndianess(value);
|
||||
variant.setFloat(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError readString(VariantData &variant) {
|
||||
T size;
|
||||
if (!readInteger(size))
|
||||
return DeserializationError::IncompleteInput;
|
||||
return readString(variant, size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError readString(const char *&str) {
|
||||
T size;
|
||||
if (!readInteger(size))
|
||||
return DeserializationError::IncompleteInput;
|
||||
return readString(str, size);
|
||||
}
|
||||
|
||||
DeserializationError readString(VariantData &variant, size_t n) {
|
||||
const char *s = 0; // <- mute "maybe-uninitialized" (+4 bytes on AVR)
|
||||
DeserializationError err = readString(s, n);
|
||||
if (!err)
|
||||
variant.setOwnedString(make_not_null(s));
|
||||
return err;
|
||||
}
|
||||
|
||||
DeserializationError readString(const char *&result, size_t n) {
|
||||
StringBuilder builder = _stringStorage.startString();
|
||||
for (; n; --n) {
|
||||
uint8_t c;
|
||||
if (!readBytes(c))
|
||||
return DeserializationError::IncompleteInput;
|
||||
builder.append(static_cast<char>(c));
|
||||
}
|
||||
result = builder.complete();
|
||||
if (!result)
|
||||
return DeserializationError::NoMemory;
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
DeserializationError readArray(CollectionData &array,
|
||||
NestingLimit nestingLimit) {
|
||||
TSize size;
|
||||
if (!readInteger(size))
|
||||
return DeserializationError::IncompleteInput;
|
||||
return readArray(array, size, nestingLimit);
|
||||
}
|
||||
|
||||
DeserializationError readArray(CollectionData &array, size_t n,
|
||||
NestingLimit nestingLimit) {
|
||||
if (nestingLimit.reached())
|
||||
return DeserializationError::TooDeep;
|
||||
|
||||
for (; n; --n) {
|
||||
VariantData *value = array.addElement(_pool);
|
||||
if (!value)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
DeserializationError err = parse(*value, nestingLimit.decrement());
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
DeserializationError readObject(CollectionData &object,
|
||||
NestingLimit nestingLimit) {
|
||||
TSize size;
|
||||
if (!readInteger(size))
|
||||
return DeserializationError::IncompleteInput;
|
||||
return readObject(object, size, nestingLimit);
|
||||
}
|
||||
|
||||
DeserializationError readObject(CollectionData &object, size_t n,
|
||||
NestingLimit nestingLimit) {
|
||||
if (nestingLimit.reached())
|
||||
return DeserializationError::TooDeep;
|
||||
|
||||
for (; n; --n) {
|
||||
VariantSlot *slot = object.addSlot(_pool);
|
||||
if (!slot)
|
||||
return DeserializationError::NoMemory;
|
||||
|
||||
const char *key = 0; // <- mute "maybe-uninitialized" (+4 bytes on AVR)
|
||||
DeserializationError err = parseKey(key);
|
||||
if (err)
|
||||
return err;
|
||||
slot->setOwnedKey(make_not_null(key));
|
||||
|
||||
err = parse(*slot->data(), nestingLimit.decrement());
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
DeserializationError parseKey(const char *&key) {
|
||||
uint8_t code;
|
||||
if (!readByte(code))
|
||||
return DeserializationError::IncompleteInput;
|
||||
|
||||
if ((code & 0xe0) == 0xa0)
|
||||
return readString(key, code & 0x1f);
|
||||
|
||||
switch (code) {
|
||||
case 0xd9:
|
||||
return readString<uint8_t>(key);
|
||||
|
||||
case 0xda:
|
||||
return readString<uint16_t>(key);
|
||||
|
||||
case 0xdb:
|
||||
return readString<uint32_t>(key);
|
||||
|
||||
default:
|
||||
return DeserializationError::NotSupported;
|
||||
}
|
||||
}
|
||||
|
||||
MemoryPool *_pool;
|
||||
TReader _reader;
|
||||
TStringStorage _stringStorage;
|
||||
};
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, const TInput &input,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, TInput *input,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, TInput *input, size_t inputSize,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, TInput &input,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Deserialization/deserialize.hpp>
|
||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||
#include <ArduinoJson/MsgPack/ieee754.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TReader, typename TStringStorage>
|
||||
class MsgPackDeserializer {
|
||||
public:
|
||||
MsgPackDeserializer(MemoryPool &pool, TReader reader,
|
||||
TStringStorage stringStorage)
|
||||
: _pool(&pool),
|
||||
_reader(reader),
|
||||
_stringStorage(stringStorage),
|
||||
_error(DeserializationError::Ok) {}
|
||||
|
||||
// TODO: add support for filter
|
||||
DeserializationError parse(VariantData &variant, AllowAllFilter,
|
||||
NestingLimit nestingLimit) {
|
||||
parseVariant(variant, nestingLimit);
|
||||
return _error;
|
||||
}
|
||||
|
||||
private:
|
||||
bool parseVariant(VariantData &variant, NestingLimit nestingLimit) {
|
||||
uint8_t code;
|
||||
if (!readByte(code)) {
|
||||
_error = DeserializationError::IncompleteInput;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((code & 0x80) == 0) {
|
||||
variant.setUnsignedInteger(code);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((code & 0xe0) == 0xe0) {
|
||||
variant.setSignedInteger(static_cast<int8_t>(code));
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((code & 0xe0) == 0xa0) {
|
||||
return readString(variant, code & 0x1f);
|
||||
}
|
||||
|
||||
if ((code & 0xf0) == 0x90) {
|
||||
return readArray(variant.toArray(), code & 0x0F, nestingLimit);
|
||||
}
|
||||
|
||||
if ((code & 0xf0) == 0x80) {
|
||||
return readObject(variant.toObject(), code & 0x0F, nestingLimit);
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case 0xc0:
|
||||
// already null
|
||||
return true;
|
||||
|
||||
case 0xc2:
|
||||
variant.setBoolean(false);
|
||||
return true;
|
||||
|
||||
case 0xc3:
|
||||
variant.setBoolean(true);
|
||||
return true;
|
||||
|
||||
case 0xcc:
|
||||
return readInteger<uint8_t>(variant);
|
||||
|
||||
case 0xcd:
|
||||
return readInteger<uint16_t>(variant);
|
||||
|
||||
case 0xce:
|
||||
return readInteger<uint32_t>(variant);
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
case 0xcf:
|
||||
return readInteger<uint64_t>(variant);
|
||||
#endif
|
||||
|
||||
case 0xd0:
|
||||
return readInteger<int8_t>(variant);
|
||||
|
||||
case 0xd1:
|
||||
return readInteger<int16_t>(variant);
|
||||
|
||||
case 0xd2:
|
||||
return readInteger<int32_t>(variant);
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
case 0xd3:
|
||||
return readInteger<int64_t>(variant);
|
||||
#endif
|
||||
|
||||
case 0xca:
|
||||
return readFloat<float>(variant);
|
||||
|
||||
case 0xcb:
|
||||
return readDouble<double>(variant);
|
||||
|
||||
case 0xd9:
|
||||
return readString<uint8_t>(variant);
|
||||
|
||||
case 0xda:
|
||||
return readString<uint16_t>(variant);
|
||||
|
||||
case 0xdb:
|
||||
return readString<uint32_t>(variant);
|
||||
|
||||
case 0xdc:
|
||||
return readArray<uint16_t>(variant.toArray(), nestingLimit);
|
||||
|
||||
case 0xdd:
|
||||
return readArray<uint32_t>(variant.toArray(), nestingLimit);
|
||||
|
||||
case 0xde:
|
||||
return readObject<uint16_t>(variant.toObject(), nestingLimit);
|
||||
|
||||
case 0xdf:
|
||||
return readObject<uint32_t>(variant.toObject(), nestingLimit);
|
||||
|
||||
default:
|
||||
_error = DeserializationError::NotSupported;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Prevent VS warning "assignment operator could not be generated"
|
||||
MsgPackDeserializer &operator=(const MsgPackDeserializer &);
|
||||
|
||||
bool readByte(uint8_t &value) {
|
||||
int c = _reader.read();
|
||||
if (c < 0) {
|
||||
_error = DeserializationError::IncompleteInput;
|
||||
return false;
|
||||
}
|
||||
value = static_cast<uint8_t>(c);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readBytes(uint8_t *p, size_t n) {
|
||||
if (_reader.readBytes(reinterpret_cast<char *>(p), n) == n)
|
||||
return true;
|
||||
_error = DeserializationError::IncompleteInput;
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool readBytes(T &value) {
|
||||
return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool readInteger(T &value) {
|
||||
if (!readBytes(value))
|
||||
return false;
|
||||
fixEndianess(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool readInteger(VariantData &variant) {
|
||||
T value;
|
||||
if (!readInteger(value))
|
||||
return false;
|
||||
variant.setInteger(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, bool>::type readFloat(
|
||||
VariantData &variant) {
|
||||
T value;
|
||||
if (!readBytes(value))
|
||||
return false;
|
||||
fixEndianess(value);
|
||||
variant.setFloat(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 8, bool>::type readDouble(
|
||||
VariantData &variant) {
|
||||
T value;
|
||||
if (!readBytes(value))
|
||||
return false;
|
||||
fixEndianess(value);
|
||||
variant.setFloat(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, bool>::type readDouble(
|
||||
VariantData &variant) {
|
||||
uint8_t i[8]; // input is 8 bytes
|
||||
T value; // output is 4 bytes
|
||||
uint8_t *o = reinterpret_cast<uint8_t *>(&value);
|
||||
if (!readBytes(i, 8))
|
||||
return false;
|
||||
doubleToFloat(i, o);
|
||||
fixEndianess(value);
|
||||
variant.setFloat(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool readString(VariantData &variant) {
|
||||
T size;
|
||||
if (!readInteger(size))
|
||||
return false;
|
||||
return readString(variant, size);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool readString(const char *&str) {
|
||||
T size;
|
||||
if (!readInteger(size))
|
||||
return false;
|
||||
return readString(str, size);
|
||||
}
|
||||
|
||||
bool readString(VariantData &variant, size_t n) {
|
||||
const char *s = 0; // <- mute "maybe-uninitialized" (+4 bytes on AVR)
|
||||
if (!readString(s, n))
|
||||
return false;
|
||||
variant.setString(make_not_null(s),
|
||||
typename TStringStorage::storage_policy());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readString(const char *&result, size_t n) {
|
||||
_stringStorage.startString(_pool);
|
||||
for (; n; --n) {
|
||||
uint8_t c;
|
||||
if (!readBytes(c))
|
||||
return false;
|
||||
_stringStorage.append(static_cast<char>(c));
|
||||
}
|
||||
_stringStorage.append('\0');
|
||||
if (!_stringStorage.isValid()) {
|
||||
_error = DeserializationError::NoMemory;
|
||||
return false;
|
||||
}
|
||||
|
||||
result = _stringStorage.save(_pool);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
bool readArray(CollectionData &array, NestingLimit nestingLimit) {
|
||||
TSize size;
|
||||
if (!readInteger(size))
|
||||
return false;
|
||||
return readArray(array, size, nestingLimit);
|
||||
}
|
||||
|
||||
bool readArray(CollectionData &array, size_t n, NestingLimit nestingLimit) {
|
||||
if (nestingLimit.reached()) {
|
||||
_error = DeserializationError::TooDeep;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; n; --n) {
|
||||
VariantData *value = array.addElement(_pool);
|
||||
if (!value) {
|
||||
_error = DeserializationError::NoMemory;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parseVariant(*value, nestingLimit.decrement()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
bool readObject(CollectionData &object, NestingLimit nestingLimit) {
|
||||
TSize size;
|
||||
if (!readInteger(size))
|
||||
return false;
|
||||
return readObject(object, size, nestingLimit);
|
||||
}
|
||||
|
||||
bool readObject(CollectionData &object, size_t n, NestingLimit nestingLimit) {
|
||||
if (nestingLimit.reached()) {
|
||||
_error = DeserializationError::TooDeep;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (; n; --n) {
|
||||
VariantSlot *slot = object.addSlot(_pool);
|
||||
if (!slot) {
|
||||
_error = DeserializationError::NoMemory;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *key = 0; // <- mute "maybe-uninitialized" (+4 bytes on AVR)
|
||||
if (!parseKey(key))
|
||||
return false;
|
||||
|
||||
slot->setKey(key, typename TStringStorage::storage_policy());
|
||||
|
||||
if (!parseVariant(*slot->data(), nestingLimit.decrement()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parseKey(const char *&key) {
|
||||
uint8_t code;
|
||||
if (!readByte(code))
|
||||
return false;
|
||||
|
||||
if ((code & 0xe0) == 0xa0)
|
||||
return readString(key, code & 0x1f);
|
||||
|
||||
switch (code) {
|
||||
case 0xd9:
|
||||
return readString<uint8_t>(key);
|
||||
|
||||
case 0xda:
|
||||
return readString<uint16_t>(key);
|
||||
|
||||
case 0xdb:
|
||||
return readString<uint32_t>(key);
|
||||
|
||||
default:
|
||||
_error = DeserializationError::NotSupported;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
MemoryPool *_pool;
|
||||
TReader _reader;
|
||||
TStringStorage _stringStorage;
|
||||
DeserializationError _error;
|
||||
};
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, const TInput &input,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, TInput *input,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, TInput *input, size_t inputSize,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
|
||||
template <typename TInput>
|
||||
DeserializationError deserializeMsgPack(
|
||||
JsonDocument &doc, TInput &input,
|
||||
NestingLimit nestingLimit = NestingLimit()) {
|
||||
return deserialize<MsgPackDeserializer>(doc, input, nestingLimit,
|
||||
AllowAllFilter());
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,187 +1,193 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Serialization/measure.hpp>
|
||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class MsgPackSerializer {
|
||||
public:
|
||||
MsgPackSerializer(TWriter writer) : _writer(writer), _bytesWritten(0) {}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4>::type visitFloat(T value32) {
|
||||
writeByte(0xCA);
|
||||
writeInteger(value32);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
||||
typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) {
|
||||
float value32 = float(value64);
|
||||
if (value32 == value64) {
|
||||
writeByte(0xCA);
|
||||
writeInteger(value32);
|
||||
} else {
|
||||
writeByte(0xCB);
|
||||
writeInteger(value64);
|
||||
}
|
||||
}
|
||||
|
||||
void visitArray(const CollectionData& array) {
|
||||
size_t n = array.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x90 + array.size()));
|
||||
} else if (n < 0x10000) {
|
||||
writeByte(0xDC);
|
||||
writeInteger(uint16_t(n));
|
||||
} else {
|
||||
writeByte(0xDD);
|
||||
writeInteger(uint32_t(n));
|
||||
}
|
||||
for (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
|
||||
slot->data()->accept(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void visitObject(const CollectionData& object) {
|
||||
size_t n = object.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x80 + n));
|
||||
} else if (n < 0x10000) {
|
||||
writeByte(0xDE);
|
||||
writeInteger(uint16_t(n));
|
||||
} else {
|
||||
writeByte(0xDF);
|
||||
writeInteger(uint32_t(n));
|
||||
}
|
||||
for (VariantSlot* slot = object.head(); slot; slot = slot->next()) {
|
||||
visitString(slot->key());
|
||||
slot->data()->accept(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void visitString(const char* value) {
|
||||
ARDUINOJSON_ASSERT(value != NULL);
|
||||
|
||||
size_t n = strlen(value);
|
||||
|
||||
if (n < 0x20) {
|
||||
writeByte(uint8_t(0xA0 + n));
|
||||
} else if (n < 0x100) {
|
||||
writeByte(0xD9);
|
||||
writeInteger(uint8_t(n));
|
||||
} else if (n < 0x10000) {
|
||||
writeByte(0xDA);
|
||||
writeInteger(uint16_t(n));
|
||||
} else {
|
||||
writeByte(0xDB);
|
||||
writeInteger(uint32_t(n));
|
||||
}
|
||||
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
||||
}
|
||||
|
||||
void visitRawJson(const char* data, size_t size) {
|
||||
writeBytes(reinterpret_cast<const uint8_t*>(data), size);
|
||||
}
|
||||
|
||||
void visitNegativeInteger(UInt value) {
|
||||
UInt negated = UInt(~value + 1);
|
||||
if (value <= 0x20) {
|
||||
writeInteger(int8_t(negated));
|
||||
} else if (value <= 0x80) {
|
||||
writeByte(0xD0);
|
||||
writeInteger(int8_t(negated));
|
||||
} else if (value <= 0x8000) {
|
||||
writeByte(0xD1);
|
||||
writeInteger(int16_t(negated));
|
||||
} else if (value <= 0x80000000) {
|
||||
writeByte(0xD2);
|
||||
writeInteger(int32_t(negated));
|
||||
}
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
else {
|
||||
writeByte(0xD3);
|
||||
writeInteger(int64_t(negated));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void visitPositiveInteger(UInt value) {
|
||||
if (value <= 0x7F) {
|
||||
writeInteger(uint8_t(value));
|
||||
} else if (value <= 0xFF) {
|
||||
writeByte(0xCC);
|
||||
writeInteger(uint8_t(value));
|
||||
} else if (value <= 0xFFFF) {
|
||||
writeByte(0xCD);
|
||||
writeInteger(uint16_t(value));
|
||||
} else if (value <= 0xFFFFFFFF) {
|
||||
writeByte(0xCE);
|
||||
writeInteger(uint32_t(value));
|
||||
}
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
else {
|
||||
writeByte(0xCF);
|
||||
writeInteger(uint64_t(value));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void visitBoolean(bool value) {
|
||||
writeByte(value ? 0xC3 : 0xC2);
|
||||
}
|
||||
|
||||
void visitNull() {
|
||||
writeByte(0xC0);
|
||||
}
|
||||
|
||||
size_t bytesWritten() const {
|
||||
return _bytesWritten;
|
||||
}
|
||||
|
||||
private:
|
||||
void writeByte(uint8_t c) {
|
||||
_bytesWritten += _writer.write(c);
|
||||
}
|
||||
|
||||
void writeBytes(const uint8_t* p, size_t n) {
|
||||
_bytesWritten += _writer.write(p, n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writeInteger(T value) {
|
||||
fixEndianess(value);
|
||||
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
TWriter _writer;
|
||||
size_t _bytesWritten;
|
||||
};
|
||||
|
||||
template <typename TSource, typename TDestination>
|
||||
inline size_t serializeMsgPack(const TSource& source, TDestination& output) {
|
||||
return serialize<MsgPackSerializer>(source, output);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
inline size_t serializeMsgPack(const TSource& source, void* output,
|
||||
size_t size) {
|
||||
return serialize<MsgPackSerializer>(source, output, size);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
inline size_t measureMsgPack(const TSource& source) {
|
||||
return measure<MsgPackSerializer>(source);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Serialization/measure.hpp>
|
||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TWriter>
|
||||
class MsgPackSerializer {
|
||||
public:
|
||||
MsgPackSerializer(TWriter writer) : _writer(writer), _bytesWritten(0) {}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4>::type visitFloat(T value32) {
|
||||
writeByte(0xCA);
|
||||
writeInteger(value32);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
||||
typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) {
|
||||
float value32 = float(value64);
|
||||
if (value32 == value64) {
|
||||
writeByte(0xCA);
|
||||
writeInteger(value32);
|
||||
} else {
|
||||
writeByte(0xCB);
|
||||
writeInteger(value64);
|
||||
}
|
||||
}
|
||||
|
||||
void visitArray(const CollectionData& array) {
|
||||
size_t n = array.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x90 + array.size()));
|
||||
} else if (n < 0x10000) {
|
||||
writeByte(0xDC);
|
||||
writeInteger(uint16_t(n));
|
||||
} else {
|
||||
writeByte(0xDD);
|
||||
writeInteger(uint32_t(n));
|
||||
}
|
||||
for (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
|
||||
slot->data()->accept(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void visitObject(const CollectionData& object) {
|
||||
size_t n = object.size();
|
||||
if (n < 0x10) {
|
||||
writeByte(uint8_t(0x80 + n));
|
||||
} else if (n < 0x10000) {
|
||||
writeByte(0xDE);
|
||||
writeInteger(uint16_t(n));
|
||||
} else {
|
||||
writeByte(0xDF);
|
||||
writeInteger(uint32_t(n));
|
||||
}
|
||||
for (VariantSlot* slot = object.head(); slot; slot = slot->next()) {
|
||||
visitString(slot->key());
|
||||
slot->data()->accept(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void visitString(const char* value) {
|
||||
ARDUINOJSON_ASSERT(value != NULL);
|
||||
|
||||
size_t n = strlen(value);
|
||||
|
||||
if (n < 0x20) {
|
||||
writeByte(uint8_t(0xA0 + n));
|
||||
} else if (n < 0x100) {
|
||||
writeByte(0xD9);
|
||||
writeInteger(uint8_t(n));
|
||||
} else if (n < 0x10000) {
|
||||
writeByte(0xDA);
|
||||
writeInteger(uint16_t(n));
|
||||
} else {
|
||||
writeByte(0xDB);
|
||||
writeInteger(uint32_t(n));
|
||||
}
|
||||
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
||||
}
|
||||
|
||||
void visitRawJson(const char* data, size_t size) {
|
||||
writeBytes(reinterpret_cast<const uint8_t*>(data), size);
|
||||
}
|
||||
|
||||
void visitNegativeInteger(UInt value) {
|
||||
UInt negated = UInt(~value + 1);
|
||||
if (value <= 0x20) {
|
||||
writeInteger(int8_t(negated));
|
||||
} else if (value <= 0x80) {
|
||||
writeByte(0xD0);
|
||||
writeInteger(int8_t(negated));
|
||||
} else if (value <= 0x8000) {
|
||||
writeByte(0xD1);
|
||||
writeInteger(int16_t(negated));
|
||||
} else if (value <= 0x80000000) {
|
||||
writeByte(0xD2);
|
||||
writeInteger(int32_t(negated));
|
||||
}
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
else {
|
||||
writeByte(0xD3);
|
||||
writeInteger(int64_t(negated));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void visitPositiveInteger(UInt value) {
|
||||
if (value <= 0x7F) {
|
||||
writeInteger(uint8_t(value));
|
||||
} else if (value <= 0xFF) {
|
||||
writeByte(0xCC);
|
||||
writeInteger(uint8_t(value));
|
||||
} else if (value <= 0xFFFF) {
|
||||
writeByte(0xCD);
|
||||
writeInteger(uint16_t(value));
|
||||
}
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
else if (value <= 0xFFFFFFFF)
|
||||
#else
|
||||
else
|
||||
#endif
|
||||
{
|
||||
writeByte(0xCE);
|
||||
writeInteger(uint32_t(value));
|
||||
}
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
else {
|
||||
writeByte(0xCF);
|
||||
writeInteger(uint64_t(value));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void visitBoolean(bool value) {
|
||||
writeByte(value ? 0xC3 : 0xC2);
|
||||
}
|
||||
|
||||
void visitNull() {
|
||||
writeByte(0xC0);
|
||||
}
|
||||
|
||||
size_t bytesWritten() const {
|
||||
return _bytesWritten;
|
||||
}
|
||||
|
||||
private:
|
||||
void writeByte(uint8_t c) {
|
||||
_bytesWritten += _writer.write(c);
|
||||
}
|
||||
|
||||
void writeBytes(const uint8_t* p, size_t n) {
|
||||
_bytesWritten += _writer.write(p, n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void writeInteger(T value) {
|
||||
fixEndianess(value);
|
||||
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
TWriter _writer;
|
||||
size_t _bytesWritten;
|
||||
};
|
||||
|
||||
template <typename TSource, typename TDestination>
|
||||
inline size_t serializeMsgPack(const TSource& source, TDestination& output) {
|
||||
return serialize<MsgPackSerializer>(source, output);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
inline size_t serializeMsgPack(const TSource& source, void* output,
|
||||
size_t size) {
|
||||
return serialize<MsgPackSerializer>(source, output, size);
|
||||
}
|
||||
|
||||
template <typename TSource>
|
||||
inline size_t measureMsgPack(const TSource& source) {
|
||||
return measure<MsgPackSerializer>(source);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,41 +1,41 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Polyfills/utility.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
#if ARDUINOJSON_LITTLE_ENDIAN
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) {
|
||||
swap(p[0], p[7]);
|
||||
swap(p[1], p[6]);
|
||||
swap(p[2], p[5]);
|
||||
swap(p[3], p[4]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) {
|
||||
swap(p[0], p[3]);
|
||||
swap(p[1], p[2]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) {
|
||||
swap(p[0], p[1]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {}
|
||||
|
||||
template <typename T>
|
||||
inline void fixEndianess(T &value) {
|
||||
fixEndianess(reinterpret_cast<uint8_t *>(&value),
|
||||
integral_constant<size_t, sizeof(T)>());
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
inline void fixEndianess(T &) {}
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Polyfills/utility.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
#if ARDUINOJSON_LITTLE_ENDIAN
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) {
|
||||
swap(p[0], p[7]);
|
||||
swap(p[1], p[6]);
|
||||
swap(p[2], p[5]);
|
||||
swap(p[3], p[4]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) {
|
||||
swap(p[0], p[3]);
|
||||
swap(p[1], p[2]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) {
|
||||
swap(p[0], p[1]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {}
|
||||
|
||||
template <typename T>
|
||||
inline void fixEndianess(T &value) {
|
||||
fixEndianess(reinterpret_cast<uint8_t *>(&value),
|
||||
integral_constant<size_t, sizeof(T)>());
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
inline void fixEndianess(T &) {}
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,18 +1,18 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline void doubleToFloat(const uint8_t d[8], uint8_t f[4]) {
|
||||
f[0] = uint8_t((d[0] & 0xC0) | (d[0] << 3 & 0x3f) | (d[1] >> 5));
|
||||
f[1] = uint8_t((d[1] << 3) | (d[2] >> 5));
|
||||
f[2] = uint8_t((d[2] << 3) | (d[3] >> 5));
|
||||
f[3] = uint8_t((d[3] << 3) | (d[4] >> 5));
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline void doubleToFloat(const uint8_t d[8], uint8_t f[4]) {
|
||||
f[0] = uint8_t((d[0] & 0xC0) | (d[0] << 3 & 0x3f) | (d[1] >> 5));
|
||||
f[1] = uint8_t((d[1] << 3) | (d[2] >> 5));
|
||||
f[2] = uint8_t((d[2] << 3) | (d[3] >> 5));
|
||||
f[3] = uint8_t((d[3] << 3) | (d[4] >> 5));
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
49
lib/ArduinoJson/src/ArduinoJson/Namespace.hpp
Normal file
49
lib/ArduinoJson/src/ArduinoJson/Namespace.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/version.hpp>
|
||||
|
||||
#ifndef ARDUINOJSON_NAMESPACE
|
||||
|
||||
#define ARDUINOJSON_HEX_DIGIT_0000() 0
|
||||
#define ARDUINOJSON_HEX_DIGIT_0001() 1
|
||||
#define ARDUINOJSON_HEX_DIGIT_0010() 2
|
||||
#define ARDUINOJSON_HEX_DIGIT_0011() 3
|
||||
#define ARDUINOJSON_HEX_DIGIT_0100() 4
|
||||
#define ARDUINOJSON_HEX_DIGIT_0101() 5
|
||||
#define ARDUINOJSON_HEX_DIGIT_0110() 6
|
||||
#define ARDUINOJSON_HEX_DIGIT_0111() 7
|
||||
#define ARDUINOJSON_HEX_DIGIT_1000() 8
|
||||
#define ARDUINOJSON_HEX_DIGIT_1001() 9
|
||||
#define ARDUINOJSON_HEX_DIGIT_1010() A
|
||||
#define ARDUINOJSON_HEX_DIGIT_1011() B
|
||||
#define ARDUINOJSON_HEX_DIGIT_1100() C
|
||||
#define ARDUINOJSON_HEX_DIGIT_1101() D
|
||||
#define ARDUINOJSON_HEX_DIGIT_1110() E
|
||||
#define ARDUINOJSON_HEX_DIGIT_1111() F
|
||||
#define ARDUINOJSON_HEX_DIGIT_(A, B, C, D) ARDUINOJSON_HEX_DIGIT_##A##B##C##D()
|
||||
#define ARDUINOJSON_HEX_DIGIT(A, B, C, D) ARDUINOJSON_HEX_DIGIT_(A, B, C, D)
|
||||
|
||||
#define ARDUINOJSON_CONCAT_(A, B) A##B
|
||||
#define ARDUINOJSON_CONCAT2(A, B) ARDUINOJSON_CONCAT_(A, B)
|
||||
#define ARDUINOJSON_CONCAT4(A, B, C, D) \
|
||||
ARDUINOJSON_CONCAT2(ARDUINOJSON_CONCAT2(A, B), ARDUINOJSON_CONCAT2(C, D))
|
||||
|
||||
#define ARDUINOJSON_NAMESPACE \
|
||||
ARDUINOJSON_CONCAT4( \
|
||||
ARDUINOJSON_CONCAT4(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
|
||||
ARDUINOJSON_VERSION_MINOR, \
|
||||
ARDUINOJSON_VERSION_REVISION), \
|
||||
_, \
|
||||
ARDUINOJSON_HEX_DIGIT(0, ARDUINOJSON_USE_LONG_LONG, \
|
||||
ARDUINOJSON_USE_DOUBLE, \
|
||||
ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \
|
||||
ARDUINOJSON_HEX_DIGIT( \
|
||||
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
|
||||
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE))
|
||||
|
||||
#endif
|
||||
@@ -1,17 +1,17 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
typedef double Float;
|
||||
#else
|
||||
typedef float Float;
|
||||
#endif
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
typedef double Float;
|
||||
#else
|
||||
typedef float Float;
|
||||
#endif
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,87 +1,87 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||
#include <ArduinoJson/Polyfills/math.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TFloat>
|
||||
struct FloatParts {
|
||||
uint32_t integral;
|
||||
uint32_t decimal;
|
||||
int16_t exponent;
|
||||
int8_t decimalPlaces;
|
||||
|
||||
FloatParts(TFloat value) {
|
||||
uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000;
|
||||
decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6;
|
||||
|
||||
exponent = normalize(value);
|
||||
|
||||
integral = uint32_t(value);
|
||||
// reduce number of decimal places by the number of integral places
|
||||
for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
|
||||
maxDecimalPart /= 10;
|
||||
decimalPlaces--;
|
||||
}
|
||||
|
||||
TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart);
|
||||
|
||||
decimal = uint32_t(remainder);
|
||||
remainder = remainder - TFloat(decimal);
|
||||
|
||||
// rounding:
|
||||
// increment by 1 if remainder >= 0.5
|
||||
decimal += uint32_t(remainder * 2);
|
||||
if (decimal >= maxDecimalPart) {
|
||||
decimal = 0;
|
||||
integral++;
|
||||
if (exponent && integral >= 10) {
|
||||
exponent++;
|
||||
integral = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// remove trailing zeros
|
||||
while (decimal % 10 == 0 && decimalPlaces > 0) {
|
||||
decimal /= 10;
|
||||
decimalPlaces--;
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t normalize(TFloat& value) {
|
||||
typedef FloatTraits<TFloat> traits;
|
||||
int16_t powersOf10 = 0;
|
||||
|
||||
int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
|
||||
int bit = 1 << index;
|
||||
|
||||
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
|
||||
for (; index >= 0; index--) {
|
||||
if (value >= traits::positiveBinaryPowerOfTen(index)) {
|
||||
value *= traits::negativeBinaryPowerOfTen(index);
|
||||
powersOf10 = int16_t(powersOf10 + bit);
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
|
||||
for (; index >= 0; index--) {
|
||||
if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
|
||||
value *= traits::positiveBinaryPowerOfTen(index);
|
||||
powersOf10 = int16_t(powersOf10 - bit);
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return powersOf10;
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||
#include <ArduinoJson/Polyfills/math.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TFloat>
|
||||
struct FloatParts {
|
||||
uint32_t integral;
|
||||
uint32_t decimal;
|
||||
int16_t exponent;
|
||||
int8_t decimalPlaces;
|
||||
|
||||
FloatParts(TFloat value) {
|
||||
uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000;
|
||||
decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6;
|
||||
|
||||
exponent = normalize(value);
|
||||
|
||||
integral = uint32_t(value);
|
||||
// reduce number of decimal places by the number of integral places
|
||||
for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
|
||||
maxDecimalPart /= 10;
|
||||
decimalPlaces--;
|
||||
}
|
||||
|
||||
TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart);
|
||||
|
||||
decimal = uint32_t(remainder);
|
||||
remainder = remainder - TFloat(decimal);
|
||||
|
||||
// rounding:
|
||||
// increment by 1 if remainder >= 0.5
|
||||
decimal += uint32_t(remainder * 2);
|
||||
if (decimal >= maxDecimalPart) {
|
||||
decimal = 0;
|
||||
integral++;
|
||||
if (exponent && integral >= 10) {
|
||||
exponent++;
|
||||
integral = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// remove trailing zeros
|
||||
while (decimal % 10 == 0 && decimalPlaces > 0) {
|
||||
decimal /= 10;
|
||||
decimalPlaces--;
|
||||
}
|
||||
}
|
||||
|
||||
static int16_t normalize(TFloat& value) {
|
||||
typedef FloatTraits<TFloat> traits;
|
||||
int16_t powersOf10 = 0;
|
||||
|
||||
int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
|
||||
int bit = 1 << index;
|
||||
|
||||
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
|
||||
for (; index >= 0; index--) {
|
||||
if (value >= traits::positiveBinaryPowerOfTen(index)) {
|
||||
value *= traits::negativeBinaryPowerOfTen(index);
|
||||
powersOf10 = int16_t(powersOf10 + bit);
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
|
||||
for (; index >= 0; index--) {
|
||||
if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
|
||||
value *= traits::positiveBinaryPowerOfTen(index);
|
||||
powersOf10 = int16_t(powersOf10 - bit);
|
||||
}
|
||||
bit >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
return powersOf10;
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,181 +1,181 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h>
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Polyfills/alias_cast.hpp>
|
||||
#include <ArduinoJson/Polyfills/math.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T, size_t = sizeof(T)>
|
||||
struct FloatTraits {};
|
||||
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 8 /*64bits*/> {
|
||||
typedef uint64_t mantissa_type;
|
||||
static const short mantissa_bits = 52;
|
||||
static const mantissa_type mantissa_max =
|
||||
(mantissa_type(1) << mantissa_bits) - 1;
|
||||
|
||||
typedef int16_t exponent_type;
|
||||
static const exponent_type exponent_max = 308;
|
||||
|
||||
template <typename TExponent>
|
||||
static T make_float(T m, TExponent e) {
|
||||
if (e > 0) {
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= positiveBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
} else {
|
||||
e = TExponent(-e);
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= negativeBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
static T positiveBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {
|
||||
1e1,
|
||||
1e2,
|
||||
1e4,
|
||||
1e8,
|
||||
1e16,
|
||||
forge(0x4693B8B5, 0xB5056E17), // 1e32
|
||||
forge(0x4D384F03, 0xE93FF9F5), // 1e64
|
||||
forge(0x5A827748, 0xF9301D32), // 1e128
|
||||
forge(0x75154FDD, 0x7F73BF3C) // 1e256
|
||||
};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {
|
||||
forge(0x3FB99999, 0x9999999A), // 1e-1
|
||||
forge(0x3F847AE1, 0x47AE147B), // 1e-2
|
||||
forge(0x3F1A36E2, 0xEB1C432D), // 1e-4
|
||||
forge(0x3E45798E, 0xE2308C3A), // 1e-8
|
||||
forge(0x3C9CD2B2, 0x97D889BC), // 1e-16
|
||||
forge(0x3949F623, 0xD5A8A733), // 1e-32
|
||||
forge(0x32A50FFD, 0x44F4A73D), // 1e-64
|
||||
forge(0x255BBA08, 0xCF8C979D), // 1e-128
|
||||
forge(0x0AC80628, 0x64AC6F43) // 1e-256
|
||||
};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
||||
static T factors[] = {
|
||||
1e0,
|
||||
forge(0x3FB99999, 0x9999999A), // 1e-1
|
||||
forge(0x3F50624D, 0xD2F1A9FC), // 1e-3
|
||||
forge(0x3E7AD7F2, 0x9ABCAF48), // 1e-7
|
||||
forge(0x3CD203AF, 0x9EE75616), // 1e-15
|
||||
forge(0x398039D6, 0x65896880), // 1e-31
|
||||
forge(0x32DA53FC, 0x9631D10D), // 1e-63
|
||||
forge(0x25915445, 0x81B7DEC2), // 1e-127
|
||||
forge(0x0AFE07B2, 0x7DD78B14) // 1e-255
|
||||
};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T nan() {
|
||||
return forge(0x7ff80000, 0x00000000);
|
||||
}
|
||||
|
||||
static T inf() {
|
||||
return forge(0x7ff00000, 0x00000000);
|
||||
}
|
||||
|
||||
static T highest() {
|
||||
return forge(0x7FEFFFFF, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static T lowest() {
|
||||
return forge(0xFFEFFFFF, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// constructs a double floating point values from its binary representation
|
||||
// we use this function to workaround platforms with single precision literals
|
||||
// (for example, when -fsingle-precision-constant is passed to GCC)
|
||||
static T forge(uint32_t msb, uint32_t lsb) {
|
||||
return alias_cast<T>((uint64_t(msb) << 32) | lsb);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 4 /*32bits*/> {
|
||||
typedef uint32_t mantissa_type;
|
||||
static const short mantissa_bits = 23;
|
||||
static const mantissa_type mantissa_max =
|
||||
(mantissa_type(1) << mantissa_bits) - 1;
|
||||
|
||||
typedef int8_t exponent_type;
|
||||
static const exponent_type exponent_max = 38;
|
||||
|
||||
template <typename TExponent>
|
||||
static T make_float(T m, TExponent e) {
|
||||
if (e > 0) {
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= positiveBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
} else {
|
||||
e = -e;
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= negativeBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
static T positiveBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
||||
static T factors[] = {1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T forge(uint32_t bits) {
|
||||
return alias_cast<T>(bits);
|
||||
}
|
||||
|
||||
static T nan() {
|
||||
return forge(0x7fc00000);
|
||||
}
|
||||
|
||||
static T inf() {
|
||||
return forge(0x7f800000);
|
||||
}
|
||||
|
||||
static T highest() {
|
||||
return forge(0x7f7fffff);
|
||||
}
|
||||
|
||||
static T lowest() {
|
||||
return forge(0xFf7fffff);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h>
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Polyfills/alias_cast.hpp>
|
||||
#include <ArduinoJson/Polyfills/math.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T, size_t = sizeof(T)>
|
||||
struct FloatTraits {};
|
||||
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 8 /*64bits*/> {
|
||||
typedef uint64_t mantissa_type;
|
||||
static const short mantissa_bits = 52;
|
||||
static const mantissa_type mantissa_max =
|
||||
(mantissa_type(1) << mantissa_bits) - 1;
|
||||
|
||||
typedef int16_t exponent_type;
|
||||
static const exponent_type exponent_max = 308;
|
||||
|
||||
template <typename TExponent>
|
||||
static T make_float(T m, TExponent e) {
|
||||
if (e > 0) {
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= positiveBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
} else {
|
||||
e = TExponent(-e);
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= negativeBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
static T positiveBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {
|
||||
1e1,
|
||||
1e2,
|
||||
1e4,
|
||||
1e8,
|
||||
1e16,
|
||||
forge(0x4693B8B5, 0xB5056E17), // 1e32
|
||||
forge(0x4D384F03, 0xE93FF9F5), // 1e64
|
||||
forge(0x5A827748, 0xF9301D32), // 1e128
|
||||
forge(0x75154FDD, 0x7F73BF3C) // 1e256
|
||||
};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {
|
||||
forge(0x3FB99999, 0x9999999A), // 1e-1
|
||||
forge(0x3F847AE1, 0x47AE147B), // 1e-2
|
||||
forge(0x3F1A36E2, 0xEB1C432D), // 1e-4
|
||||
forge(0x3E45798E, 0xE2308C3A), // 1e-8
|
||||
forge(0x3C9CD2B2, 0x97D889BC), // 1e-16
|
||||
forge(0x3949F623, 0xD5A8A733), // 1e-32
|
||||
forge(0x32A50FFD, 0x44F4A73D), // 1e-64
|
||||
forge(0x255BBA08, 0xCF8C979D), // 1e-128
|
||||
forge(0x0AC80628, 0x64AC6F43) // 1e-256
|
||||
};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
||||
static T factors[] = {
|
||||
1e0,
|
||||
forge(0x3FB99999, 0x9999999A), // 1e-1
|
||||
forge(0x3F50624D, 0xD2F1A9FC), // 1e-3
|
||||
forge(0x3E7AD7F2, 0x9ABCAF48), // 1e-7
|
||||
forge(0x3CD203AF, 0x9EE75616), // 1e-15
|
||||
forge(0x398039D6, 0x65896880), // 1e-31
|
||||
forge(0x32DA53FC, 0x9631D10D), // 1e-63
|
||||
forge(0x25915445, 0x81B7DEC2), // 1e-127
|
||||
forge(0x0AFE07B2, 0x7DD78B14) // 1e-255
|
||||
};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T nan() {
|
||||
return forge(0x7ff80000, 0x00000000);
|
||||
}
|
||||
|
||||
static T inf() {
|
||||
return forge(0x7ff00000, 0x00000000);
|
||||
}
|
||||
|
||||
static T highest() {
|
||||
return forge(0x7FEFFFFF, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static T lowest() {
|
||||
return forge(0xFFEFFFFF, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// constructs a double floating point values from its binary representation
|
||||
// we use this function to workaround platforms with single precision literals
|
||||
// (for example, when -fsingle-precision-constant is passed to GCC)
|
||||
static T forge(uint32_t msb, uint32_t lsb) {
|
||||
return alias_cast<T>((uint64_t(msb) << 32) | lsb);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 4 /*32bits*/> {
|
||||
typedef uint32_t mantissa_type;
|
||||
static const short mantissa_bits = 23;
|
||||
static const mantissa_type mantissa_max =
|
||||
(mantissa_type(1) << mantissa_bits) - 1;
|
||||
|
||||
typedef int8_t exponent_type;
|
||||
static const exponent_type exponent_max = 38;
|
||||
|
||||
template <typename TExponent>
|
||||
static T make_float(T m, TExponent e) {
|
||||
if (e > 0) {
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= positiveBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
} else {
|
||||
e = -e;
|
||||
for (uint8_t index = 0; e != 0; index++) {
|
||||
if (e & 1)
|
||||
m *= negativeBinaryPowerOfTen(index);
|
||||
e >>= 1;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
static T positiveBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTen(int index) {
|
||||
static T factors[] = {1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
||||
static T factors[] = {1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f};
|
||||
return factors[index];
|
||||
}
|
||||
|
||||
static T forge(uint32_t bits) {
|
||||
return alias_cast<T>(bits);
|
||||
}
|
||||
|
||||
static T nan() {
|
||||
return forge(0x7fc00000);
|
||||
}
|
||||
|
||||
static T inf() {
|
||||
return forge(0x7f800000);
|
||||
}
|
||||
|
||||
static T highest() {
|
||||
return forge(0x7f7fffff);
|
||||
}
|
||||
|
||||
static T lowest() {
|
||||
return forge(0xFf7fffff);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
32
lib/ArduinoJson/src/ArduinoJson/Numbers/Integer.hpp
Normal file
32
lib/ArduinoJson/src/ArduinoJson/Numbers/Integer.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stdint.h> // int64_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
typedef int64_t Integer;
|
||||
typedef uint64_t UInt;
|
||||
#else
|
||||
typedef long Integer;
|
||||
typedef unsigned long UInt;
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#if ARDUINOJSON_HAS_LONG_LONG && !ARDUINOJSON_USE_LONG_LONG
|
||||
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
|
||||
static_assert(sizeof(T) <= sizeof(ARDUINOJSON_NAMESPACE::Integer), \
|
||||
"To use 64-bit integers with ArduinoJson, you must set " \
|
||||
"ARDUINOJSON_USE_LONG_LONG to 1. See " \
|
||||
"https://arduinojson.org/v6/api/config/use_long_long/");
|
||||
#else
|
||||
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T)
|
||||
#endif
|
||||
121
lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp
Normal file
121
lib/ArduinoJson/src/ArduinoJson/Numbers/arithmeticCompare.hpp
Normal file
@@ -0,0 +1,121 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
enum CompareResult {
|
||||
COMPARE_RESULT_DIFFER = 0,
|
||||
COMPARE_RESULT_EQUAL = 1,
|
||||
COMPARE_RESULT_GREATER = 2,
|
||||
COMPARE_RESULT_LESS = 4,
|
||||
|
||||
COMPARE_RESULT_GREATER_OR_EQUAL = 3,
|
||||
COMPARE_RESULT_LESS_OR_EQUAL = 5
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
CompareResult arithmeticCompare(const T &lhs, const T &rhs) {
|
||||
if (lhs < rhs)
|
||||
return COMPARE_RESULT_LESS;
|
||||
else if (lhs > rhs)
|
||||
return COMPARE_RESULT_GREATER;
|
||||
else
|
||||
return COMPARE_RESULT_EQUAL;
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1 &lhs, const T2 &rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
sizeof(T1) < sizeof(T2),
|
||||
int // Using int instead of void to avoid C2572 on
|
||||
// Visual Studio 2012, 2013, and 2015
|
||||
>::type * = 0) {
|
||||
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1 &lhs, const T2 &rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
sizeof(T2) < sizeof(T1)>::type * = 0) {
|
||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1 &lhs, const T2 &rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_signed<T1>::value == is_signed<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1 &lhs, const T2 &rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_unsigned<T1>::value && is_signed<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
||||
if (rhs < 0)
|
||||
return COMPARE_RESULT_GREATER;
|
||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1 &lhs, const T2 &rhs,
|
||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||
is_signed<T1>::value && is_unsigned<T2>::value &&
|
||||
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
||||
if (lhs < 0)
|
||||
return COMPARE_RESULT_LESS;
|
||||
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
||||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
CompareResult arithmeticCompare(
|
||||
const T1 &lhs, const T2 &rhs,
|
||||
typename enable_if<is_floating_point<T1>::value ||
|
||||
is_floating_point<T2>::value>::type * = 0) {
|
||||
return arithmeticCompare<double>(static_cast<double>(lhs),
|
||||
static_cast<double>(rhs));
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
CompareResult arithmeticCompareNegateLeft(
|
||||
UInt, const T2 &, typename enable_if<is_unsigned<T2>::value>::type * = 0) {
|
||||
return COMPARE_RESULT_LESS;
|
||||
}
|
||||
|
||||
template <typename T2>
|
||||
CompareResult arithmeticCompareNegateLeft(
|
||||
UInt lhs, const T2 &rhs,
|
||||
typename enable_if<is_signed<T2>::value>::type * = 0) {
|
||||
if (rhs > 0)
|
||||
return COMPARE_RESULT_LESS;
|
||||
return arithmeticCompare(-rhs, static_cast<T2>(lhs));
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
CompareResult arithmeticCompareNegateRight(
|
||||
const T1 &, UInt, typename enable_if<is_unsigned<T1>::value>::type * = 0) {
|
||||
return COMPARE_RESULT_GREATER;
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
CompareResult arithmeticCompareNegateRight(
|
||||
const T1 &lhs, UInt rhs,
|
||||
typename enable_if<is_signed<T1>::value>::type * = 0) {
|
||||
if (lhs > 0)
|
||||
return COMPARE_RESULT_GREATER;
|
||||
return arithmeticCompare(static_cast<T1>(rhs), -lhs);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,105 +1,105 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
|
||||
#include <ArduinoJson/Numbers/Float.hpp>
|
||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||
#include <ArduinoJson/Polyfills/limits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
|
||||
bool>::type
|
||||
canStorePositiveInteger(TIn value) {
|
||||
return value <= TIn(numeric_limits<TOut>::highest());
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
|
||||
bool>::type
|
||||
canStorePositiveInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||
canStorePositiveInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) <= sizeof(TIn),
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn value) {
|
||||
return value <= TIn(numeric_limits<TOut>::highest()) + 1;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TIn) < sizeof(TOut),
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value,
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
TOut convertPositiveInteger(TIn value) {
|
||||
return canStorePositiveInteger<TOut>(value) ? TOut(value) : 0;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
TOut convertNegativeInteger(TIn value) {
|
||||
return canStoreNegativeInteger<TOut>(value) ? TOut(~value + 1) : 0;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||
TIn value) {
|
||||
return TOut(value);
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<!is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||
TIn value) {
|
||||
return value >= numeric_limits<TOut>::lowest() &&
|
||||
value <= numeric_limits<TOut>::highest()
|
||||
? TOut(value)
|
||||
: 0;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
|
||||
#include <ArduinoJson/Numbers/Float.hpp>
|
||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||
#include <ArduinoJson/Polyfills/limits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
|
||||
bool>::type
|
||||
canStorePositiveInteger(TIn value) {
|
||||
return value <= TIn(numeric_limits<TOut>::highest());
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
|
||||
bool>::type
|
||||
canStorePositiveInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||
canStorePositiveInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) <= sizeof(TIn),
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn value) {
|
||||
return value <= TIn(numeric_limits<TOut>::highest()) + 1;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TIn) < sizeof(TOut),
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value,
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
TOut convertPositiveInteger(TIn value) {
|
||||
return canStorePositiveInteger<TOut>(value) ? TOut(value) : 0;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
TOut convertNegativeInteger(TIn value) {
|
||||
return canStoreNegativeInteger<TOut>(value) ? TOut(~value + 1) : 0;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||
TIn value) {
|
||||
return TOut(value);
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<!is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||
TIn value) {
|
||||
return value >= numeric_limits<TOut>::lowest() &&
|
||||
value <= numeric_limits<TOut>::highest()
|
||||
? TOut(value)
|
||||
: 0;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,18 +1,20 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
inline T parseFloat(const char* s) {
|
||||
// try to reuse the same parameters as JsonDeserializer
|
||||
typedef typename choose_largest<Float, T>::type TFloat;
|
||||
return parseNumber<TFloat, UInt>(s).template as<T>();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
inline T parseFloat(const char* s) {
|
||||
// try to reuse the same parameters as JsonDeserializer
|
||||
typedef typename choose_largest<Float, T>::type TFloat;
|
||||
ParsedNumber<TFloat, UInt> value;
|
||||
parseNumber(s, value);
|
||||
return value.template as<T>();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,19 +1,21 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename T>
|
||||
T parseInteger(const char *s) {
|
||||
// try to reuse the same parameters as JsonDeserializer
|
||||
typedef typename choose_largest<UInt, typename make_unsigned<T>::type>::type
|
||||
TUInt;
|
||||
return parseNumber<Float, TUInt>(s).template as<T>();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||
#include <ArduinoJson/Numbers/parseNumber.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename T>
|
||||
T parseInteger(const char *s) {
|
||||
// try to reuse the same parameters as JsonDeserializer
|
||||
typedef typename choose_largest<UInt, typename make_unsigned<T>::type>::type
|
||||
TUInt;
|
||||
ParsedNumber<Float, TUInt> value;
|
||||
parseNumber(s, value);
|
||||
return value.template as<T>();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,163 +1,177 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/ctype.hpp>
|
||||
#include <ArduinoJson/Polyfills/math.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Variant/VariantContent.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TFloat, typename TUInt>
|
||||
struct ParsedNumber {
|
||||
ParsedNumber() : uintValue(0), floatValue(0), _type(VALUE_IS_NULL) {}
|
||||
|
||||
ParsedNumber(TUInt value, bool is_negative)
|
||||
: uintValue(value),
|
||||
floatValue(TFloat(value)),
|
||||
_type(uint8_t(is_negative ? VALUE_IS_NEGATIVE_INTEGER
|
||||
: VALUE_IS_POSITIVE_INTEGER)) {}
|
||||
ParsedNumber(TFloat value) : floatValue(value), _type(VALUE_IS_FLOAT) {}
|
||||
|
||||
template <typename T>
|
||||
T as() const {
|
||||
switch (_type) {
|
||||
case VALUE_IS_NEGATIVE_INTEGER:
|
||||
return convertNegativeInteger<T>(uintValue);
|
||||
case VALUE_IS_POSITIVE_INTEGER:
|
||||
return convertPositiveInteger<T>(uintValue);
|
||||
case VALUE_IS_FLOAT:
|
||||
return convertFloat<T>(floatValue);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
TUInt uintValue;
|
||||
TFloat floatValue;
|
||||
uint8_t _type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {};
|
||||
|
||||
template <typename TFloat, typename TUInt>
|
||||
inline ParsedNumber<TFloat, TUInt> parseNumber(const char *s) {
|
||||
typedef FloatTraits<TFloat> traits;
|
||||
typedef typename choose_largest<typename traits::mantissa_type, TUInt>::type
|
||||
mantissa_t;
|
||||
typedef typename traits::exponent_type exponent_t;
|
||||
typedef ParsedNumber<TFloat, TUInt> return_type;
|
||||
|
||||
ARDUINOJSON_ASSERT(s != 0);
|
||||
|
||||
bool is_negative = false;
|
||||
switch (*s) {
|
||||
case '-':
|
||||
is_negative = true;
|
||||
s++;
|
||||
break;
|
||||
case '+':
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_NAN
|
||||
if (*s == 'n' || *s == 'N')
|
||||
return traits::nan();
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_INFINITY
|
||||
if (*s == 'i' || *s == 'I')
|
||||
return is_negative ? -traits::inf() : traits::inf();
|
||||
#endif
|
||||
|
||||
if (!isdigit(*s) && *s != '.')
|
||||
return return_type();
|
||||
|
||||
mantissa_t mantissa = 0;
|
||||
exponent_t exponent_offset = 0;
|
||||
const mantissa_t maxUint = TUInt(-1);
|
||||
|
||||
while (isdigit(*s)) {
|
||||
uint8_t digit = uint8_t(*s - '0');
|
||||
if (mantissa > maxUint / 10)
|
||||
break;
|
||||
mantissa *= 10;
|
||||
if (mantissa > maxUint - digit)
|
||||
break;
|
||||
mantissa += digit;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '\0')
|
||||
return return_type(TUInt(mantissa), is_negative);
|
||||
|
||||
// avoid mantissa overflow
|
||||
while (mantissa > traits::mantissa_max) {
|
||||
mantissa /= 10;
|
||||
exponent_offset++;
|
||||
}
|
||||
|
||||
// remaing digits can't fit in the mantissa
|
||||
while (isdigit(*s)) {
|
||||
exponent_offset++;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '.') {
|
||||
s++;
|
||||
while (isdigit(*s)) {
|
||||
if (mantissa < traits::mantissa_max / 10) {
|
||||
mantissa = mantissa * 10 + uint8_t(*s - '0');
|
||||
exponent_offset--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
int exponent = 0;
|
||||
if (*s == 'e' || *s == 'E') {
|
||||
s++;
|
||||
bool negative_exponent = false;
|
||||
if (*s == '-') {
|
||||
negative_exponent = true;
|
||||
s++;
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
}
|
||||
|
||||
while (isdigit(*s)) {
|
||||
exponent = exponent * 10 + (*s - '0');
|
||||
if (exponent + exponent_offset > traits::exponent_max) {
|
||||
if (negative_exponent)
|
||||
return is_negative ? -0.0f : 0.0f;
|
||||
else
|
||||
return is_negative ? -traits::inf() : traits::inf();
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (negative_exponent)
|
||||
exponent = -exponent;
|
||||
}
|
||||
exponent += exponent_offset;
|
||||
|
||||
// we should be at the end of the string, otherwise it's an error
|
||||
if (*s != '\0')
|
||||
return return_type();
|
||||
|
||||
TFloat result = traits::make_float(static_cast<TFloat>(mantissa), exponent);
|
||||
|
||||
return is_negative ? -result : result;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
#include <ArduinoJson/Polyfills/ctype.hpp>
|
||||
#include <ArduinoJson/Polyfills/math.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Variant/VariantContent.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TFloat, typename TUInt>
|
||||
struct ParsedNumber {
|
||||
ParsedNumber() : _type(VALUE_IS_NULL) {}
|
||||
|
||||
void setInteger(TUInt value, bool is_negative) {
|
||||
uintValue = value;
|
||||
_type = uint8_t(is_negative ? VALUE_IS_NEGATIVE_INTEGER
|
||||
: VALUE_IS_POSITIVE_INTEGER);
|
||||
}
|
||||
|
||||
void setFloat(TFloat value) {
|
||||
floatValue = value;
|
||||
_type = VALUE_IS_FLOAT;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T as() const {
|
||||
switch (_type) {
|
||||
case VALUE_IS_NEGATIVE_INTEGER:
|
||||
return convertNegativeInteger<T>(uintValue);
|
||||
case VALUE_IS_POSITIVE_INTEGER:
|
||||
return convertPositiveInteger<T>(uintValue);
|
||||
case VALUE_IS_FLOAT:
|
||||
return convertFloat<T>(floatValue);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
union {
|
||||
TUInt uintValue;
|
||||
TFloat floatValue;
|
||||
};
|
||||
uint8_t _type;
|
||||
}; // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
template <typename A, typename B>
|
||||
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {};
|
||||
|
||||
template <typename TFloat, typename TUInt>
|
||||
inline void parseNumber(const char* s, ParsedNumber<TFloat, TUInt>& result) {
|
||||
typedef FloatTraits<TFloat> traits;
|
||||
typedef typename choose_largest<typename traits::mantissa_type, TUInt>::type
|
||||
mantissa_t;
|
||||
typedef typename traits::exponent_type exponent_t;
|
||||
|
||||
ARDUINOJSON_ASSERT(s != 0);
|
||||
|
||||
bool is_negative = false;
|
||||
switch (*s) {
|
||||
case '-':
|
||||
is_negative = true;
|
||||
s++;
|
||||
break;
|
||||
case '+':
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_NAN
|
||||
if (*s == 'n' || *s == 'N') {
|
||||
result.setFloat(traits::nan());
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_INFINITY
|
||||
if (*s == 'i' || *s == 'I') {
|
||||
result.setFloat(is_negative ? -traits::inf() : traits::inf());
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!isdigit(*s) && *s != '.')
|
||||
return;
|
||||
|
||||
mantissa_t mantissa = 0;
|
||||
exponent_t exponent_offset = 0;
|
||||
const mantissa_t maxUint = TUInt(-1);
|
||||
|
||||
while (isdigit(*s)) {
|
||||
uint8_t digit = uint8_t(*s - '0');
|
||||
if (mantissa > maxUint / 10)
|
||||
break;
|
||||
mantissa *= 10;
|
||||
if (mantissa > maxUint - digit)
|
||||
break;
|
||||
mantissa += digit;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '\0') {
|
||||
result.setInteger(TUInt(mantissa), is_negative);
|
||||
return;
|
||||
}
|
||||
|
||||
// avoid mantissa overflow
|
||||
while (mantissa > traits::mantissa_max) {
|
||||
mantissa /= 10;
|
||||
exponent_offset++;
|
||||
}
|
||||
|
||||
// remaing digits can't fit in the mantissa
|
||||
while (isdigit(*s)) {
|
||||
exponent_offset++;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '.') {
|
||||
s++;
|
||||
while (isdigit(*s)) {
|
||||
if (mantissa < traits::mantissa_max / 10) {
|
||||
mantissa = mantissa * 10 + uint8_t(*s - '0');
|
||||
exponent_offset--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
int exponent = 0;
|
||||
if (*s == 'e' || *s == 'E') {
|
||||
s++;
|
||||
bool negative_exponent = false;
|
||||
if (*s == '-') {
|
||||
negative_exponent = true;
|
||||
s++;
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
}
|
||||
|
||||
while (isdigit(*s)) {
|
||||
exponent = exponent * 10 + (*s - '0');
|
||||
if (exponent + exponent_offset > traits::exponent_max) {
|
||||
if (negative_exponent)
|
||||
result.setFloat(is_negative ? -0.0f : 0.0f);
|
||||
else
|
||||
result.setFloat(is_negative ? -traits::inf() : traits::inf());
|
||||
return;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (negative_exponent)
|
||||
exponent = -exponent;
|
||||
}
|
||||
exponent += exponent_offset;
|
||||
|
||||
// we should be at the end of the string, otherwise it's an error
|
||||
if (*s != '\0')
|
||||
return;
|
||||
|
||||
TFloat final_result =
|
||||
traits::make_float(static_cast<TFloat>(mantissa), exponent);
|
||||
|
||||
result.setFloat(is_negative ? -final_result : final_result);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,186 +1,187 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Operators/VariantOperators.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4522)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TObject, typename TStringRef>
|
||||
class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
public Visitable {
|
||||
typedef MemberProxy<TObject, TStringRef> this_type;
|
||||
|
||||
public:
|
||||
FORCE_INLINE MemberProxy(TObject variant, TStringRef key)
|
||||
: _object(variant), _key(key) {}
|
||||
|
||||
FORCE_INLINE MemberProxy(const MemberProxy &src)
|
||||
: _object(src._object), _key(src._key) {}
|
||||
|
||||
FORCE_INLINE operator VariantConstRef() const {
|
||||
return getUpstreamMember();
|
||||
}
|
||||
|
||||
FORCE_INLINE this_type &operator=(const this_type &src) {
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type
|
||||
operator=(const TValue &src) {
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// operator=(char*)
|
||||
// operator=(const char*)
|
||||
// operator=(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE this_type &operator=(TChar *src) {
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamMember()) == rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator!=(VariantConstRef rhs) const {
|
||||
return static_cast<VariantConstRef>(getUpstreamMember()) != rhs;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamMember().clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return getUpstreamMember().isNull();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantAs<TValue>::type as() const {
|
||||
return getUpstreamMember().template as<TValue>();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool is() const {
|
||||
return getUpstreamMember().template is<TValue>();
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return getUpstreamMember().size();
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
getUpstreamMember().remove(index);
|
||||
}
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
|
||||
TChar *key) const {
|
||||
getUpstreamMember().remove(key);
|
||||
}
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString &key) const {
|
||||
getUpstreamMember().remove(key);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
||||
return getOrAddUpstreamMember().template to<TValue>();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue &value) {
|
||||
return getOrAddUpstreamMember().set(value);
|
||||
}
|
||||
|
||||
// set(char*) const
|
||||
// set(const char*) const
|
||||
// set(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool set(TChar *value) {
|
||||
return getOrAddUpstreamMember().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor &visitor) const {
|
||||
return getUpstreamMember().accept(visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef addElement() const {
|
||||
return getOrAddUpstreamMember().addElement();
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return getUpstreamMember().getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
return getOrAddUpstreamMember().getOrAddElement(index);
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getMember(TChar *key) const {
|
||||
return getUpstreamMember().getMember(key);
|
||||
}
|
||||
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getMember(const TString &key) const {
|
||||
return getUpstreamMember().getMember(key);
|
||||
}
|
||||
|
||||
// getOrAddMember(char*) const
|
||||
// getOrAddMember(const char*) const
|
||||
// getOrAddMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar *key) const {
|
||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||
}
|
||||
|
||||
// getOrAddMember(const std::string&) const
|
||||
// getOrAddMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString &key) const {
|
||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||
}
|
||||
|
||||
private:
|
||||
FORCE_INLINE VariantRef getUpstreamMember() const {
|
||||
return _object.getMember(_key);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddUpstreamMember() const {
|
||||
return _object.getOrAddMember(_key);
|
||||
}
|
||||
|
||||
TObject _object;
|
||||
TStringRef _key;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4522)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TObject, typename TStringRef>
|
||||
class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
public VariantShortcuts<MemberProxy<TObject, TStringRef> >,
|
||||
public Visitable {
|
||||
typedef MemberProxy<TObject, TStringRef> this_type;
|
||||
|
||||
public:
|
||||
FORCE_INLINE MemberProxy(TObject variant, TStringRef key)
|
||||
: _object(variant), _key(key) {}
|
||||
|
||||
FORCE_INLINE MemberProxy(const MemberProxy &src)
|
||||
: _object(src._object), _key(src._key) {}
|
||||
|
||||
FORCE_INLINE operator VariantConstRef() const {
|
||||
return getUpstreamMember();
|
||||
}
|
||||
|
||||
FORCE_INLINE this_type &operator=(const this_type &src) {
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type
|
||||
operator=(const TValue &src) {
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// operator=(char*)
|
||||
// operator=(const char*)
|
||||
// operator=(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE this_type &operator=(TChar *src) {
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamMember().clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return getUpstreamMember().isNull();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantAs<TValue>::type as() const {
|
||||
return getUpstreamMember().template as<TValue>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE operator T() const {
|
||||
return getUpstreamMember();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool is() const {
|
||||
return getUpstreamMember().template is<TValue>();
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return getUpstreamMember().size();
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
getUpstreamMember().remove(index);
|
||||
}
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
|
||||
TChar *key) const {
|
||||
getUpstreamMember().remove(key);
|
||||
}
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString &key) const {
|
||||
getUpstreamMember().remove(key);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
||||
return getOrAddUpstreamMember().template to<TValue>();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue &value) {
|
||||
return getOrAddUpstreamMember().set(value);
|
||||
}
|
||||
|
||||
// set(char*) const
|
||||
// set(const char*) const
|
||||
// set(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool set(TChar *value) {
|
||||
return getOrAddUpstreamMember().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor &visitor) const {
|
||||
return getUpstreamMember().accept(visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef addElement() const {
|
||||
return getOrAddUpstreamMember().addElement();
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return getUpstreamMember().getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||
return getOrAddUpstreamMember().getOrAddElement(index);
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getMember(TChar *key) const {
|
||||
return getUpstreamMember().getMember(key);
|
||||
}
|
||||
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getMember(const TString &key) const {
|
||||
return getUpstreamMember().getMember(key);
|
||||
}
|
||||
|
||||
// getOrAddMember(char*) const
|
||||
// getOrAddMember(const char*) const
|
||||
// getOrAddMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar *key) const {
|
||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||
}
|
||||
|
||||
// getOrAddMember(const std::string&) const
|
||||
// getOrAddMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString &key) const {
|
||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||
}
|
||||
|
||||
private:
|
||||
FORCE_INLINE VariantRef getUpstreamMember() const {
|
||||
return _object.getMember(_key);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrAddUpstreamMember() const {
|
||||
return _object.getOrAddMember(_key);
|
||||
}
|
||||
|
||||
TObject _object;
|
||||
TStringRef _key;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
@@ -1,50 +1,50 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename Visitor>
|
||||
void objectAccept(const CollectionData *obj, Visitor &visitor) {
|
||||
if (obj)
|
||||
visitor.visitObject(*obj);
|
||||
else
|
||||
visitor.visitNull();
|
||||
}
|
||||
|
||||
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||
if (lhs == rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return lhs->equalsObject(*rhs);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData *objectGetMember(const CollectionData *obj,
|
||||
TAdaptedString key) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
return obj->getMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void objectRemove(CollectionData *obj, TAdaptedString key) {
|
||||
if (!obj)
|
||||
return;
|
||||
obj->removeMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData *objectGetOrAddMember(CollectionData *obj,
|
||||
TAdaptedString key, MemoryPool *pool) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
return obj->getOrAddMember(key, pool);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename Visitor>
|
||||
void objectAccept(const CollectionData *obj, Visitor &visitor) {
|
||||
if (obj)
|
||||
visitor.visitObject(*obj);
|
||||
else
|
||||
visitor.visitNull();
|
||||
}
|
||||
|
||||
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||
if (lhs == rhs)
|
||||
return true;
|
||||
if (!lhs || !rhs)
|
||||
return false;
|
||||
return lhs->equalsObject(*rhs);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData *objectGetMember(const CollectionData *obj,
|
||||
TAdaptedString key) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
return obj->getMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
void objectRemove(CollectionData *obj, TAdaptedString key) {
|
||||
if (!obj)
|
||||
return;
|
||||
obj->removeMember(key);
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline VariantData *objectGetOrAddMember(CollectionData *obj,
|
||||
TAdaptedString key, MemoryPool *pool) {
|
||||
if (!obj)
|
||||
return 0;
|
||||
|
||||
return obj->getOrAddMember(key, pool);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,69 +1,69 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
|
||||
const TString& key) const {
|
||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const {
|
||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||
const TString& key) const {
|
||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||
TChar* key) const {
|
||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value, bool>::type
|
||||
ObjectShortcuts<TObject>::containsKey(const TString& key) const {
|
||||
return !impl()->getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline typename enable_if<IsString<TChar*>::value, bool>::type
|
||||
ObjectShortcuts<TObject>::containsKey(TChar* key) const {
|
||||
return !impl()->getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString*>::value,
|
||||
MemberProxy<TObject, TString*> >::type
|
||||
ObjectShortcuts<TObject>::operator[](TString* key) const {
|
||||
return MemberProxy<TObject, TString*>(*impl(), key);
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<TObject, TString> >::type
|
||||
ObjectShortcuts<TObject>::operator[](const TString& key) const {
|
||||
return MemberProxy<TObject, TString>(*impl(), key);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
|
||||
const TString& key) const {
|
||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const {
|
||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||
const TString& key) const {
|
||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||
TChar* key) const {
|
||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value, bool>::type
|
||||
ObjectShortcuts<TObject>::containsKey(const TString& key) const {
|
||||
return !impl()->getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline typename enable_if<IsString<TChar*>::value, bool>::type
|
||||
ObjectShortcuts<TObject>::containsKey(TChar* key) const {
|
||||
return !impl()->getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString*>::value,
|
||||
MemberProxy<TObject, TString*> >::type
|
||||
ObjectShortcuts<TObject>::operator[](TString* key) const {
|
||||
return MemberProxy<TObject, TString*>(*impl(), key);
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<TObject, TString> >::type
|
||||
ObjectShortcuts<TObject>::operator[](const TString& key) const {
|
||||
return MemberProxy<TObject, TString>(*impl(), key);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,123 +1,123 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Object/Pair.hpp>
|
||||
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class PairPtr {
|
||||
public:
|
||||
PairPtr(MemoryPool *pool, VariantSlot *slot) : _pair(pool, slot) {}
|
||||
|
||||
const Pair *operator->() const {
|
||||
return &_pair;
|
||||
}
|
||||
|
||||
const Pair &operator*() const {
|
||||
return _pair;
|
||||
}
|
||||
|
||||
private:
|
||||
Pair _pair;
|
||||
};
|
||||
|
||||
class ObjectIterator {
|
||||
public:
|
||||
ObjectIterator() : _slot(0) {}
|
||||
|
||||
explicit ObjectIterator(MemoryPool *pool, VariantSlot *slot)
|
||||
: _pool(pool), _slot(slot) {}
|
||||
|
||||
Pair operator*() const {
|
||||
return Pair(_pool, _slot);
|
||||
}
|
||||
PairPtr operator->() {
|
||||
return PairPtr(_pool, _slot);
|
||||
}
|
||||
|
||||
bool operator==(const ObjectIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ObjectIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ObjectIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ObjectIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool *_pool;
|
||||
VariantSlot *_slot;
|
||||
};
|
||||
|
||||
class PairConstPtr {
|
||||
public:
|
||||
PairConstPtr(const VariantSlot *slot) : _pair(slot) {}
|
||||
|
||||
const PairConst *operator->() const {
|
||||
return &_pair;
|
||||
}
|
||||
|
||||
const PairConst &operator*() const {
|
||||
return _pair;
|
||||
}
|
||||
|
||||
private:
|
||||
PairConst _pair;
|
||||
};
|
||||
|
||||
class ObjectConstIterator {
|
||||
public:
|
||||
ObjectConstIterator() : _slot(0) {}
|
||||
|
||||
explicit ObjectConstIterator(const VariantSlot *slot) : _slot(slot) {}
|
||||
|
||||
PairConst operator*() const {
|
||||
return PairConst(_slot);
|
||||
}
|
||||
PairConstPtr operator->() {
|
||||
return PairConstPtr(_slot);
|
||||
}
|
||||
|
||||
bool operator==(const ObjectConstIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ObjectConstIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ObjectConstIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ObjectConstIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
const VariantSlot *_slot;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Object/Pair.hpp>
|
||||
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class PairPtr {
|
||||
public:
|
||||
PairPtr(MemoryPool *pool, VariantSlot *slot) : _pair(pool, slot) {}
|
||||
|
||||
const Pair *operator->() const {
|
||||
return &_pair;
|
||||
}
|
||||
|
||||
const Pair &operator*() const {
|
||||
return _pair;
|
||||
}
|
||||
|
||||
private:
|
||||
Pair _pair;
|
||||
};
|
||||
|
||||
class ObjectIterator {
|
||||
public:
|
||||
ObjectIterator() : _slot(0) {}
|
||||
|
||||
explicit ObjectIterator(MemoryPool *pool, VariantSlot *slot)
|
||||
: _pool(pool), _slot(slot) {}
|
||||
|
||||
Pair operator*() const {
|
||||
return Pair(_pool, _slot);
|
||||
}
|
||||
PairPtr operator->() {
|
||||
return PairPtr(_pool, _slot);
|
||||
}
|
||||
|
||||
bool operator==(const ObjectIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ObjectIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ObjectIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ObjectIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool *_pool;
|
||||
VariantSlot *_slot;
|
||||
};
|
||||
|
||||
class PairConstPtr {
|
||||
public:
|
||||
PairConstPtr(const VariantSlot *slot) : _pair(slot) {}
|
||||
|
||||
const PairConst *operator->() const {
|
||||
return &_pair;
|
||||
}
|
||||
|
||||
const PairConst &operator*() const {
|
||||
return _pair;
|
||||
}
|
||||
|
||||
private:
|
||||
PairConst _pair;
|
||||
};
|
||||
|
||||
class ObjectConstIterator {
|
||||
public:
|
||||
ObjectConstIterator() : _slot(0) {}
|
||||
|
||||
explicit ObjectConstIterator(const VariantSlot *slot) : _slot(slot) {}
|
||||
|
||||
PairConst operator*() const {
|
||||
return PairConst(_slot);
|
||||
}
|
||||
PairConstPtr operator->() {
|
||||
return PairConstPtr(_slot);
|
||||
}
|
||||
|
||||
bool operator==(const ObjectConstIterator &other) const {
|
||||
return _slot == other._slot;
|
||||
}
|
||||
|
||||
bool operator!=(const ObjectConstIterator &other) const {
|
||||
return _slot != other._slot;
|
||||
}
|
||||
|
||||
ObjectConstIterator &operator++() {
|
||||
_slot = _slot->next();
|
||||
return *this;
|
||||
}
|
||||
|
||||
ObjectConstIterator &operator+=(size_t distance) {
|
||||
_slot = _slot->next(distance);
|
||||
return *this;
|
||||
}
|
||||
|
||||
const VariantSlot *internal() {
|
||||
return _slot;
|
||||
}
|
||||
|
||||
private:
|
||||
const VariantSlot *_slot;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,239 +1,239 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Object/ObjectFunctions.hpp>
|
||||
#include <ArduinoJson/Object/ObjectIterator.hpp>
|
||||
|
||||
// Returns the size (in bytes) of an object with n elements.
|
||||
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
|
||||
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TData>
|
||||
class ObjectRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
const void* data = _data; // prevent warning cast-align
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
||||
objectAccept(_data, visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return _data == 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE operator bool() const {
|
||||
return _data != 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t memoryUsage() const {
|
||||
return _data ? _data->memoryUsage() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t nesting() const {
|
||||
return _data ? _data->nesting() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return _data ? _data->size() : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
ObjectRefBase(TData* data) : _data(data) {}
|
||||
TData* _data;
|
||||
};
|
||||
|
||||
class ObjectConstRef : public ObjectRefBase<const CollectionData>,
|
||||
public Visitable {
|
||||
friend class ObjectRef;
|
||||
typedef ObjectRefBase<const CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ObjectConstIterator iterator;
|
||||
|
||||
ObjectConstRef() : base_type(0) {}
|
||||
ObjectConstRef(const CollectionData* data) : base_type(data) {}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE bool containsKey(const TString& key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool containsKey(TChar* key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantConstRef getMember(const TString& key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// operator[](const std::string&) const
|
||||
// operator[](const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
operator[](const TString& key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// operator[](char*) const
|
||||
// operator[](const char*) const
|
||||
// operator[](const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
||||
operator[](TChar* key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ObjectConstRef rhs) const {
|
||||
return objectEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename TAdaptedString>
|
||||
FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const {
|
||||
return VariantConstRef(objectGetMember(_data, key));
|
||||
}
|
||||
};
|
||||
|
||||
class ObjectRef : public ObjectRefBase<CollectionData>,
|
||||
public ObjectShortcuts<ObjectRef>,
|
||||
public Visitable {
|
||||
typedef ObjectRefBase<CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ObjectIterator iterator;
|
||||
|
||||
FORCE_INLINE ObjectRef() : base_type(0), _pool(0) {}
|
||||
FORCE_INLINE ObjectRef(MemoryPool* buf, CollectionData* data)
|
||||
: base_type(data), _pool(buf) {}
|
||||
|
||||
operator VariantRef() const {
|
||||
void* data = _data; // prevent warning cast-align
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||
}
|
||||
|
||||
operator ObjectConstRef() const {
|
||||
return ObjectConstRef(_data);
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_pool, _data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
void clear() const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool set(ObjectConstRef src) {
|
||||
if (!_data || !src._data)
|
||||
return false;
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getMember(const TString& key) const {
|
||||
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getMember(TChar* key) const {
|
||||
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
||||
}
|
||||
|
||||
// getOrAddMember(const std::string&) const
|
||||
// getOrAddMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
|
||||
return VariantRef(_pool,
|
||||
objectGetOrAddMember(_data, adaptString(key), _pool));
|
||||
}
|
||||
|
||||
// getOrAddMember(char*) const
|
||||
// getOrAddMember(const char*) const
|
||||
// getOrAddMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
|
||||
return VariantRef(_pool,
|
||||
objectGetOrAddMember(_data, adaptString(key), _pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ObjectRef rhs) const {
|
||||
return objectEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeSlot(it.internal());
|
||||
}
|
||||
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE void remove(const TString& key) const {
|
||||
objectRemove(_data, adaptString(key));
|
||||
}
|
||||
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE void remove(TChar* key) const {
|
||||
objectRemove(_data, adaptString(key));
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool* _pool;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Object/ObjectFunctions.hpp>
|
||||
#include <ArduinoJson/Object/ObjectIterator.hpp>
|
||||
|
||||
// Returns the size (in bytes) of an object with n elements.
|
||||
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
|
||||
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TData>
|
||||
class ObjectRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
const void* data = _data; // prevent warning cast-align
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
||||
objectAccept(_data, visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return _data == 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE operator bool() const {
|
||||
return _data != 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t memoryUsage() const {
|
||||
return _data ? _data->memoryUsage() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t nesting() const {
|
||||
return _data ? _data->nesting() : 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return _data ? _data->size() : 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
ObjectRefBase(TData* data) : _data(data) {}
|
||||
TData* _data;
|
||||
};
|
||||
|
||||
class ObjectConstRef : public ObjectRefBase<const CollectionData>,
|
||||
public Visitable {
|
||||
friend class ObjectRef;
|
||||
typedef ObjectRefBase<const CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ObjectConstIterator iterator;
|
||||
|
||||
ObjectConstRef() : base_type(0) {}
|
||||
ObjectConstRef(const CollectionData* data) : base_type(data) {}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE bool containsKey(const TString& key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool containsKey(TChar* key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantConstRef getMember(const TString& key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// operator[](const std::string&) const
|
||||
// operator[](const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
operator[](const TString& key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// operator[](char*) const
|
||||
// operator[](const char*) const
|
||||
// operator[](const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
||||
operator[](TChar* key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ObjectConstRef rhs) const {
|
||||
return objectEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename TAdaptedString>
|
||||
FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const {
|
||||
return VariantConstRef(objectGetMember(_data, key));
|
||||
}
|
||||
};
|
||||
|
||||
class ObjectRef : public ObjectRefBase<CollectionData>,
|
||||
public ObjectShortcuts<ObjectRef>,
|
||||
public Visitable {
|
||||
typedef ObjectRefBase<CollectionData> base_type;
|
||||
|
||||
public:
|
||||
typedef ObjectIterator iterator;
|
||||
|
||||
FORCE_INLINE ObjectRef() : base_type(0), _pool(0) {}
|
||||
FORCE_INLINE ObjectRef(MemoryPool* buf, CollectionData* data)
|
||||
: base_type(data), _pool(buf) {}
|
||||
|
||||
operator VariantRef() const {
|
||||
void* data = _data; // prevent warning cast-align
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||
}
|
||||
|
||||
operator ObjectConstRef() const {
|
||||
return ObjectConstRef(_data);
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator begin() const {
|
||||
if (!_data)
|
||||
return iterator();
|
||||
return iterator(_pool, _data->head());
|
||||
}
|
||||
|
||||
FORCE_INLINE iterator end() const {
|
||||
return iterator();
|
||||
}
|
||||
|
||||
void clear() const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool set(ObjectConstRef src) {
|
||||
if (!_data || !src._data)
|
||||
return false;
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getMember(const TString& key) const {
|
||||
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getMember(TChar* key) const {
|
||||
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
||||
}
|
||||
|
||||
// getOrAddMember(const std::string&) const
|
||||
// getOrAddMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
|
||||
return VariantRef(_pool,
|
||||
objectGetOrAddMember(_data, adaptString(key), _pool));
|
||||
}
|
||||
|
||||
// getOrAddMember(char*) const
|
||||
// getOrAddMember(const char*) const
|
||||
// getOrAddMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
|
||||
return VariantRef(_pool,
|
||||
objectGetOrAddMember(_data, adaptString(key), _pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ObjectRef rhs) const {
|
||||
return objectEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(iterator it) const {
|
||||
if (!_data)
|
||||
return;
|
||||
_data->removeSlot(it.internal());
|
||||
}
|
||||
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE void remove(const TString& key) const {
|
||||
objectRemove(_data, adaptString(key));
|
||||
}
|
||||
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE void remove(TChar* key) const {
|
||||
objectRemove(_data, adaptString(key));
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool* _pool;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,73 +1,73 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename TParent, typename TStringRef>
|
||||
class MemberProxy;
|
||||
|
||||
template <typename TObject>
|
||||
class ObjectShortcuts {
|
||||
public:
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type
|
||||
containsKey(const TString &key) const;
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type
|
||||
containsKey(TChar *key) const;
|
||||
|
||||
// operator[](const std::string&) const
|
||||
// operator[](const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<TObject, TString> >::type
|
||||
operator[](const TString &key) const;
|
||||
|
||||
// operator[](char*) const
|
||||
// operator[](const char*) const
|
||||
// operator[](const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value,
|
||||
MemberProxy<TObject, TChar *> >::type
|
||||
operator[](TChar *key) const;
|
||||
|
||||
// createNestedArray(const std::string&) const
|
||||
// createNestedArray(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE ArrayRef createNestedArray(const TString &key) const;
|
||||
|
||||
// createNestedArray(char*) const
|
||||
// createNestedArray(const char*) const
|
||||
// createNestedArray(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE ArrayRef createNestedArray(TChar *key) const;
|
||||
|
||||
// createNestedObject(const std::string&) const
|
||||
// createNestedObject(const String&) const
|
||||
template <typename TString>
|
||||
ObjectRef createNestedObject(const TString &key) const;
|
||||
|
||||
// createNestedObject(char*) const
|
||||
// createNestedObject(const char*) const
|
||||
// createNestedObject(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
ObjectRef createNestedObject(TChar *key) const;
|
||||
|
||||
private:
|
||||
const TObject *impl() const {
|
||||
return static_cast<const TObject *>(this);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename TParent, typename TStringRef>
|
||||
class MemberProxy;
|
||||
|
||||
template <typename TObject>
|
||||
class ObjectShortcuts {
|
||||
public:
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type
|
||||
containsKey(const TString &key) const;
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type
|
||||
containsKey(TChar *key) const;
|
||||
|
||||
// operator[](const std::string&) const
|
||||
// operator[](const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||
MemberProxy<TObject, TString> >::type
|
||||
operator[](const TString &key) const;
|
||||
|
||||
// operator[](char*) const
|
||||
// operator[](const char*) const
|
||||
// operator[](const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value,
|
||||
MemberProxy<TObject, TChar *> >::type
|
||||
operator[](TChar *key) const;
|
||||
|
||||
// createNestedArray(const std::string&) const
|
||||
// createNestedArray(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE ArrayRef createNestedArray(const TString &key) const;
|
||||
|
||||
// createNestedArray(char*) const
|
||||
// createNestedArray(const char*) const
|
||||
// createNestedArray(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE ArrayRef createNestedArray(TChar *key) const;
|
||||
|
||||
// createNestedObject(const std::string&) const
|
||||
// createNestedObject(const String&) const
|
||||
template <typename TString>
|
||||
ObjectRef createNestedObject(const TString &key) const;
|
||||
|
||||
// createNestedObject(char*) const
|
||||
// createNestedObject(const char*) const
|
||||
// createNestedObject(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
ObjectRef createNestedObject(TChar *key) const;
|
||||
|
||||
private:
|
||||
const TObject *impl() const {
|
||||
return static_cast<const TObject *>(this);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,55 +1,55 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Strings/String.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
// A key value pair for CollectionData.
|
||||
class Pair {
|
||||
public:
|
||||
Pair(MemoryPool* pool, VariantSlot* slot) {
|
||||
if (slot) {
|
||||
_key = String(slot->key(), !slot->ownsKey());
|
||||
_value = VariantRef(pool, slot->data());
|
||||
}
|
||||
}
|
||||
|
||||
String key() const {
|
||||
return _key;
|
||||
}
|
||||
|
||||
VariantRef value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
private:
|
||||
String _key;
|
||||
VariantRef _value;
|
||||
};
|
||||
|
||||
class PairConst {
|
||||
public:
|
||||
PairConst(const VariantSlot* slot) {
|
||||
if (slot) {
|
||||
_key = String(slot->key(), !slot->ownsKey());
|
||||
_value = VariantConstRef(slot->data());
|
||||
}
|
||||
}
|
||||
|
||||
String key() const {
|
||||
return _key;
|
||||
}
|
||||
|
||||
VariantConstRef value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
private:
|
||||
String _key;
|
||||
VariantConstRef _value;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Strings/String.hpp>
|
||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
// A key value pair for CollectionData.
|
||||
class Pair {
|
||||
public:
|
||||
Pair(MemoryPool* pool, VariantSlot* slot) {
|
||||
if (slot) {
|
||||
_key = String(slot->key(), !slot->ownsKey());
|
||||
_value = VariantRef(pool, slot->data());
|
||||
}
|
||||
}
|
||||
|
||||
String key() const {
|
||||
return _key;
|
||||
}
|
||||
|
||||
VariantRef value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
private:
|
||||
String _key;
|
||||
VariantRef _value;
|
||||
};
|
||||
|
||||
class PairConst {
|
||||
public:
|
||||
PairConst(const VariantSlot* slot) {
|
||||
if (slot) {
|
||||
_key = String(slot->key(), !slot->ownsKey());
|
||||
_value = VariantConstRef(slot->data());
|
||||
}
|
||||
}
|
||||
|
||||
String key() const {
|
||||
return _key;
|
||||
}
|
||||
|
||||
VariantConstRef value() const {
|
||||
return _value;
|
||||
}
|
||||
|
||||
private:
|
||||
String _key;
|
||||
VariantConstRef _value;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,29 +1,29 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // for size_t
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include "math.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T, typename F>
|
||||
struct alias_cast_t {
|
||||
union {
|
||||
F raw;
|
||||
T data;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
T alias_cast(F raw_data) {
|
||||
alias_cast_t<T, F> ac;
|
||||
ac.raw = raw_data;
|
||||
return ac.data;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // for size_t
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
#include "math.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T, typename F>
|
||||
struct alias_cast_t {
|
||||
union {
|
||||
F raw;
|
||||
T data;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
T alias_cast(F raw_data) {
|
||||
alias_cast_t<T, F> ac;
|
||||
ac.raw = raw_data;
|
||||
return ac.data;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,14 +1,14 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
|
||||
#if ARDUINOJSON_DEBUG
|
||||
#include <assert.h>
|
||||
#define ARDUINOJSON_ASSERT(X) assert(X)
|
||||
#else
|
||||
#define ARDUINOJSON_ASSERT(X) ((void)0)
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Configuration.hpp>
|
||||
|
||||
#if ARDUINOJSON_DEBUG
|
||||
#include <assert.h>
|
||||
#define ARDUINOJSON_ASSERT(X) assert(X)
|
||||
#else
|
||||
#define ARDUINOJSON_ASSERT(X) ((void)0)
|
||||
#endif
|
||||
@@ -1,45 +1,45 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER // Visual Studio
|
||||
|
||||
#define FORCE_INLINE // __forceinline causes C4714 when returning std::string
|
||||
#define NO_INLINE __declspec(noinline)
|
||||
#define DEPRECATED(msg) __declspec(deprecated(msg))
|
||||
|
||||
#elif defined(__GNUC__) // GCC or Clang
|
||||
|
||||
#define FORCE_INLINE __attribute__((always_inline))
|
||||
#define NO_INLINE __attribute__((noinline))
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#else
|
||||
#define DEPRECATED(msg) __attribute__((deprecated))
|
||||
#endif
|
||||
|
||||
#else // Other compilers
|
||||
|
||||
#define FORCE_INLINE
|
||||
#define NO_INLINE
|
||||
#define DEPRECATED(msg)
|
||||
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define NOEXCEPT noexcept
|
||||
#else
|
||||
#define NOEXCEPT throw()
|
||||
#endif
|
||||
|
||||
#if defined(__has_attribute)
|
||||
#if __has_attribute(no_sanitize)
|
||||
#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
|
||||
#else
|
||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||
#endif
|
||||
#else
|
||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER // Visual Studio
|
||||
|
||||
#define FORCE_INLINE // __forceinline causes C4714 when returning std::string
|
||||
#define NO_INLINE __declspec(noinline)
|
||||
#define DEPRECATED(msg) __declspec(deprecated(msg))
|
||||
|
||||
#elif defined(__GNUC__) // GCC or Clang
|
||||
|
||||
#define FORCE_INLINE __attribute__((always_inline))
|
||||
#define NO_INLINE __attribute__((noinline))
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||
#else
|
||||
#define DEPRECATED(msg) __attribute__((deprecated))
|
||||
#endif
|
||||
|
||||
#else // Other compilers
|
||||
|
||||
#define FORCE_INLINE
|
||||
#define NO_INLINE
|
||||
#define DEPRECATED(msg)
|
||||
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define NOEXCEPT noexcept
|
||||
#else
|
||||
#define NOEXCEPT throw()
|
||||
#endif
|
||||
|
||||
#if defined(__has_attribute)
|
||||
#if __has_attribute(no_sanitize)
|
||||
#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
|
||||
#else
|
||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||
#endif
|
||||
#else
|
||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||
#endif
|
||||
@@ -1,18 +1,18 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline bool isdigit(char c) {
|
||||
return '0' <= c && c <= '9';
|
||||
}
|
||||
|
||||
inline bool issign(char c) {
|
||||
return '-' == c || c == '+';
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline bool isdigit(char c) {
|
||||
return '0' <= c && c <= '9';
|
||||
}
|
||||
|
||||
inline bool issign(char c) {
|
||||
return '-' == c || c == '+';
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,34 +1,34 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
class not_null {
|
||||
public:
|
||||
explicit not_null(T ptr) : _ptr(ptr) {
|
||||
ARDUINOJSON_ASSERT(ptr != NULL);
|
||||
}
|
||||
|
||||
T get() const {
|
||||
ARDUINOJSON_ASSERT(_ptr != NULL);
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
T _ptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
not_null<T> make_not_null(T ptr) {
|
||||
ARDUINOJSON_ASSERT(ptr != NULL);
|
||||
return not_null<T>(ptr);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
class not_null {
|
||||
public:
|
||||
explicit not_null(T ptr) : _ptr(ptr) {
|
||||
ARDUINOJSON_ASSERT(ptr != NULL);
|
||||
}
|
||||
|
||||
T get() const {
|
||||
ARDUINOJSON_ASSERT(_ptr != NULL);
|
||||
return _ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
T _ptr;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
not_null<T> make_not_null(T ptr) {
|
||||
ARDUINOJSON_ASSERT(ptr != NULL);
|
||||
return not_null<T>(ptr);
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,45 +1,45 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "type_traits.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4310)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Differs from standard because we can't use the symbols "min" and "max"
|
||||
template <typename T, typename Enable = void>
|
||||
struct numeric_limits;
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
|
||||
static T lowest() {
|
||||
return 0;
|
||||
}
|
||||
static T highest() {
|
||||
return T(-1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<
|
||||
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> {
|
||||
static T lowest() {
|
||||
return T(T(1) << (sizeof(T) * 8 - 1));
|
||||
}
|
||||
static T highest() {
|
||||
return T(~lowest());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "type_traits.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4310)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Differs from standard because we can't use the symbols "min" and "max"
|
||||
template <typename T, typename Enable = void>
|
||||
struct numeric_limits;
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
|
||||
static T lowest() {
|
||||
return 0;
|
||||
}
|
||||
static T highest() {
|
||||
return T(-1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<
|
||||
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> {
|
||||
static T lowest() {
|
||||
return T(T(1) << (sizeof(T) * 8 - 1));
|
||||
}
|
||||
static T highest() {
|
||||
return T(~lowest());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
@@ -1,27 +1,27 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Some libraries #define isnan() and isinf() so we need to check before
|
||||
// using this name
|
||||
|
||||
#ifndef isnan
|
||||
template <typename T>
|
||||
bool isnan(T x) {
|
||||
return x != x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef isinf
|
||||
template <typename T>
|
||||
bool isinf(T x) {
|
||||
return x != 0.0 && x * 2 == x;
|
||||
}
|
||||
#endif
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Some libraries #define isnan() and isinf() so we need to check before
|
||||
// using this name
|
||||
|
||||
#ifndef isnan
|
||||
template <typename T>
|
||||
bool isnan(T x) {
|
||||
return x != x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef isinf
|
||||
template <typename T>
|
||||
bool isinf(T x) {
|
||||
return x != 0.0 && x * 2 == x;
|
||||
}
|
||||
#endif
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,26 +1,26 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that returns the highest value
|
||||
template <size_t X, size_t Y, bool MaxIsX = (X > Y)>
|
||||
struct Max {};
|
||||
|
||||
template <size_t X, size_t Y>
|
||||
struct Max<X, Y, true> {
|
||||
static const size_t value = X;
|
||||
};
|
||||
|
||||
template <size_t X, size_t Y>
|
||||
struct Max<X, Y, false> {
|
||||
static const size_t value = Y;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that returns the highest value
|
||||
template <size_t X, size_t Y, bool MaxIsX = (X > Y)>
|
||||
struct Max {};
|
||||
|
||||
template <size_t X, size_t Y>
|
||||
struct Max<X, Y, true> {
|
||||
static const size_t value = X;
|
||||
};
|
||||
|
||||
template <size_t X, size_t Y>
|
||||
struct Max<X, Y, false> {
|
||||
static const size_t value = Y;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,78 +1,78 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
// Wraps a const char* so that the our functions are picked only if the
|
||||
// originals are missing
|
||||
struct pgm_p {
|
||||
pgm_p(const char* p) : address(p) {}
|
||||
const char* address;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifndef strlen_P
|
||||
inline size_t strlen_P(ARDUINOJSON_NAMESPACE::pgm_p s) {
|
||||
const char* p = s.address;
|
||||
ARDUINOJSON_ASSERT(p != NULL);
|
||||
while (pgm_read_byte(p)) p++;
|
||||
return size_t(p - s.address);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef strncmp_P
|
||||
inline int strncmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b, size_t n) {
|
||||
const char* s1 = a;
|
||||
const char* s2 = b.address;
|
||||
ARDUINOJSON_ASSERT(s1 != NULL);
|
||||
ARDUINOJSON_ASSERT(s2 != NULL);
|
||||
while (n-- > 0) {
|
||||
char c1 = *s1++;
|
||||
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
if (c1 == 0 /* and c2 as well */)
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef strcmp_P
|
||||
inline int strcmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b) {
|
||||
const char* s1 = a;
|
||||
const char* s2 = b.address;
|
||||
ARDUINOJSON_ASSERT(s1 != NULL);
|
||||
ARDUINOJSON_ASSERT(s2 != NULL);
|
||||
for (;;) {
|
||||
char c1 = *s1++;
|
||||
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
if (c1 == 0 /* and c2 as well */)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef memcpy_P
|
||||
inline void* memcpy_P(void* dst, ARDUINOJSON_NAMESPACE::pgm_p src, size_t n) {
|
||||
uint8_t* d = reinterpret_cast<uint8_t*>(dst);
|
||||
const char* s = src.address;
|
||||
ARDUINOJSON_ASSERT(d != NULL);
|
||||
ARDUINOJSON_ASSERT(s != NULL);
|
||||
while (n-- > 0) {
|
||||
*d++ = pgm_read_byte(s++);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
// Wraps a const char* so that the our functions are picked only if the
|
||||
// originals are missing
|
||||
struct pgm_p {
|
||||
pgm_p(const char* p) : address(p) {}
|
||||
const char* address;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifndef strlen_P
|
||||
inline size_t strlen_P(ARDUINOJSON_NAMESPACE::pgm_p s) {
|
||||
const char* p = s.address;
|
||||
ARDUINOJSON_ASSERT(p != NULL);
|
||||
while (pgm_read_byte(p)) p++;
|
||||
return size_t(p - s.address);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef strncmp_P
|
||||
inline int strncmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b, size_t n) {
|
||||
const char* s1 = a;
|
||||
const char* s2 = b.address;
|
||||
ARDUINOJSON_ASSERT(s1 != NULL);
|
||||
ARDUINOJSON_ASSERT(s2 != NULL);
|
||||
while (n-- > 0) {
|
||||
char c1 = *s1++;
|
||||
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
if (c1 == 0 /* and c2 as well */)
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef strcmp_P
|
||||
inline int strcmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b) {
|
||||
const char* s1 = a;
|
||||
const char* s2 = b.address;
|
||||
ARDUINOJSON_ASSERT(s1 != NULL);
|
||||
ARDUINOJSON_ASSERT(s2 != NULL);
|
||||
for (;;) {
|
||||
char c1 = *s1++;
|
||||
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
||||
if (c1 < c2)
|
||||
return -1;
|
||||
if (c1 > c2)
|
||||
return 1;
|
||||
if (c1 == 0 /* and c2 as well */)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef memcpy_P
|
||||
inline void* memcpy_P(void* dst, ARDUINOJSON_NAMESPACE::pgm_p src, size_t n) {
|
||||
uint8_t* d = reinterpret_cast<uint8_t*>(dst);
|
||||
const char* s = src.address;
|
||||
ARDUINOJSON_ASSERT(d != NULL);
|
||||
ARDUINOJSON_ASSERT(s != NULL);
|
||||
while (n-- > 0) {
|
||||
*d++ = pgm_read_byte(s++);
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
@@ -1,32 +1,32 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stdint.h> // int8_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline int safe_strcmp(const char* a, const char* b) {
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (!a)
|
||||
return -1;
|
||||
if (!b)
|
||||
return 1;
|
||||
return strcmp(a, b);
|
||||
}
|
||||
|
||||
inline int safe_strncmp(const char* a, const char* b, size_t n) {
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (!a)
|
||||
return -1;
|
||||
if (!b)
|
||||
return 1;
|
||||
return strncmp(a, b, n);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stdint.h> // int8_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline int safe_strcmp(const char* a, const char* b) {
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (!a)
|
||||
return -1;
|
||||
if (!b)
|
||||
return 1;
|
||||
return strcmp(a, b);
|
||||
}
|
||||
|
||||
inline int safe_strncmp(const char* a, const char* b, size_t n) {
|
||||
if (a == b)
|
||||
return 0;
|
||||
if (!a)
|
||||
return -1;
|
||||
if (!b)
|
||||
return 1;
|
||||
return strncmp(a, b, n);
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,23 +1,23 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "type_traits/conditional.hpp"
|
||||
#include "type_traits/enable_if.hpp"
|
||||
#include "type_traits/integral_constant.hpp"
|
||||
#include "type_traits/is_array.hpp"
|
||||
#include "type_traits/is_base_of.hpp"
|
||||
#include "type_traits/is_class.hpp"
|
||||
#include "type_traits/is_const.hpp"
|
||||
#include "type_traits/is_convertible.hpp"
|
||||
#include "type_traits/is_enum.hpp"
|
||||
#include "type_traits/is_floating_point.hpp"
|
||||
#include "type_traits/is_integral.hpp"
|
||||
#include "type_traits/is_same.hpp"
|
||||
#include "type_traits/is_signed.hpp"
|
||||
#include "type_traits/is_unsigned.hpp"
|
||||
#include "type_traits/make_unsigned.hpp"
|
||||
#include "type_traits/remove_const.hpp"
|
||||
#include "type_traits/remove_reference.hpp"
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "type_traits/conditional.hpp"
|
||||
#include "type_traits/enable_if.hpp"
|
||||
#include "type_traits/integral_constant.hpp"
|
||||
#include "type_traits/is_array.hpp"
|
||||
#include "type_traits/is_base_of.hpp"
|
||||
#include "type_traits/is_class.hpp"
|
||||
#include "type_traits/is_const.hpp"
|
||||
#include "type_traits/is_convertible.hpp"
|
||||
#include "type_traits/is_enum.hpp"
|
||||
#include "type_traits/is_floating_point.hpp"
|
||||
#include "type_traits/is_integral.hpp"
|
||||
#include "type_traits/is_same.hpp"
|
||||
#include "type_traits/is_signed.hpp"
|
||||
#include "type_traits/is_unsigned.hpp"
|
||||
#include "type_traits/make_unsigned.hpp"
|
||||
#include "type_traits/remove_const.hpp"
|
||||
#include "type_traits/remove_reference.hpp"
|
||||
@@ -1,20 +1,20 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <bool Condition, class TrueType, class FalseType>
|
||||
struct conditional {
|
||||
typedef TrueType type;
|
||||
};
|
||||
|
||||
template <class TrueType, class FalseType>
|
||||
struct conditional<false, TrueType, FalseType> {
|
||||
typedef FalseType type;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <bool Condition, class TrueType, class FalseType>
|
||||
struct conditional {
|
||||
typedef TrueType type;
|
||||
};
|
||||
|
||||
template <class TrueType, class FalseType>
|
||||
struct conditional<false, TrueType, FalseType> {
|
||||
typedef FalseType type;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,14 +1,14 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
T declval();
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
T declval();
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,19 +1,19 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that return the type T if Condition is true.
|
||||
template <bool Condition, typename T = void>
|
||||
struct enable_if {};
|
||||
|
||||
template <typename T>
|
||||
struct enable_if<true, T> {
|
||||
typedef T type;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that return the type T if Condition is true.
|
||||
template <bool Condition, typename T = void>
|
||||
struct enable_if {};
|
||||
|
||||
template <typename T>
|
||||
struct enable_if<true, T> {
|
||||
typedef T type;
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,19 +1,19 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T, T v>
|
||||
struct integral_constant {
|
||||
static const T value = v;
|
||||
};
|
||||
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T, T v>
|
||||
struct integral_constant {
|
||||
static const T value = v;
|
||||
};
|
||||
|
||||
typedef integral_constant<bool, true> true_type;
|
||||
typedef integral_constant<bool, false> false_type;
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,21 +1,21 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct is_array : false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_array<T[]> : true_type {};
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct is_array<T[N]> : true_type {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct is_array : false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_array<T[]> : true_type {};
|
||||
|
||||
template <typename T, size_t N>
|
||||
struct is_array<T[N]> : true_type {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,26 +1,26 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that returns true if Derived inherits from TBase is an
|
||||
// integral type.
|
||||
template <typename TBase, typename TDerived>
|
||||
class is_base_of {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
typedef char Yes[1];
|
||||
typedef char No[2];
|
||||
|
||||
static Yes &probe(const TBase *);
|
||||
static No &probe(...);
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes);
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ArduinoJson/Namespace.hpp>
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that returns true if Derived inherits from TBase is an
|
||||
// integral type.
|
||||
template <typename TBase, typename TDerived>
|
||||
class is_base_of {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
typedef char Yes[1];
|
||||
typedef char No[2];
|
||||
|
||||
static Yes &probe(const TBase *);
|
||||
static No &probe(...);
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes);
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,26 +1,26 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "declval.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct is_class {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
typedef char Yes[1];
|
||||
typedef char No[2];
|
||||
|
||||
template <typename U>
|
||||
static Yes &probe(void (U::*)(void));
|
||||
template <typename>
|
||||
static No &probe(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(probe<T>(0)) == sizeof(Yes);
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "declval.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct is_class {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
typedef char Yes[1];
|
||||
typedef char No[2];
|
||||
|
||||
template <typename U>
|
||||
static Yes &probe(void (U::*)(void));
|
||||
template <typename>
|
||||
static No &probe(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(probe<T>(0)) == sizeof(Yes);
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,17 +1,17 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "integral_constant.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that return the type T without the const modifier
|
||||
template <typename T>
|
||||
struct is_const : false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_const<const T> : true_type {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "integral_constant.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// A meta-function that return the type T without the const modifier
|
||||
template <typename T>
|
||||
struct is_const : false_type {};
|
||||
|
||||
template <typename T>
|
||||
struct is_const<const T> : true_type {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,34 +1,43 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "declval.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
// conversion from 'T' to 'To', possible loss of data
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename From, typename To>
|
||||
struct is_convertible {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
typedef char Yes[1];
|
||||
typedef char No[2];
|
||||
|
||||
static Yes &probe(To);
|
||||
static No &probe(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(probe(declval<From>())) == sizeof(Yes);
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "declval.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
// conversion from 'T' to 'To', possible loss of data
|
||||
#pragma warning(disable : 4244)
|
||||
#endif
|
||||
|
||||
#ifdef __ICCARM__
|
||||
// Suppress IAR Compiler Warning[Pa093]: implicit conversion from floating point to integer
|
||||
#pragma diag_suppress=Pa093
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename From, typename To>
|
||||
struct is_convertible {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
typedef char Yes[1];
|
||||
typedef char No[2];
|
||||
|
||||
static Yes &probe(To);
|
||||
static No &probe(...);
|
||||
|
||||
public:
|
||||
static const bool value = sizeof(probe(declval<From>())) == sizeof(Yes);
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#ifdef __ICCARM__
|
||||
#pragma diag_default=Pa093
|
||||
#endif
|
||||
@@ -1,23 +1,22 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "is_class.hpp"
|
||||
#include "is_convertible.hpp"
|
||||
#include "is_floating_point.hpp"
|
||||
#include "is_integral.hpp"
|
||||
#include "is_same.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct is_enum {
|
||||
static const bool value = is_convertible<T, int>::value &&
|
||||
!is_class<T>::value && !is_integral<T>::value &&
|
||||
!is_floating_point<T>::value &&
|
||||
!is_same<T, bool>::value;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "is_class.hpp"
|
||||
#include "is_convertible.hpp"
|
||||
#include "is_floating_point.hpp"
|
||||
#include "is_integral.hpp"
|
||||
#include "is_same.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
struct is_enum {
|
||||
static const bool value = is_convertible<T, int>::value &&
|
||||
!is_class<T>::value && !is_integral<T>::value &&
|
||||
!is_floating_point<T>::value;
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
@@ -1,19 +1,19 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "integral_constant.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename>
|
||||
struct is_floating_point : false_type {};
|
||||
|
||||
template <>
|
||||
struct is_floating_point<float> : true_type {};
|
||||
|
||||
template <>
|
||||
struct is_floating_point<double> : true_type {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2020
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "integral_constant.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename>
|
||||
struct is_floating_point : false_type {};
|
||||
|
||||
template <>
|
||||
struct is_floating_point<float> : true_type {};
|
||||
|
||||
template <>
|
||||
struct is_floating_point<double> : true_type {};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user