mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-06 07:49:52 +03:00
upgrade arduinojson to 6.17.0
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include "src/ArduinoJson.h"
|
#include "src/ArduinoJson.h"
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
ArduinoJson: change log
|
ArduinoJson: change log
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
v6.17.0 (2020-10-19)
|
||||||
|
-------
|
||||||
|
|
||||||
|
* Added a build failure when nullptr is defined as a macro (issue #1355)
|
||||||
|
* Added `JsonDocument::overflowed()` which tells if the memory pool was too small (issue #1358)
|
||||||
|
* Added `DeserializationError::EmptyInput` which tells if the input was empty
|
||||||
|
* Added `DeserializationError::f_str()` which returns a `const __FlashStringHelper*` (issue #846)
|
||||||
|
* Added `operator|(JsonVariantConst, JsonVariantConst)`
|
||||||
|
* Added filtering for MessagePack (issue #1298, PR #1394 by Luca Passarella)
|
||||||
|
* Moved float convertion tables to PROGMEM
|
||||||
|
* Fixed `JsonVariant::set((char*)0)` which returned false instead of true (issue #1368)
|
||||||
|
* Fixed error `No such file or directory #include <WString.h>` (issue #1381)
|
||||||
|
|
||||||
v6.16.1 (2020-08-04)
|
v6.16.1 (2020-08-04)
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@@ -12,6 +25,7 @@ v6.16.0 (2020-08-01)
|
|||||||
* Added comparisons (`>`, `>=`, `==`, `!=`, `<`, and `<=`) between `JsonVariant`s
|
* Added comparisons (`>`, `>=`, `==`, `!=`, `<`, and `<=`) between `JsonVariant`s
|
||||||
* Added string deduplication (issue #1303)
|
* Added string deduplication (issue #1303)
|
||||||
* Added `JsonString::operator!=`
|
* Added `JsonString::operator!=`
|
||||||
|
* Added wildcard key (`*`) for filters (issue #1309)
|
||||||
* Set `ARDUINOJSON_DECODE_UNICODE` to `1` by default
|
* Set `ARDUINOJSON_DECODE_UNICODE` to `1` by default
|
||||||
* Fixed `copyArray()` not working with `String`, `ElementProxy`, and `MemberProxy`
|
* Fixed `copyArray()` not working with `String`, `ElementProxy`, and `MemberProxy`
|
||||||
* Fixed error `getOrAddElement is not a member of ElementProxy` (issue #1311)
|
* Fixed error `getOrAddElement is not a member of ElementProxy` (issue #1311)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
[](https://www.ardu-badge.com/ArduinoJson/6.16.1)
|
[](https://www.ardu-badge.com/ArduinoJson/6.17.0)
|
||||||
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||||
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:arduinojson)
|
||||||
|
|||||||
27
lib/ArduinoJson/SUPPORT.md
Normal file
27
lib/ArduinoJson/SUPPORT.md
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# ArduinoJson Support
|
||||||
|
|
||||||
|
First off, thank you very much for using ArduinoJson.
|
||||||
|
|
||||||
|
We'll be very happy to help you, but first please read the following.
|
||||||
|
|
||||||
|
## Before asking for help
|
||||||
|
|
||||||
|
1. Read the [FAQ](https://arduinojson.org/faq/?utm_source=github&utm_medium=support)
|
||||||
|
2. Search in the [API Reference](https://arduinojson.org/api/?utm_source=github&utm_medium=support)
|
||||||
|
|
||||||
|
If you did not find the answer, please create a [new issue on GitHub](https://github.com/bblanchon/ArduinoJson/issues/new).
|
||||||
|
|
||||||
|
It is OK to add a comment to a currently opened issue, but please avoid adding comments to a closed issue.
|
||||||
|
|
||||||
|
## Before hitting the Submit button
|
||||||
|
|
||||||
|
Please provide all the relevant information:
|
||||||
|
|
||||||
|
* Good title
|
||||||
|
* Short description of the problem
|
||||||
|
* Target platform
|
||||||
|
* Compiler model and version
|
||||||
|
* [MVCE](https://stackoverflow.com/help/mcve)
|
||||||
|
* Compiler output
|
||||||
|
|
||||||
|
Good questions get fast answers!
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
// 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 ❤❤❤❤❤
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
// 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,77 +0,0 @@
|
|||||||
// 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 ❤❤❤❤❤
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
// 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,80 +0,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 ❤❤❤❤❤
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
// 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 ❤❤❤❤❤
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
// 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,75 +0,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
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
// 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 ❤❤❤❤❤
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
// 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 +0,0 @@
|
|||||||
# 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 +0,0 @@
|
|||||||
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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "ArduinoJson.hpp"
|
#include "ArduinoJson.hpp"
|
||||||
|
|
||||||
using namespace ArduinoJson;
|
using namespace ArduinoJson;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp
|
#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "ArduinoJson/Configuration.hpp"
|
#include "ArduinoJson/Configuration.hpp"
|
||||||
|
|
||||||
#if !ARDUINOJSON_DEBUG
|
#if !ARDUINOJSON_DEBUG
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
#pragma clang system_header
|
#pragma clang system_header
|
||||||
#elif defined __GNUC__
|
#elif defined __GNUC__
|
||||||
#pragma GCC system_header
|
#pragma GCC system_header
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "ArduinoJson/Array/ArrayRef.hpp"
|
#include "ArduinoJson/Array/ArrayRef.hpp"
|
||||||
#include "ArduinoJson/Object/ObjectRef.hpp"
|
#include "ArduinoJson/Object/ObjectRef.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantRef.hpp"
|
#include "ArduinoJson/Variant/VariantRef.hpp"
|
||||||
|
|
||||||
#include "ArduinoJson/Document/DynamicJsonDocument.hpp"
|
#include "ArduinoJson/Document/DynamicJsonDocument.hpp"
|
||||||
#include "ArduinoJson/Document/StaticJsonDocument.hpp"
|
#include "ArduinoJson/Document/StaticJsonDocument.hpp"
|
||||||
|
|
||||||
#include "ArduinoJson/Array/ArrayImpl.hpp"
|
#include "ArduinoJson/Array/ArrayImpl.hpp"
|
||||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||||
#include "ArduinoJson/Array/Utilities.hpp"
|
#include "ArduinoJson/Array/Utilities.hpp"
|
||||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantAsImpl.hpp"
|
#include "ArduinoJson/Variant/VariantAsImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
||||||
|
|
||||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||||
#include "ArduinoJson/Json/JsonSerializer.hpp"
|
#include "ArduinoJson/Json/JsonSerializer.hpp"
|
||||||
#include "ArduinoJson/Json/PrettyJsonSerializer.hpp"
|
#include "ArduinoJson/Json/PrettyJsonSerializer.hpp"
|
||||||
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
||||||
#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp"
|
#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp"
|
||||||
|
|
||||||
#include "ArduinoJson/compatibility.hpp"
|
#include "ArduinoJson/compatibility.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst;
|
typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst;
|
||||||
typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray;
|
typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray;
|
||||||
typedef ARDUINOJSON_NAMESPACE::Float JsonFloat;
|
typedef ARDUINOJSON_NAMESPACE::Float JsonFloat;
|
||||||
typedef ARDUINOJSON_NAMESPACE::Integer JsonInteger;
|
typedef ARDUINOJSON_NAMESPACE::Integer JsonInteger;
|
||||||
typedef ARDUINOJSON_NAMESPACE::ObjectConstRef JsonObjectConst;
|
typedef ARDUINOJSON_NAMESPACE::ObjectConstRef JsonObjectConst;
|
||||||
typedef ARDUINOJSON_NAMESPACE::ObjectRef JsonObject;
|
typedef ARDUINOJSON_NAMESPACE::ObjectRef JsonObject;
|
||||||
typedef ARDUINOJSON_NAMESPACE::Pair JsonPair;
|
typedef ARDUINOJSON_NAMESPACE::Pair JsonPair;
|
||||||
typedef ARDUINOJSON_NAMESPACE::PairConst JsonPairConst;
|
typedef ARDUINOJSON_NAMESPACE::PairConst JsonPairConst;
|
||||||
typedef ARDUINOJSON_NAMESPACE::String JsonString;
|
typedef ARDUINOJSON_NAMESPACE::String JsonString;
|
||||||
typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt;
|
typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt;
|
||||||
typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst;
|
typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst;
|
||||||
typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant;
|
typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant;
|
||||||
using ARDUINOJSON_NAMESPACE::BasicJsonDocument;
|
using ARDUINOJSON_NAMESPACE::BasicJsonDocument;
|
||||||
using ARDUINOJSON_NAMESPACE::copyArray;
|
using ARDUINOJSON_NAMESPACE::copyArray;
|
||||||
using ARDUINOJSON_NAMESPACE::DeserializationError;
|
using ARDUINOJSON_NAMESPACE::DeserializationError;
|
||||||
using ARDUINOJSON_NAMESPACE::deserializeJson;
|
using ARDUINOJSON_NAMESPACE::deserializeJson;
|
||||||
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;
|
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;
|
||||||
using ARDUINOJSON_NAMESPACE::DynamicJsonDocument;
|
using ARDUINOJSON_NAMESPACE::DynamicJsonDocument;
|
||||||
using ARDUINOJSON_NAMESPACE::JsonDocument;
|
using ARDUINOJSON_NAMESPACE::JsonDocument;
|
||||||
using ARDUINOJSON_NAMESPACE::measureJson;
|
using ARDUINOJSON_NAMESPACE::measureJson;
|
||||||
using ARDUINOJSON_NAMESPACE::serialized;
|
using ARDUINOJSON_NAMESPACE::serialized;
|
||||||
using ARDUINOJSON_NAMESPACE::serializeJson;
|
using ARDUINOJSON_NAMESPACE::serializeJson;
|
||||||
using ARDUINOJSON_NAMESPACE::serializeJsonPretty;
|
using ARDUINOJSON_NAMESPACE::serializeJsonPretty;
|
||||||
using ARDUINOJSON_NAMESPACE::serializeMsgPack;
|
using ARDUINOJSON_NAMESPACE::serializeMsgPack;
|
||||||
using ARDUINOJSON_NAMESPACE::StaticJsonDocument;
|
using ARDUINOJSON_NAMESPACE::StaticJsonDocument;
|
||||||
|
|
||||||
namespace DeserializationOption {
|
namespace DeserializationOption {
|
||||||
using ARDUINOJSON_NAMESPACE::Filter;
|
using ARDUINOJSON_NAMESPACE::Filter;
|
||||||
using ARDUINOJSON_NAMESPACE::NestingLimit;
|
using ARDUINOJSON_NAMESPACE::NestingLimit;
|
||||||
} // namespace DeserializationOption
|
} // namespace DeserializationOption
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
|||||||
@@ -1,30 +1,31 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
|
inline VariantData *arrayAdd(CollectionData *arr, MemoryPool *pool) {
|
||||||
return arr ? arr->addElement(pool) : 0;
|
return arr ? arr->addElement(pool) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
inline void arrayAccept(const CollectionData *arr, Visitor &visitor) {
|
inline typename TVisitor::result_type arrayAccept(const CollectionData *arr,
|
||||||
if (arr)
|
TVisitor &visitor) {
|
||||||
visitor.visitArray(*arr);
|
if (arr)
|
||||||
else
|
return visitor.visitArray(*arr);
|
||||||
visitor.visitNull();
|
else
|
||||||
}
|
return visitor.visitNull();
|
||||||
|
}
|
||||||
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
|
||||||
if (lhs == rhs)
|
inline bool arrayEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||||
return true;
|
if (lhs == rhs)
|
||||||
if (!lhs || !rhs)
|
return true;
|
||||||
return false;
|
if (!lhs || !rhs)
|
||||||
return lhs->equalsArray(*rhs);
|
return false;
|
||||||
}
|
return lhs->equalsArray(*rhs);
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
}
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,28 +1,28 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TArray>
|
template <typename TArray>
|
||||||
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
|
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
|
||||||
return impl()->addElement().template to<ArrayRef>();
|
return impl()->addElement().template to<ArrayRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TArray>
|
template <typename TArray>
|
||||||
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
|
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
|
||||||
return impl()->addElement().template to<ObjectRef>();
|
return impl()->addElement().template to<ObjectRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TArray>
|
template <typename TArray>
|
||||||
inline ElementProxy<TArray> ArrayShortcuts<TArray>::operator[](
|
inline ElementProxy<TArray> ArrayShortcuts<TArray>::operator[](
|
||||||
size_t index) const {
|
size_t index) const {
|
||||||
return ElementProxy<TArray>(*impl(), index);
|
return ElementProxy<TArray>(*impl(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,121 +1,121 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class VariantPtr {
|
class VariantPtr {
|
||||||
public:
|
public:
|
||||||
VariantPtr(MemoryPool *pool, VariantData *data) : _variant(pool, data) {}
|
VariantPtr(MemoryPool *pool, VariantData *data) : _variant(pool, data) {}
|
||||||
|
|
||||||
VariantRef *operator->() {
|
VariantRef *operator->() {
|
||||||
return &_variant;
|
return &_variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantRef &operator*() {
|
VariantRef &operator*() {
|
||||||
return _variant;
|
return _variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VariantRef _variant;
|
VariantRef _variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayIterator {
|
class ArrayIterator {
|
||||||
public:
|
public:
|
||||||
ArrayIterator() : _slot(0) {}
|
ArrayIterator() : _slot(0) {}
|
||||||
explicit ArrayIterator(MemoryPool *pool, VariantSlot *slot)
|
explicit ArrayIterator(MemoryPool *pool, VariantSlot *slot)
|
||||||
: _pool(pool), _slot(slot) {}
|
: _pool(pool), _slot(slot) {}
|
||||||
|
|
||||||
VariantRef operator*() const {
|
VariantRef operator*() const {
|
||||||
return VariantRef(_pool, _slot->data());
|
return VariantRef(_pool, _slot->data());
|
||||||
}
|
}
|
||||||
VariantPtr operator->() {
|
VariantPtr operator->() {
|
||||||
return VariantPtr(_pool, _slot->data());
|
return VariantPtr(_pool, _slot->data());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ArrayIterator &other) const {
|
bool operator==(const ArrayIterator &other) const {
|
||||||
return _slot == other._slot;
|
return _slot == other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ArrayIterator &other) const {
|
bool operator!=(const ArrayIterator &other) const {
|
||||||
return _slot != other._slot;
|
return _slot != other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayIterator &operator++() {
|
ArrayIterator &operator++() {
|
||||||
_slot = _slot->next();
|
_slot = _slot->next();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayIterator &operator+=(size_t distance) {
|
ArrayIterator &operator+=(size_t distance) {
|
||||||
_slot = _slot->next(distance);
|
_slot = _slot->next(distance);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantSlot *internal() {
|
VariantSlot *internal() {
|
||||||
return _slot;
|
return _slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool *_pool;
|
MemoryPool *_pool;
|
||||||
VariantSlot *_slot;
|
VariantSlot *_slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VariantConstPtr {
|
class VariantConstPtr {
|
||||||
public:
|
public:
|
||||||
VariantConstPtr(const VariantData *data) : _variant(data) {}
|
VariantConstPtr(const VariantData *data) : _variant(data) {}
|
||||||
|
|
||||||
VariantConstRef *operator->() {
|
VariantConstRef *operator->() {
|
||||||
return &_variant;
|
return &_variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantConstRef &operator*() {
|
VariantConstRef &operator*() {
|
||||||
return _variant;
|
return _variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VariantConstRef _variant;
|
VariantConstRef _variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayConstRefIterator {
|
class ArrayConstRefIterator {
|
||||||
public:
|
public:
|
||||||
ArrayConstRefIterator() : _slot(0) {}
|
ArrayConstRefIterator() : _slot(0) {}
|
||||||
explicit ArrayConstRefIterator(const VariantSlot *slot) : _slot(slot) {}
|
explicit ArrayConstRefIterator(const VariantSlot *slot) : _slot(slot) {}
|
||||||
|
|
||||||
VariantConstRef operator*() const {
|
VariantConstRef operator*() const {
|
||||||
return VariantConstRef(_slot->data());
|
return VariantConstRef(_slot->data());
|
||||||
}
|
}
|
||||||
VariantConstPtr operator->() {
|
VariantConstPtr operator->() {
|
||||||
return VariantConstPtr(_slot->data());
|
return VariantConstPtr(_slot->data());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ArrayConstRefIterator &other) const {
|
bool operator==(const ArrayConstRefIterator &other) const {
|
||||||
return _slot == other._slot;
|
return _slot == other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ArrayConstRefIterator &other) const {
|
bool operator!=(const ArrayConstRefIterator &other) const {
|
||||||
return _slot != other._slot;
|
return _slot != other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayConstRefIterator &operator++() {
|
ArrayConstRefIterator &operator++() {
|
||||||
_slot = _slot->next();
|
_slot = _slot->next();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayConstRefIterator &operator+=(size_t distance) {
|
ArrayConstRefIterator &operator+=(size_t distance) {
|
||||||
_slot = _slot->next(distance);
|
_slot = _slot->next(distance);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VariantSlot *internal() {
|
const VariantSlot *internal() {
|
||||||
return _slot;
|
return _slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const VariantSlot *_slot;
|
const VariantSlot *_slot;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,167 +1,167 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Array/ArrayFunctions.hpp>
|
#include <ArduinoJson/Array/ArrayFunctions.hpp>
|
||||||
#include <ArduinoJson/Array/ArrayIterator.hpp>
|
#include <ArduinoJson/Array/ArrayIterator.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
|
|
||||||
// Returns the size (in bytes) of an array with n elements.
|
// Returns the size (in bytes) of an array with n elements.
|
||||||
// Can be very handy to determine the size of a StaticMemoryPool.
|
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||||
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
||||||
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class ObjectRef;
|
class ObjectRef;
|
||||||
template <typename>
|
template <typename>
|
||||||
class ElementProxy;
|
class ElementProxy;
|
||||||
|
|
||||||
template <typename TData>
|
template <typename TData>
|
||||||
class ArrayRefBase {
|
class ArrayRefBase {
|
||||||
public:
|
public:
|
||||||
operator VariantConstRef() const {
|
operator VariantConstRef() const {
|
||||||
const void* data = _data; // prevent warning cast-align
|
const void* data = _data; // prevent warning cast-align
|
||||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
FORCE_INLINE typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
arrayAccept(_data, visitor);
|
return arrayAccept(_data, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
return _data == 0;
|
return _data == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE operator bool() const {
|
FORCE_INLINE operator bool() const {
|
||||||
return _data != 0;
|
return _data != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t memoryUsage() const {
|
FORCE_INLINE size_t memoryUsage() const {
|
||||||
return _data ? _data->memoryUsage() : 0;
|
return _data ? _data->memoryUsage() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t nesting() const {
|
FORCE_INLINE size_t nesting() const {
|
||||||
return _data ? _data->nesting() : 0;
|
return _data ? _data->nesting() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t size() const {
|
FORCE_INLINE size_t size() const {
|
||||||
return _data ? _data->size() : 0;
|
return _data ? _data->size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ArrayRefBase(TData* data) : _data(data) {}
|
ArrayRefBase(TData* data) : _data(data) {}
|
||||||
TData* _data;
|
TData* _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayConstRef : public ArrayRefBase<const CollectionData>,
|
class ArrayConstRef : public ArrayRefBase<const CollectionData>,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
friend class ArrayRef;
|
friend class ArrayRef;
|
||||||
typedef ArrayRefBase<const CollectionData> base_type;
|
typedef ArrayRefBase<const CollectionData> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef ArrayConstRefIterator iterator;
|
typedef ArrayConstRefIterator iterator;
|
||||||
|
|
||||||
FORCE_INLINE iterator begin() const {
|
FORCE_INLINE iterator begin() const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return iterator();
|
return iterator();
|
||||||
return iterator(_data->head());
|
return iterator(_data->head());
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE iterator end() const {
|
FORCE_INLINE iterator end() const {
|
||||||
return iterator();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE ArrayConstRef() : base_type(0) {}
|
FORCE_INLINE ArrayConstRef() : base_type(0) {}
|
||||||
FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {}
|
FORCE_INLINE ArrayConstRef(const CollectionData* data) : base_type(data) {}
|
||||||
|
|
||||||
FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
|
FORCE_INLINE bool operator==(ArrayConstRef rhs) const {
|
||||||
return arrayEquals(_data, rhs._data);
|
return arrayEquals(_data, rhs._data);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||||
return getElement(index);
|
return getElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||||
return VariantConstRef(_data ? _data->getElement(index) : 0);
|
return VariantConstRef(_data ? _data->getElement(index) : 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ArrayRef : public ArrayRefBase<CollectionData>,
|
class ArrayRef : public ArrayRefBase<CollectionData>,
|
||||||
public ArrayShortcuts<ArrayRef>,
|
public ArrayShortcuts<ArrayRef>,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef ArrayRefBase<CollectionData> base_type;
|
typedef ArrayRefBase<CollectionData> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef ArrayIterator iterator;
|
typedef ArrayIterator iterator;
|
||||||
|
|
||||||
FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {}
|
FORCE_INLINE ArrayRef() : base_type(0), _pool(0) {}
|
||||||
FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data)
|
FORCE_INLINE ArrayRef(MemoryPool* pool, CollectionData* data)
|
||||||
: base_type(data), _pool(pool) {}
|
: base_type(data), _pool(pool) {}
|
||||||
|
|
||||||
operator VariantRef() {
|
operator VariantRef() {
|
||||||
void* data = _data; // prevent warning cast-align
|
void* data = _data; // prevent warning cast-align
|
||||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator ArrayConstRef() const {
|
operator ArrayConstRef() const {
|
||||||
return ArrayConstRef(_data);
|
return ArrayConstRef(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantRef addElement() const {
|
VariantRef addElement() const {
|
||||||
return VariantRef(_pool, arrayAdd(_data, _pool));
|
return VariantRef(_pool, arrayAdd(_data, _pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE iterator begin() const {
|
FORCE_INLINE iterator begin() const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return iterator();
|
return iterator();
|
||||||
return iterator(_pool, _data->head());
|
return iterator(_pool, _data->head());
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE iterator end() const {
|
FORCE_INLINE iterator end() const {
|
||||||
return iterator();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a ArrayRef
|
// Copy a ArrayRef
|
||||||
FORCE_INLINE bool set(ArrayConstRef src) const {
|
FORCE_INLINE bool set(ArrayConstRef src) const {
|
||||||
if (!_data || !src._data)
|
if (!_data || !src._data)
|
||||||
return false;
|
return false;
|
||||||
return _data->copyFrom(*src._data, _pool);
|
return _data->copyFrom(*src._data, _pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool operator==(ArrayRef rhs) const {
|
FORCE_INLINE bool operator==(ArrayRef rhs) const {
|
||||||
return arrayEquals(_data, rhs._data);
|
return arrayEquals(_data, rhs._data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal use
|
// Internal use
|
||||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||||
return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
|
return VariantRef(_pool, _data ? _data->getOrAddElement(index, _pool) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the value at the specified index.
|
// Gets the value at the specified index.
|
||||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||||
return VariantRef(_pool, _data ? _data->getElement(index) : 0);
|
return VariantRef(_pool, _data ? _data->getElement(index) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes element at specified position.
|
// Removes element at specified position.
|
||||||
FORCE_INLINE void remove(iterator it) const {
|
FORCE_INLINE void remove(iterator it) const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return;
|
return;
|
||||||
_data->removeSlot(it.internal());
|
_data->removeSlot(it.internal());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes element at specified index.
|
// Removes element at specified index.
|
||||||
FORCE_INLINE void remove(size_t index) const {
|
FORCE_INLINE void remove(size_t index) const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return;
|
return;
|
||||||
_data->removeElement(index);
|
_data->removeElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool* _pool;
|
MemoryPool* _pool;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,47 +1,47 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
template <typename>
|
template <typename>
|
||||||
class ElementProxy;
|
class ElementProxy;
|
||||||
|
|
||||||
template <typename TArray>
|
template <typename TArray>
|
||||||
class ArrayShortcuts {
|
class ArrayShortcuts {
|
||||||
public:
|
public:
|
||||||
// Returns the element at specified index if the variant is an array.
|
// Returns the element at specified index if the variant is an array.
|
||||||
FORCE_INLINE ElementProxy<TArray> operator[](size_t index) const;
|
FORCE_INLINE ElementProxy<TArray> operator[](size_t index) const;
|
||||||
|
|
||||||
FORCE_INLINE ObjectRef createNestedObject() const;
|
FORCE_INLINE ObjectRef createNestedObject() const;
|
||||||
|
|
||||||
FORCE_INLINE ArrayRef createNestedArray() const;
|
FORCE_INLINE ArrayRef createNestedArray() const;
|
||||||
|
|
||||||
// Adds the specified value at the end of the array.
|
// Adds the specified value at the end of the array.
|
||||||
//
|
//
|
||||||
// bool add(TValue);
|
// bool add(TValue);
|
||||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||||
// std::string, String, ObjectRef
|
// std::string, String, ObjectRef
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE bool add(const T &value) const {
|
FORCE_INLINE bool add(const T &value) const {
|
||||||
return impl()->addElement().set(value);
|
return impl()->addElement().set(value);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// bool add(TValue);
|
// bool add(TValue);
|
||||||
// TValue = char*, const char*, const __FlashStringHelper*
|
// TValue = char*, const char*, const __FlashStringHelper*
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE bool add(T *value) const {
|
FORCE_INLINE bool add(T *value) const {
|
||||||
return impl()->addElement().set(value);
|
return impl()->addElement().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TArray *impl() const {
|
const TArray *impl() const {
|
||||||
return static_cast<const TArray *>(this);
|
return static_cast<const TArray *>(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,178 +1,178 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4522)
|
#pragma warning(disable : 4522)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TArray>
|
template <typename TArray>
|
||||||
class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||||
public VariantShortcuts<ElementProxy<TArray> >,
|
public VariantShortcuts<ElementProxy<TArray> >,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef ElementProxy<TArray> this_type;
|
typedef ElementProxy<TArray> this_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FORCE_INLINE ElementProxy(TArray array, size_t index)
|
FORCE_INLINE ElementProxy(TArray array, size_t index)
|
||||||
: _array(array), _index(index) {}
|
: _array(array), _index(index) {}
|
||||||
|
|
||||||
FORCE_INLINE ElementProxy(const ElementProxy& src)
|
FORCE_INLINE ElementProxy(const ElementProxy& src)
|
||||||
: _array(src._array), _index(src._index) {}
|
: _array(src._array), _index(src._index) {}
|
||||||
|
|
||||||
FORCE_INLINE this_type& operator=(const this_type& src) {
|
FORCE_INLINE this_type& operator=(const this_type& src) {
|
||||||
getOrAddUpstreamElement().set(src.as<VariantConstRef>());
|
getOrAddUpstreamElement().set(src.as<VariantConstRef>());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replaces the value
|
// Replaces the value
|
||||||
//
|
//
|
||||||
// operator=(const TValue&)
|
// operator=(const TValue&)
|
||||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||||
// std::string, String, ArrayRef, ObjectRef
|
// std::string, String, ArrayRef, ObjectRef
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE this_type& operator=(const T& src) {
|
FORCE_INLINE this_type& operator=(const T& src) {
|
||||||
getOrAddUpstreamElement().set(src);
|
getOrAddUpstreamElement().set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// operator=(TValue)
|
// operator=(TValue)
|
||||||
// TValue = char*, const char*, const __FlashStringHelper*
|
// TValue = char*, const char*, const __FlashStringHelper*
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE this_type& operator=(T* src) {
|
FORCE_INLINE this_type& operator=(T* src) {
|
||||||
getOrAddUpstreamElement().set(src);
|
getOrAddUpstreamElement().set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void clear() const {
|
FORCE_INLINE void clear() const {
|
||||||
getUpstreamElement().clear();
|
getUpstreamElement().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
return getUpstreamElement().isNull();
|
return getUpstreamElement().isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE typename VariantAs<T>::type as() const {
|
FORCE_INLINE typename VariantAs<T>::type as() const {
|
||||||
return getUpstreamElement().template as<T>();
|
return getUpstreamElement().template as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE operator T() const {
|
FORCE_INLINE operator T() const {
|
||||||
return getUpstreamElement();
|
return getUpstreamElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE bool is() const {
|
FORCE_INLINE bool is() const {
|
||||||
return getUpstreamElement().template is<T>();
|
return getUpstreamElement().template is<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE typename VariantTo<T>::type to() const {
|
FORCE_INLINE typename VariantTo<T>::type to() const {
|
||||||
return getOrAddUpstreamElement().template to<T>();
|
return getOrAddUpstreamElement().template to<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Replaces the value
|
// Replaces the value
|
||||||
//
|
//
|
||||||
// bool set(const TValue&)
|
// bool set(const TValue&)
|
||||||
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
// TValue = bool, long, int, short, float, double, serialized, VariantRef,
|
||||||
// std::string, String, ArrayRef, ObjectRef
|
// std::string, String, ArrayRef, ObjectRef
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE bool set(const TValue& value) const {
|
FORCE_INLINE bool set(const TValue& value) const {
|
||||||
return getOrAddUpstreamElement().set(value);
|
return getOrAddUpstreamElement().set(value);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// bool set(TValue)
|
// bool set(TValue)
|
||||||
// TValue = char*, const char*, const __FlashStringHelper*
|
// TValue = char*, const char*, const __FlashStringHelper*
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE bool set(TValue* value) const {
|
FORCE_INLINE bool set(TValue* value) const {
|
||||||
return getOrAddUpstreamElement().set(value);
|
return getOrAddUpstreamElement().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor& visitor) const {
|
typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
return getUpstreamElement().accept(visitor);
|
return getUpstreamElement().accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t size() const {
|
FORCE_INLINE size_t size() const {
|
||||||
return getUpstreamElement().size();
|
return getUpstreamElement().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TNestedKey>
|
template <typename TNestedKey>
|
||||||
VariantRef getMember(TNestedKey* key) const {
|
VariantRef getMember(TNestedKey* key) const {
|
||||||
return getUpstreamElement().getMember(key);
|
return getUpstreamElement().getMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TNestedKey>
|
template <typename TNestedKey>
|
||||||
VariantRef getMember(const TNestedKey& key) const {
|
VariantRef getMember(const TNestedKey& key) const {
|
||||||
return getUpstreamElement().getMember(key);
|
return getUpstreamElement().getMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TNestedKey>
|
template <typename TNestedKey>
|
||||||
VariantRef getOrAddMember(TNestedKey* key) const {
|
VariantRef getOrAddMember(TNestedKey* key) const {
|
||||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TNestedKey>
|
template <typename TNestedKey>
|
||||||
VariantRef getOrAddMember(const TNestedKey& key) const {
|
VariantRef getOrAddMember(const TNestedKey& key) const {
|
||||||
return getOrAddUpstreamElement().getOrAddMember(key);
|
return getOrAddUpstreamElement().getOrAddMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantRef addElement() const {
|
VariantRef addElement() const {
|
||||||
return getOrAddUpstreamElement().addElement();
|
return getOrAddUpstreamElement().addElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantRef getElement(size_t index) const {
|
VariantRef getElement(size_t index) const {
|
||||||
return getOrAddUpstreamElement().getElement(index);
|
return getOrAddUpstreamElement().getElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantRef getOrAddElement(size_t index) const {
|
VariantRef getOrAddElement(size_t index) const {
|
||||||
return getOrAddUpstreamElement().getOrAddElement(index);
|
return getOrAddUpstreamElement().getOrAddElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void remove(size_t index) const {
|
FORCE_INLINE void remove(size_t index) const {
|
||||||
getUpstreamElement().remove(index);
|
getUpstreamElement().remove(index);
|
||||||
}
|
}
|
||||||
// remove(char*) const
|
// remove(char*) const
|
||||||
// remove(const char*) const
|
// remove(const char*) const
|
||||||
// remove(const __FlashStringHelper*) const
|
// remove(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||||
TChar* key) const {
|
TChar* key) const {
|
||||||
getUpstreamElement().remove(key);
|
getUpstreamElement().remove(key);
|
||||||
}
|
}
|
||||||
// remove(const std::string&) const
|
// remove(const std::string&) const
|
||||||
// remove(const String&) const
|
// remove(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||||
const TString& key) const {
|
const TString& key) const {
|
||||||
getUpstreamElement().remove(key);
|
getUpstreamElement().remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FORCE_INLINE VariantRef getUpstreamElement() const {
|
FORCE_INLINE VariantRef getUpstreamElement() const {
|
||||||
return _array.getElement(_index);
|
return _array.getElement(_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantRef getOrAddUpstreamElement() const {
|
FORCE_INLINE VariantRef getOrAddUpstreamElement() const {
|
||||||
return _array.getOrAddElement(_index);
|
return _array.getOrAddElement(_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
TArray _array;
|
TArray _array;
|
||||||
const size_t _index;
|
const size_t _index;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,150 +1,171 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// Copy a 1D array to a JsonArray
|
// Copy a 1D array to a JsonArray
|
||||||
template <typename T, size_t N, typename TDestination>
|
template <typename T, size_t N, typename TDestination>
|
||||||
inline typename enable_if<!is_array<T>::value &&
|
inline typename enable_if<!is_array<T>::value &&
|
||||||
!is_base_of<JsonDocument, TDestination>::value,
|
!is_base_of<JsonDocument, TDestination>::value,
|
||||||
bool>::type
|
bool>::type
|
||||||
copyArray(T (&src)[N], const TDestination& dst) {
|
copyArray(T (&src)[N], const TDestination& dst) {
|
||||||
return copyArray(src, N, dst);
|
return copyArray(src, N, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a 1D array to a JsonDocument
|
// Copy a 1D array to a JsonDocument
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
inline bool copyArray(T (&src)[N], JsonDocument& dst) {
|
inline bool copyArray(T (&src)[N], JsonDocument& dst) {
|
||||||
return copyArray(src, dst.to<ArrayRef>());
|
return copyArray(src, dst.to<ArrayRef>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a 1D array to a JsonArray
|
// Copy a 1D array to a JsonArray
|
||||||
template <typename T, typename TDestination>
|
template <typename T, typename TDestination>
|
||||||
inline typename enable_if<!is_array<T>::value &&
|
inline typename enable_if<!is_array<T>::value &&
|
||||||
!is_base_of<JsonDocument, TDestination>::value,
|
!is_base_of<JsonDocument, TDestination>::value,
|
||||||
bool>::type
|
bool>::type
|
||||||
copyArray(T* src, size_t len, const TDestination& dst) {
|
copyArray(T* src, size_t len, const TDestination& dst) {
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
for (size_t i = 0; i < len; i++) {
|
for (size_t i = 0; i < len; i++) {
|
||||||
ok &= dst.add(src[i]);
|
ok &= dst.add(src[i]);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a 1D array to a JsonDocument
|
// Copy a 1D array to a JsonDocument
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool copyArray(T* src, size_t len, JsonDocument& dst) {
|
inline bool copyArray(T* src, size_t len, JsonDocument& dst) {
|
||||||
return copyArray(src, len, dst.to<ArrayRef>());
|
return copyArray(src, len, dst.to<ArrayRef>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a 2D array to a JsonArray
|
// Copy a 2D array to a JsonArray
|
||||||
template <typename T, size_t N1, size_t N2, typename TDestination>
|
template <typename T, size_t N1, size_t N2, typename TDestination>
|
||||||
inline typename enable_if<!is_base_of<JsonDocument, TDestination>::value,
|
inline typename enable_if<!is_base_of<JsonDocument, TDestination>::value,
|
||||||
bool>::type
|
bool>::type
|
||||||
copyArray(T (&src)[N1][N2], const TDestination& dst) {
|
copyArray(T (&src)[N1][N2], const TDestination& dst) {
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
for (size_t i = 0; i < N1; i++) {
|
for (size_t i = 0; i < N1; i++) {
|
||||||
ArrayRef nestedArray = dst.createNestedArray();
|
ArrayRef nestedArray = dst.createNestedArray();
|
||||||
for (size_t j = 0; j < N2; j++) {
|
for (size_t j = 0; j < N2; j++) {
|
||||||
ok &= nestedArray.add(src[i][j]);
|
ok &= nestedArray.add(src[i][j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy a 2D array to a JsonDocument
|
// Copy a 2D array to a JsonDocument
|
||||||
template <typename T, size_t N1, size_t N2>
|
template <typename T, size_t N1, size_t N2>
|
||||||
inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) {
|
inline bool copyArray(T (&src)[N1][N2], JsonDocument& dst) {
|
||||||
return copyArray(src, dst.to<ArrayRef>());
|
return copyArray(src, dst.to<ArrayRef>());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ArrayCopier1D {
|
class ArrayCopier1D : public Visitor<size_t> {
|
||||||
public:
|
public:
|
||||||
ArrayCopier1D(T* destination, size_t capacity)
|
ArrayCopier1D(T* destination, size_t capacity)
|
||||||
: _destination(destination), _capacity(capacity), _size(0) {}
|
: _destination(destination), _capacity(capacity) {}
|
||||||
|
|
||||||
void visitArray(const CollectionData& array) {
|
size_t visitArray(const CollectionData& array) {
|
||||||
VariantSlot* slot = array.head();
|
size_t size = 0;
|
||||||
|
VariantSlot* slot = array.head();
|
||||||
while (slot != 0 && _size < _capacity) {
|
|
||||||
_destination[_size++] = variantAs<T>(slot->data());
|
while (slot != 0 && size < _capacity) {
|
||||||
slot = slot->next();
|
_destination[size++] = variantAs<T>(slot->data());
|
||||||
}
|
slot = slot->next();
|
||||||
}
|
}
|
||||||
void visitObject(const CollectionData&) {}
|
return size;
|
||||||
void visitFloat(Float) {}
|
}
|
||||||
void visitString(const char*) {}
|
|
||||||
void visitRawJson(const char*, size_t) {}
|
size_t visitObject(const CollectionData&) {
|
||||||
void visitNegativeInteger(UInt) {}
|
return 0;
|
||||||
void visitPositiveInteger(UInt) {}
|
}
|
||||||
void visitBoolean(bool) {}
|
|
||||||
void visitNull() {}
|
size_t visitFloat(Float) {
|
||||||
|
return 0;
|
||||||
size_t result() const {
|
}
|
||||||
return _size;
|
|
||||||
}
|
size_t visitString(const char*) {
|
||||||
|
return 0;
|
||||||
private:
|
}
|
||||||
T* _destination;
|
|
||||||
size_t _capacity;
|
size_t visitRawJson(const char*, size_t) {
|
||||||
size_t _size;
|
return 0;
|
||||||
};
|
}
|
||||||
|
|
||||||
template <typename T, size_t N1, size_t N2>
|
size_t visitNegativeInteger(UInt) {
|
||||||
class ArrayCopier2D {
|
return 0;
|
||||||
public:
|
}
|
||||||
ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {}
|
|
||||||
|
size_t visitPositiveInteger(UInt) {
|
||||||
void visitArray(const CollectionData& array) {
|
return 0;
|
||||||
VariantSlot* slot = array.head();
|
}
|
||||||
size_t n = 0;
|
|
||||||
while (slot != 0 && n < N1) {
|
size_t visitBoolean(bool) {
|
||||||
ArrayCopier1D<T> copier((*_destination)[n++], N2);
|
return 0;
|
||||||
variantAccept(slot->data(), copier);
|
}
|
||||||
slot = slot->next();
|
|
||||||
}
|
size_t visitNull() {
|
||||||
}
|
return 0;
|
||||||
void visitObject(const CollectionData&) {}
|
}
|
||||||
void visitFloat(Float) {}
|
|
||||||
void visitString(const char*) {}
|
private:
|
||||||
void visitRawJson(const char*, size_t) {}
|
T* _destination;
|
||||||
void visitNegativeInteger(UInt) {}
|
size_t _capacity;
|
||||||
void visitPositiveInteger(UInt) {}
|
};
|
||||||
void visitBoolean(bool) {}
|
|
||||||
void visitNull() {}
|
template <typename T, size_t N1, size_t N2>
|
||||||
|
class ArrayCopier2D : public Visitor<void> {
|
||||||
private:
|
public:
|
||||||
T (*_destination)[N1][N2];
|
ArrayCopier2D(T (*destination)[N1][N2]) : _destination(destination) {}
|
||||||
size_t _capacity1, _capacity2;
|
|
||||||
};
|
void visitArray(const CollectionData& array) {
|
||||||
|
VariantSlot* slot = array.head();
|
||||||
// Copy a JsonArray to a 1D array
|
size_t n = 0;
|
||||||
template <typename TSource, typename T, size_t N>
|
while (slot != 0 && n < N1) {
|
||||||
inline typename enable_if<!is_array<T>::value, size_t>::type copyArray(
|
ArrayCopier1D<T> copier((*_destination)[n++], N2);
|
||||||
const TSource& src, T (&dst)[N]) {
|
variantAccept(slot->data(), copier);
|
||||||
return copyArray(src, dst, N);
|
slot = slot->next();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Copy a JsonArray to a 1D array
|
void visitObject(const CollectionData&) {}
|
||||||
template <typename TSource, typename T>
|
void visitFloat(Float) {}
|
||||||
inline size_t copyArray(const TSource& src, T* dst, size_t len) {
|
void visitString(const char*) {}
|
||||||
ArrayCopier1D<T> copier(dst, len);
|
void visitRawJson(const char*, size_t) {}
|
||||||
src.accept(copier);
|
void visitNegativeInteger(UInt) {}
|
||||||
return copier.result();
|
void visitPositiveInteger(UInt) {}
|
||||||
}
|
void visitBoolean(bool) {}
|
||||||
|
void visitNull() {}
|
||||||
// Copy a JsonArray to a 2D array
|
|
||||||
template <typename TSource, typename T, size_t N1, size_t N2>
|
private:
|
||||||
inline void copyArray(const TSource& src, T (&dst)[N1][N2]) {
|
T (*_destination)[N1][N2];
|
||||||
ArrayCopier2D<T, N1, N2> copier(&dst);
|
size_t _capacity1, _capacity2;
|
||||||
src.accept(copier);
|
};
|
||||||
}
|
|
||||||
|
// Copy a JsonArray to a 1D array
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
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);
|
||||||
|
|
||||||
|
return src.accept(copier);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
|
|
||||||
#include <stddef.h> // size_t
|
#include <stddef.h> // size_t
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class MemoryPool;
|
class MemoryPool;
|
||||||
class VariantData;
|
class VariantData;
|
||||||
class VariantSlot;
|
class VariantSlot;
|
||||||
|
|
||||||
class CollectionData {
|
class CollectionData {
|
||||||
VariantSlot *_head;
|
VariantSlot *_head;
|
||||||
VariantSlot *_tail;
|
VariantSlot *_tail;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Must be a POD!
|
// Must be a POD!
|
||||||
// - no constructor
|
// - no constructor
|
||||||
// - no destructor
|
// - no destructor
|
||||||
// - no virtual
|
// - no virtual
|
||||||
// - no inheritance
|
// - no inheritance
|
||||||
|
|
||||||
// Array only
|
// Array only
|
||||||
|
|
||||||
VariantData *addElement(MemoryPool *pool);
|
VariantData *addElement(MemoryPool *pool);
|
||||||
|
|
||||||
VariantData *getElement(size_t index) const;
|
VariantData *getElement(size_t index) const;
|
||||||
|
|
||||||
VariantData *getOrAddElement(size_t index, MemoryPool *pool);
|
VariantData *getOrAddElement(size_t index, MemoryPool *pool);
|
||||||
|
|
||||||
void removeElement(size_t index);
|
void removeElement(size_t index);
|
||||||
|
|
||||||
bool equalsArray(const CollectionData &other) const;
|
bool equalsArray(const CollectionData &other) const;
|
||||||
|
|
||||||
// Object only
|
// Object only
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData *addMember(TAdaptedString key, MemoryPool *pool);
|
VariantData *addMember(TAdaptedString key, MemoryPool *pool);
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData *getMember(TAdaptedString key) const;
|
VariantData *getMember(TAdaptedString key) const;
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool);
|
VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool);
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
void removeMember(TAdaptedString key) {
|
void removeMember(TAdaptedString key) {
|
||||||
removeSlot(getSlot(key));
|
removeSlot(getSlot(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
bool containsKey(const TAdaptedString &key) const;
|
bool containsKey(const TAdaptedString &key) const;
|
||||||
|
|
||||||
bool equalsObject(const CollectionData &other) const;
|
bool equalsObject(const CollectionData &other) const;
|
||||||
|
|
||||||
// Generic
|
// Generic
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
size_t memoryUsage() const;
|
size_t memoryUsage() const;
|
||||||
size_t nesting() const;
|
size_t nesting() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
|
|
||||||
VariantSlot *addSlot(MemoryPool *);
|
VariantSlot *addSlot(MemoryPool *);
|
||||||
void removeSlot(VariantSlot *slot);
|
void removeSlot(VariantSlot *slot);
|
||||||
|
|
||||||
bool copyFrom(const CollectionData &src, MemoryPool *pool);
|
bool copyFrom(const CollectionData &src, MemoryPool *pool);
|
||||||
|
|
||||||
VariantSlot *head() const {
|
VariantSlot *head() const {
|
||||||
return _head;
|
return _head;
|
||||||
}
|
}
|
||||||
|
|
||||||
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance);
|
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VariantSlot *getSlot(size_t index) const;
|
VariantSlot *getSlot(size_t index) const;
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantSlot *getSlot(TAdaptedString key) const;
|
VariantSlot *getSlot(TAdaptedString key) const;
|
||||||
|
|
||||||
VariantSlot *getPreviousSlot(VariantSlot *) const;
|
VariantSlot *getPreviousSlot(VariantSlot *) const;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,232 +1,232 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
inline bool variantEquals(const VariantData* a, const VariantData* b) {
|
inline bool variantEquals(const VariantData* a, const VariantData* b) {
|
||||||
return variantCompare(a, b) == COMPARE_RESULT_EQUAL;
|
return variantCompare(a, b) == COMPARE_RESULT_EQUAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
|
inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
|
||||||
VariantSlot* slot = pool->allocVariant();
|
VariantSlot* slot = pool->allocVariant();
|
||||||
if (!slot)
|
if (!slot)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (_tail) {
|
if (_tail) {
|
||||||
_tail->setNextNotNull(slot);
|
_tail->setNextNotNull(slot);
|
||||||
_tail = slot;
|
_tail = slot;
|
||||||
} else {
|
} else {
|
||||||
_head = slot;
|
_head = slot;
|
||||||
_tail = slot;
|
_tail = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
slot->clear();
|
slot->clear();
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* CollectionData::addElement(MemoryPool* pool) {
|
inline VariantData* CollectionData::addElement(MemoryPool* pool) {
|
||||||
return slotData(addSlot(pool));
|
return slotData(addSlot(pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
||||||
MemoryPool* pool) {
|
MemoryPool* pool) {
|
||||||
VariantSlot* slot = addSlot(pool);
|
VariantSlot* slot = addSlot(pool);
|
||||||
if (!slotSetKey(slot, key, pool)) {
|
if (!slotSetKey(slot, key, pool)) {
|
||||||
removeSlot(slot);
|
removeSlot(slot);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return slot->data();
|
return slot->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionData::clear() {
|
inline void CollectionData::clear() {
|
||||||
_head = 0;
|
_head = 0;
|
||||||
_tail = 0;
|
_tail = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline bool CollectionData::containsKey(const TAdaptedString& key) const {
|
inline bool CollectionData::containsKey(const TAdaptedString& key) const {
|
||||||
return getSlot(key) != 0;
|
return getSlot(key) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CollectionData::copyFrom(const CollectionData& src,
|
inline bool CollectionData::copyFrom(const CollectionData& src,
|
||||||
MemoryPool* pool) {
|
MemoryPool* pool) {
|
||||||
clear();
|
clear();
|
||||||
for (VariantSlot* s = src._head; s; s = s->next()) {
|
for (VariantSlot* s = src._head; s; s = s->next()) {
|
||||||
VariantData* var;
|
VariantData* var;
|
||||||
if (s->key() != 0) {
|
if (s->key() != 0) {
|
||||||
if (s->ownsKey())
|
if (s->ownsKey())
|
||||||
var = addMember(RamStringAdapter(s->key()), pool);
|
var = addMember(RamStringAdapter(s->key()), pool);
|
||||||
else
|
else
|
||||||
var = addMember(ConstRamStringAdapter(s->key()), pool);
|
var = addMember(ConstRamStringAdapter(s->key()), pool);
|
||||||
} else {
|
} else {
|
||||||
var = addElement(pool);
|
var = addElement(pool);
|
||||||
}
|
}
|
||||||
if (!var)
|
if (!var)
|
||||||
return false;
|
return false;
|
||||||
if (!var->copyFrom(*s->data(), pool))
|
if (!var->copyFrom(*s->data(), pool))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CollectionData::equalsObject(const CollectionData& other) const {
|
inline bool CollectionData::equalsObject(const CollectionData& other) const {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for (VariantSlot* slot = _head; slot; slot = slot->next()) {
|
for (VariantSlot* slot = _head; slot; slot = slot->next()) {
|
||||||
VariantData* v1 = slot->data();
|
VariantData* v1 = slot->data();
|
||||||
VariantData* v2 = other.getMember(adaptString(slot->key()));
|
VariantData* v2 = other.getMember(adaptString(slot->key()));
|
||||||
if (!variantEquals(v1, v2))
|
if (!variantEquals(v1, v2))
|
||||||
return false;
|
return false;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
return count == other.size();
|
return count == other.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CollectionData::equalsArray(const CollectionData& other) const {
|
inline bool CollectionData::equalsArray(const CollectionData& other) const {
|
||||||
VariantSlot* s1 = _head;
|
VariantSlot* s1 = _head;
|
||||||
VariantSlot* s2 = other._head;
|
VariantSlot* s2 = other._head;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (s1 == s2)
|
if (s1 == s2)
|
||||||
return true;
|
return true;
|
||||||
if (!s1 || !s2)
|
if (!s1 || !s2)
|
||||||
return false;
|
return false;
|
||||||
if (!variantEquals(s1->data(), s2->data()))
|
if (!variantEquals(s1->data(), s2->data()))
|
||||||
return false;
|
return false;
|
||||||
s1 = s1->next();
|
s1 = s1->next();
|
||||||
s2 = s2->next();
|
s2 = s2->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const {
|
||||||
VariantSlot* slot = _head;
|
VariantSlot* slot = _head;
|
||||||
while (slot) {
|
while (slot) {
|
||||||
if (key.equals(slot->key()))
|
if (key.equals(slot->key()))
|
||||||
break;
|
break;
|
||||||
slot = slot->next();
|
slot = slot->next();
|
||||||
}
|
}
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::getSlot(size_t index) const {
|
inline VariantSlot* CollectionData::getSlot(size_t index) const {
|
||||||
return _head->next(index);
|
return _head->next(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const {
|
||||||
VariantSlot* current = _head;
|
VariantSlot* current = _head;
|
||||||
while (current) {
|
while (current) {
|
||||||
VariantSlot* next = current->next();
|
VariantSlot* next = current->next();
|
||||||
if (next == target)
|
if (next == target)
|
||||||
return current;
|
return current;
|
||||||
current = next;
|
current = next;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
||||||
VariantSlot* slot = getSlot(key);
|
VariantSlot* slot = getSlot(key);
|
||||||
return slot ? slot->data() : 0;
|
return slot ? slot->data() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
||||||
MemoryPool* pool) {
|
MemoryPool* pool) {
|
||||||
// ignore null key
|
// ignore null key
|
||||||
if (key.isNull())
|
if (key.isNull())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// search a matching key
|
// search a matching key
|
||||||
VariantSlot* slot = getSlot(key);
|
VariantSlot* slot = getSlot(key);
|
||||||
if (slot)
|
if (slot)
|
||||||
return slot->data();
|
return slot->data();
|
||||||
|
|
||||||
return addMember(key, pool);
|
return addMember(key, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* CollectionData::getElement(size_t index) const {
|
inline VariantData* CollectionData::getElement(size_t index) const {
|
||||||
VariantSlot* slot = getSlot(index);
|
VariantSlot* slot = getSlot(index);
|
||||||
return slot ? slot->data() : 0;
|
return slot ? slot->data() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* CollectionData::getOrAddElement(size_t index,
|
inline VariantData* CollectionData::getOrAddElement(size_t index,
|
||||||
MemoryPool* pool) {
|
MemoryPool* pool) {
|
||||||
VariantSlot* slot = _head;
|
VariantSlot* slot = _head;
|
||||||
while (slot && index > 0) {
|
while (slot && index > 0) {
|
||||||
slot = slot->next();
|
slot = slot->next();
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
if (!slot)
|
if (!slot)
|
||||||
index++;
|
index++;
|
||||||
while (index > 0) {
|
while (index > 0) {
|
||||||
slot = addSlot(pool);
|
slot = addSlot(pool);
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
return slotData(slot);
|
return slotData(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionData::removeSlot(VariantSlot* slot) {
|
inline void CollectionData::removeSlot(VariantSlot* slot) {
|
||||||
if (!slot)
|
if (!slot)
|
||||||
return;
|
return;
|
||||||
VariantSlot* prev = getPreviousSlot(slot);
|
VariantSlot* prev = getPreviousSlot(slot);
|
||||||
VariantSlot* next = slot->next();
|
VariantSlot* next = slot->next();
|
||||||
if (prev)
|
if (prev)
|
||||||
prev->setNext(next);
|
prev->setNext(next);
|
||||||
else
|
else
|
||||||
_head = next;
|
_head = next;
|
||||||
if (!next)
|
if (!next)
|
||||||
_tail = prev;
|
_tail = prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionData::removeElement(size_t index) {
|
inline void CollectionData::removeElement(size_t index) {
|
||||||
removeSlot(getSlot(index));
|
removeSlot(getSlot(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t CollectionData::memoryUsage() const {
|
inline size_t CollectionData::memoryUsage() const {
|
||||||
size_t total = 0;
|
size_t total = 0;
|
||||||
for (VariantSlot* s = _head; s; s = s->next()) {
|
for (VariantSlot* s = _head; s; s = s->next()) {
|
||||||
total += sizeof(VariantSlot) + s->data()->memoryUsage();
|
total += sizeof(VariantSlot) + s->data()->memoryUsage();
|
||||||
if (s->ownsKey())
|
if (s->ownsKey())
|
||||||
total += strlen(s->key()) + 1;
|
total += strlen(s->key()) + 1;
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t CollectionData::nesting() const {
|
inline size_t CollectionData::nesting() const {
|
||||||
size_t maxChildNesting = 0;
|
size_t maxChildNesting = 0;
|
||||||
for (VariantSlot* s = _head; s; s = s->next()) {
|
for (VariantSlot* s = _head; s; s = s->next()) {
|
||||||
size_t childNesting = s->data()->nesting();
|
size_t childNesting = s->data()->nesting();
|
||||||
if (childNesting > maxChildNesting)
|
if (childNesting > maxChildNesting)
|
||||||
maxChildNesting = childNesting;
|
maxChildNesting = childNesting;
|
||||||
}
|
}
|
||||||
return maxChildNesting + 1;
|
return maxChildNesting + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t CollectionData::size() const {
|
inline size_t CollectionData::size() const {
|
||||||
return slotSize(_head);
|
return slotSize(_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void movePointer(T*& p, ptrdiff_t offset) {
|
inline void movePointer(T*& p, ptrdiff_t offset) {
|
||||||
if (!p)
|
if (!p)
|
||||||
return;
|
return;
|
||||||
p = reinterpret_cast<T*>(
|
p = reinterpret_cast<T*>(
|
||||||
reinterpret_cast<void*>(reinterpret_cast<char*>(p) + offset));
|
reinterpret_cast<void*>(reinterpret_cast<char*>(p) + offset));
|
||||||
ARDUINOJSON_ASSERT(isAligned(p));
|
ARDUINOJSON_ASSERT(isAligned(p));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void CollectionData::movePointers(ptrdiff_t stringDistance,
|
inline void CollectionData::movePointers(ptrdiff_t stringDistance,
|
||||||
ptrdiff_t variantDistance) {
|
ptrdiff_t variantDistance) {
|
||||||
movePointer(_head, variantDistance);
|
movePointer(_head, variantDistance);
|
||||||
movePointer(_tail, variantDistance);
|
movePointer(_tail, variantDistance);
|
||||||
for (VariantSlot* slot = _head; slot; slot = slot->next())
|
for (VariantSlot* slot = _head; slot; slot = slot->next())
|
||||||
slot->movePointers(stringDistance, variantDistance);
|
slot->movePointers(stringDistance, variantDistance);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,232 +1,237 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
#define ARDUINOJSON_HAS_LONG_LONG 1
|
#define ARDUINOJSON_HAS_LONG_LONG 1
|
||||||
#define ARDUINOJSON_HAS_NULLPTR 1
|
#define ARDUINOJSON_HAS_NULLPTR 1
|
||||||
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
|
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_HAS_LONG_LONG 0
|
#define ARDUINOJSON_HAS_LONG_LONG 0
|
||||||
#define ARDUINOJSON_HAS_NULLPTR 0
|
#define ARDUINOJSON_HAS_NULLPTR 0
|
||||||
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
|
#define ARDUINOJSON_HAS_RVALUE_REFERENCES 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !ARDUINOJSON_HAS_LONG_LONG
|
#if defined(_MSC_VER) && !ARDUINOJSON_HAS_LONG_LONG
|
||||||
#define ARDUINOJSON_HAS_INT64 1
|
#define ARDUINOJSON_HAS_INT64 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_HAS_INT64 0
|
#define ARDUINOJSON_HAS_INT64 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Small or big machine?
|
// Small or big machine?
|
||||||
#ifndef ARDUINOJSON_EMBEDDED_MODE
|
#ifndef ARDUINOJSON_EMBEDDED_MODE
|
||||||
#if defined(ARDUINO) /* Arduino*/ \
|
#if defined(ARDUINO) /* Arduino*/ \
|
||||||
|| defined(__IAR_SYSTEMS_ICC__) /* IAR Embedded Workbench */ \
|
|| defined(__IAR_SYSTEMS_ICC__) /* IAR Embedded Workbench */ \
|
||||||
|| defined(__XC) /* MPLAB XC compiler */ \
|
|| defined(__XC) /* MPLAB XC compiler */ \
|
||||||
|| defined(__ARMCC_VERSION) /* Keil ARM Compiler */ \
|
|| defined(__ARMCC_VERSION) /* Keil ARM Compiler */ \
|
||||||
|| defined(__AVR) /* Atmel AVR8/GNU C Compiler */
|
|| defined(__AVR) /* Atmel AVR8/GNU C Compiler */
|
||||||
#define ARDUINOJSON_EMBEDDED_MODE 1
|
#define ARDUINOJSON_EMBEDDED_MODE 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_EMBEDDED_MODE 0
|
#define ARDUINOJSON_EMBEDDED_MODE 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Auto enable std::stream if the right headers are here and no conflicting
|
// Auto enable std::stream if the right headers are here and no conflicting
|
||||||
// macro is defined
|
// macro is defined
|
||||||
#if !defined(ARDUINOJSON_ENABLE_STD_STREAM) && defined(__has_include)
|
#if !defined(ARDUINOJSON_ENABLE_STD_STREAM) && defined(__has_include)
|
||||||
#if __has_include(<istream>) && \
|
#if __has_include(<istream>) && \
|
||||||
__has_include(<ostream>) && \
|
__has_include(<ostream>) && \
|
||||||
!defined(min) && \
|
!defined(min) && \
|
||||||
!defined(max)
|
!defined(max)
|
||||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Auto enable std::string if the right header is here and no conflicting
|
// Auto enable std::string if the right header is here and no conflicting
|
||||||
// macro is defined
|
// macro is defined
|
||||||
#if !defined(ARDUINOJSON_ENABLE_STD_STRING) && defined(__has_include)
|
#if !defined(ARDUINOJSON_ENABLE_STD_STRING) && defined(__has_include)
|
||||||
#if __has_include(<string>) && !defined(min) && !defined(max)
|
#if __has_include(<string>) && !defined(min) && !defined(max)
|
||||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_EMBEDDED_MODE
|
#if ARDUINOJSON_EMBEDDED_MODE
|
||||||
|
|
||||||
// Store floats by default to reduce the memory usage (issue #134)
|
// Store floats by default to reduce the memory usage (issue #134)
|
||||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||||
#define ARDUINOJSON_USE_DOUBLE 0
|
#define ARDUINOJSON_USE_DOUBLE 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Store longs by default, because they usually match the size of a float.
|
// Store longs by default, because they usually match the size of a float.
|
||||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Embedded systems usually don't have std::string
|
// Embedded systems usually don't have std::string
|
||||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Embedded systems usually don't have std::stream
|
// Embedded systems usually don't have std::stream
|
||||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Limit nesting as the stack is likely to be small
|
// Limit nesting as the stack is likely to be small
|
||||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
|
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else // ARDUINOJSON_EMBEDDED_MODE
|
#else // ARDUINOJSON_EMBEDDED_MODE
|
||||||
|
|
||||||
// On a computer we have plenty of memory so we can use doubles
|
// On a computer we have plenty of memory so we can use doubles
|
||||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||||
#define ARDUINOJSON_USE_DOUBLE 1
|
#define ARDUINOJSON_USE_DOUBLE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use long long when available
|
// Use long long when available
|
||||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||||
#if ARDUINOJSON_HAS_LONG_LONG || ARDUINOJSON_HAS_INT64
|
#if ARDUINOJSON_HAS_LONG_LONG || ARDUINOJSON_HAS_INT64
|
||||||
#define ARDUINOJSON_USE_LONG_LONG 1
|
#define ARDUINOJSON_USE_LONG_LONG 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// On a computer, we can use std::string
|
// On a computer, we can use std::string
|
||||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// On a computer, we can assume std::stream
|
// On a computer, we can assume std::stream
|
||||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// On a computer, the stack is large so we can increase nesting limit
|
// On a computer, the stack is large so we can increase nesting limit
|
||||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
|
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // ARDUINOJSON_EMBEDDED_MODE
|
#endif // ARDUINOJSON_EMBEDDED_MODE
|
||||||
|
|
||||||
#ifdef ARDUINO
|
#ifdef ARDUINO
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
// Enable support for Arduino's String class
|
// Enable support for Arduino's String class
|
||||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable support for Arduino's Stream class
|
// Enable support for Arduino's Stream class
|
||||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable support for Arduino's Print class
|
// Enable support for Arduino's Print class
|
||||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
|
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else // ARDUINO
|
#else // ARDUINO
|
||||||
|
|
||||||
// Disable support for Arduino's String class
|
// Disable support for Arduino's String class
|
||||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Disable support for Arduino's Stream class
|
// Disable support for Arduino's Stream class
|
||||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
|
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Disable support for Arduino's Print class
|
// Disable support for Arduino's Print class
|
||||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
|
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // ARDUINO
|
#endif // ARDUINO
|
||||||
|
|
||||||
#ifndef ARDUINOJSON_ENABLE_PROGMEM
|
#ifndef ARDUINOJSON_ENABLE_PROGMEM
|
||||||
#ifdef PROGMEM
|
#ifdef PROGMEM
|
||||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_ENABLE_PROGMEM 0
|
#define ARDUINOJSON_ENABLE_PROGMEM 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Convert unicode escape sequence (\u0123) to UTF-8
|
// Convert unicode escape sequence (\u0123) to UTF-8
|
||||||
#ifndef ARDUINOJSON_DECODE_UNICODE
|
#ifndef ARDUINOJSON_DECODE_UNICODE
|
||||||
#define ARDUINOJSON_DECODE_UNICODE 1
|
#define ARDUINOJSON_DECODE_UNICODE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Ignore comments in input
|
// Ignore comments in input
|
||||||
#ifndef ARDUINOJSON_ENABLE_COMMENTS
|
#ifndef ARDUINOJSON_ENABLE_COMMENTS
|
||||||
#define ARDUINOJSON_ENABLE_COMMENTS 0
|
#define ARDUINOJSON_ENABLE_COMMENTS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Support NaN in JSON
|
// Support NaN in JSON
|
||||||
#ifndef ARDUINOJSON_ENABLE_NAN
|
#ifndef ARDUINOJSON_ENABLE_NAN
|
||||||
#define ARDUINOJSON_ENABLE_NAN 0
|
#define ARDUINOJSON_ENABLE_NAN 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Support Infinity in JSON
|
// Support Infinity in JSON
|
||||||
#ifndef ARDUINOJSON_ENABLE_INFINITY
|
#ifndef ARDUINOJSON_ENABLE_INFINITY
|
||||||
#define ARDUINOJSON_ENABLE_INFINITY 0
|
#define ARDUINOJSON_ENABLE_INFINITY 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Control the exponentiation threshold for big numbers
|
// Control the exponentiation threshold for big numbers
|
||||||
// CAUTION: cannot be more that 1e9 !!!!
|
// CAUTION: cannot be more that 1e9 !!!!
|
||||||
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
|
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
|
||||||
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
|
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Control the exponentiation threshold for small numbers
|
// Control the exponentiation threshold for small numbers
|
||||||
#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
|
#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
|
||||||
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
|
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
||||||
#if defined(_MSC_VER) || \
|
#if defined(_MSC_VER) || \
|
||||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
||||||
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
|
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
|
||||||
#define ARDUINOJSON_LITTLE_ENDIAN 1
|
#define ARDUINOJSON_LITTLE_ENDIAN 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_LITTLE_ENDIAN 0
|
#define ARDUINOJSON_LITTLE_ENDIAN 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
|
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
|
||||||
#if defined(__AVR)
|
#if defined(__AVR)
|
||||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
|
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
|
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARDUINOJSON_TAB
|
#ifndef ARDUINOJSON_TAB
|
||||||
#define ARDUINOJSON_TAB " "
|
#define ARDUINOJSON_TAB " "
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
#ifndef ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||||
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1
|
#define ARDUINOJSON_ENABLE_STRING_DEDUPLICATION 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARDUINOJSON_STRING_BUFFER_SIZE
|
#ifndef ARDUINOJSON_STRING_BUFFER_SIZE
|
||||||
#define ARDUINOJSON_STRING_BUFFER_SIZE 32
|
#define ARDUINOJSON_STRING_BUFFER_SIZE 32
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef ARDUINOJSON_DEBUG
|
#ifndef ARDUINOJSON_DEBUG
|
||||||
#ifdef __PLATFORMIO_BUILD_DEBUG__
|
#ifdef __PLATFORMIO_BUILD_DEBUG__
|
||||||
#define ARDUINOJSON_DEBUG 1
|
#define ARDUINOJSON_DEBUG 1
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_DEBUG 0
|
#define ARDUINOJSON_DEBUG 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_HAS_NULLPTR && defined(nullptr)
|
||||||
|
#error nullptr is defined as a macro. Remove the faulty #define or #undef nullptr
|
||||||
|
// See https://github.com/bblanchon/ArduinoJson/issues/1355
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,115 +1,125 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/preprocessor.hpp>
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
#include <ArduinoJson/Polyfills/static_array.hpp>
|
||||||
#include <ostream>
|
|
||||||
#endif
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
|
#include <ostream>
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
#endif
|
||||||
|
|
||||||
class DeserializationError {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
// safe bool idiom
|
|
||||||
typedef void (DeserializationError::*bool_type)() const;
|
class DeserializationError {
|
||||||
void safeBoolHelper() const {}
|
// safe bool idiom
|
||||||
|
typedef void (DeserializationError::*bool_type)() const;
|
||||||
public:
|
void safeBoolHelper() const {}
|
||||||
enum Code {
|
|
||||||
Ok,
|
public:
|
||||||
IncompleteInput,
|
enum Code {
|
||||||
InvalidInput,
|
Ok,
|
||||||
NoMemory,
|
EmptyInput,
|
||||||
NotSupported,
|
IncompleteInput,
|
||||||
TooDeep
|
InvalidInput,
|
||||||
};
|
NoMemory,
|
||||||
|
NotSupported,
|
||||||
DeserializationError() {}
|
TooDeep
|
||||||
DeserializationError(Code c) : _code(c) {}
|
};
|
||||||
|
|
||||||
// Compare with DeserializationError
|
DeserializationError() {}
|
||||||
friend bool operator==(const DeserializationError& lhs,
|
DeserializationError(Code c) : _code(c) {}
|
||||||
const DeserializationError& rhs) {
|
|
||||||
return lhs._code == rhs._code;
|
// Compare with DeserializationError
|
||||||
}
|
friend bool operator==(const DeserializationError& lhs,
|
||||||
friend bool operator!=(const DeserializationError& lhs,
|
const DeserializationError& rhs) {
|
||||||
const DeserializationError& rhs) {
|
return lhs._code == rhs._code;
|
||||||
return lhs._code != rhs._code;
|
}
|
||||||
}
|
friend bool operator!=(const DeserializationError& lhs,
|
||||||
|
const DeserializationError& rhs) {
|
||||||
// Compare with Code
|
return lhs._code != rhs._code;
|
||||||
friend bool operator==(const DeserializationError& lhs, Code rhs) {
|
}
|
||||||
return lhs._code == rhs;
|
|
||||||
}
|
// Compare with Code
|
||||||
friend bool operator==(Code lhs, const DeserializationError& rhs) {
|
friend bool operator==(const DeserializationError& lhs, Code rhs) {
|
||||||
return lhs == rhs._code;
|
return lhs._code == rhs;
|
||||||
}
|
}
|
||||||
friend bool operator!=(const DeserializationError& lhs, Code rhs) {
|
friend bool operator==(Code lhs, const DeserializationError& rhs) {
|
||||||
return lhs._code != rhs;
|
return lhs == rhs._code;
|
||||||
}
|
}
|
||||||
friend bool operator!=(Code lhs, const DeserializationError& rhs) {
|
friend bool operator!=(const DeserializationError& lhs, Code rhs) {
|
||||||
return lhs != rhs._code;
|
return lhs._code != rhs;
|
||||||
}
|
}
|
||||||
|
friend bool operator!=(Code lhs, const DeserializationError& rhs) {
|
||||||
// Behaves like a bool
|
return lhs != rhs._code;
|
||||||
operator bool_type() const {
|
}
|
||||||
return _code != Ok ? &DeserializationError::safeBoolHelper : 0;
|
|
||||||
}
|
// Behaves like a bool
|
||||||
friend bool operator==(bool value, const DeserializationError& err) {
|
operator bool_type() const {
|
||||||
return static_cast<bool>(err) == value;
|
return _code != Ok ? &DeserializationError::safeBoolHelper : 0;
|
||||||
}
|
}
|
||||||
friend bool operator==(const DeserializationError& err, bool value) {
|
friend bool operator==(bool value, const DeserializationError& err) {
|
||||||
return static_cast<bool>(err) == value;
|
return static_cast<bool>(err) == value;
|
||||||
}
|
}
|
||||||
friend bool operator!=(bool value, const DeserializationError& err) {
|
friend bool operator==(const DeserializationError& err, bool value) {
|
||||||
return static_cast<bool>(err) != value;
|
return static_cast<bool>(err) == value;
|
||||||
}
|
}
|
||||||
friend bool operator!=(const DeserializationError& err, bool value) {
|
friend bool operator!=(bool value, const DeserializationError& err) {
|
||||||
return static_cast<bool>(err) != value;
|
return static_cast<bool>(err) != value;
|
||||||
}
|
}
|
||||||
|
friend bool operator!=(const DeserializationError& err, bool value) {
|
||||||
// Returns internal enum, useful for switch statement
|
return static_cast<bool>(err) != value;
|
||||||
Code code() const {
|
}
|
||||||
return _code;
|
|
||||||
}
|
// Returns internal enum, useful for switch statement
|
||||||
|
Code code() const {
|
||||||
const char* c_str() const {
|
return _code;
|
||||||
switch (_code) {
|
}
|
||||||
case Ok:
|
|
||||||
return "Ok";
|
const char* c_str() const {
|
||||||
case TooDeep:
|
static const char* messages[] = {
|
||||||
return "TooDeep";
|
"Ok", "EmptyInput", "IncompleteInput", "InvalidInput",
|
||||||
case NoMemory:
|
"NoMemory", "NotSupported", "TooDeep"};
|
||||||
return "NoMemory";
|
ARDUINOJSON_ASSERT(static_cast<size_t>(_code) <
|
||||||
case InvalidInput:
|
sizeof(messages) / sizeof(messages[0]));
|
||||||
return "InvalidInput";
|
return messages[_code];
|
||||||
case IncompleteInput:
|
}
|
||||||
return "IncompleteInput";
|
|
||||||
case NotSupported:
|
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||||
return "NotSupported";
|
const __FlashStringHelper* f_str() const {
|
||||||
default:
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(char, s0, "Ok");
|
||||||
return "???";
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(char, s1, "EmptyInput");
|
||||||
}
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(char, s2, "IncompleteInput");
|
||||||
}
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(char, s3, "InvalidInput");
|
||||||
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(char, s4, "NoMemory");
|
||||||
private:
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(char, s5, "NotSupported");
|
||||||
Code _code;
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(char, s6, "TooDeep");
|
||||||
};
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(
|
||||||
|
const char*, messages,
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
ARDUINOJSON_EXPAND7({s0, s1, s2, s3, s4, s5, s6}));
|
||||||
inline std::ostream& operator<<(std::ostream& s,
|
return ARDUINOJSON_READ_STATIC_ARRAY(const __FlashStringHelper*, messages,
|
||||||
const DeserializationError& e) {
|
_code);
|
||||||
s << e.c_str();
|
}
|
||||||
return s;
|
#endif
|
||||||
}
|
|
||||||
|
private:
|
||||||
inline std::ostream& operator<<(std::ostream& s, DeserializationError::Code c) {
|
Code _code;
|
||||||
s << DeserializationError(c).c_str();
|
};
|
||||||
return s;
|
|
||||||
}
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
#endif
|
inline std::ostream& operator<<(std::ostream& s,
|
||||||
|
const DeserializationError& e) {
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class Filter {
|
class Filter {
|
||||||
public:
|
public:
|
||||||
explicit Filter(VariantConstRef v) : _variant(v) {}
|
explicit Filter(VariantConstRef v) : _variant(v) {}
|
||||||
|
|
||||||
bool allow() const {
|
bool allow() const {
|
||||||
return _variant;
|
return _variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allowArray() const {
|
bool allowArray() const {
|
||||||
return _variant == true || _variant.is<ArrayRef>();
|
return _variant == true || _variant.is<ArrayRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allowObject() const {
|
bool allowObject() const {
|
||||||
return _variant == true || _variant.is<ObjectRef>();
|
return _variant == true || _variant.is<ObjectRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allowValue() const {
|
bool allowValue() const {
|
||||||
return _variant == true;
|
return _variant == true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TKey>
|
template <typename TKey>
|
||||||
Filter operator[](const TKey& key) const {
|
Filter operator[](const TKey& key) const {
|
||||||
if (_variant == true) // "true" means "allow recursively"
|
if (_variant == true) // "true" means "allow recursively"
|
||||||
return *this;
|
return *this;
|
||||||
else
|
else
|
||||||
return Filter(_variant[key]);
|
return Filter(_variant[key] | _variant["*"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VariantConstRef _variant;
|
VariantConstRef _variant;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AllowAllFilter {
|
struct AllowAllFilter {
|
||||||
bool allow() const {
|
bool allow() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allowArray() const {
|
bool allowArray() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allowObject() const {
|
bool allowObject() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool allowValue() const {
|
bool allowValue() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TKey>
|
template <typename TKey>
|
||||||
AllowAllFilter operator[](const TKey&) const {
|
AllowAllFilter operator[](const TKey&) const {
|
||||||
return AllowAllFilter();
|
return AllowAllFilter();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class NestingLimit {
|
class NestingLimit {
|
||||||
public:
|
public:
|
||||||
NestingLimit() : _value(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
NestingLimit() : _value(ARDUINOJSON_DEFAULT_NESTING_LIMIT) {}
|
||||||
explicit NestingLimit(uint8_t n) : _value(n) {}
|
explicit NestingLimit(uint8_t n) : _value(n) {}
|
||||||
|
|
||||||
NestingLimit decrement() const {
|
NestingLimit decrement() const {
|
||||||
ARDUINOJSON_ASSERT(_value > 0);
|
ARDUINOJSON_ASSERT(_value > 0);
|
||||||
return NestingLimit(static_cast<uint8_t>(_value - 1));
|
return NestingLimit(static_cast<uint8_t>(_value - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool reached() const {
|
bool reached() const {
|
||||||
return _value == 0;
|
return _value == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t _value;
|
uint8_t _value;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
#include <stdlib.h> // for size_t
|
#include <stdlib.h> // for size_t
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// The default reader is a simple wrapper for Readers that are not copiable
|
// The default reader is a simple wrapper for Readers that are not copiable
|
||||||
template <typename TSource, typename Enable = void>
|
template <typename TSource, typename Enable = void>
|
||||||
struct Reader {
|
struct Reader {
|
||||||
public:
|
public:
|
||||||
Reader(TSource& source) : _source(&source) {}
|
Reader(TSource& source) : _source(&source) {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
return _source->read();
|
return _source->read();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
return _source->readBytes(buffer, length);
|
return _source->readBytes(buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TSource* _source;
|
TSource* _source;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TSource, typename Enable = void>
|
template <typename TSource, typename Enable = void>
|
||||||
struct BoundedReader {
|
struct BoundedReader {
|
||||||
// no default implementation because we need to pass the size to the
|
// no default implementation because we need to pass the size to the
|
||||||
// constructor
|
// constructor
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
#include <ArduinoJson/Deserialization/Readers/IteratorReader.hpp>
|
#include <ArduinoJson/Deserialization/Readers/IteratorReader.hpp>
|
||||||
#include <ArduinoJson/Deserialization/Readers/RamReader.hpp>
|
#include <ArduinoJson/Deserialization/Readers/RamReader.hpp>
|
||||||
#include <ArduinoJson/Deserialization/Readers/VariantReader.hpp>
|
#include <ArduinoJson/Deserialization/Readers/VariantReader.hpp>
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||||
#include <ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp>
|
#include <ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
#include <ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp>
|
#include <ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_PROGMEM
|
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||||
#include <ArduinoJson/Deserialization/Readers/FlashReader.hpp>
|
#include <ArduinoJson/Deserialization/Readers/FlashReader.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
#include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp>
|
#include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,31 +1,31 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Stream.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TSource>
|
template <typename TSource>
|
||||||
struct Reader<TSource,
|
struct Reader<TSource,
|
||||||
typename enable_if<is_base_of<Stream, TSource>::value>::type> {
|
typename enable_if<is_base_of<Stream, TSource>::value>::type> {
|
||||||
public:
|
public:
|
||||||
explicit Reader(Stream& stream) : _stream(&stream) {}
|
explicit Reader(Stream& stream) : _stream(&stream) {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
// don't use _stream.read() as it ignores the timeout
|
// don't use _stream.read() as it ignores the timeout
|
||||||
char c;
|
char c;
|
||||||
return _stream->readBytes(&c, 1) ? static_cast<unsigned char>(c) : -1;
|
return _stream->readBytes(&c, 1) ? static_cast<unsigned char>(c) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
return _stream->readBytes(buffer, length);
|
return _stream->readBytes(buffer, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Stream* _stream;
|
Stream* _stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TSource>
|
template <typename TSource>
|
||||||
struct Reader<TSource,
|
struct Reader<TSource,
|
||||||
typename enable_if<is_base_of< ::String, TSource>::value>::type>
|
typename enable_if<is_base_of< ::String, TSource>::value>::type>
|
||||||
: BoundedReader<const char*> {
|
: BoundedReader<const char*> {
|
||||||
explicit Reader(const ::String& s)
|
explicit Reader(const ::String& s)
|
||||||
: BoundedReader<const char*>(s.c_str(), s.length()) {}
|
: BoundedReader<const char*>(s.c_str(), s.length()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,53 +1,53 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Reader<const __FlashStringHelper*, void> {
|
struct Reader<const __FlashStringHelper*, void> {
|
||||||
const char* _ptr;
|
const char* _ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Reader(const __FlashStringHelper* ptr)
|
explicit Reader(const __FlashStringHelper* ptr)
|
||||||
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
return pgm_read_byte(_ptr++);
|
return pgm_read_byte(_ptr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
memcpy_P(buffer, _ptr, length);
|
memcpy_P(buffer, _ptr, length);
|
||||||
_ptr += length;
|
_ptr += length;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct BoundedReader<const __FlashStringHelper*, void> {
|
struct BoundedReader<const __FlashStringHelper*, void> {
|
||||||
const char* _ptr;
|
const char* _ptr;
|
||||||
const char* _end;
|
const char* _end;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BoundedReader(const __FlashStringHelper* ptr, size_t size)
|
explicit BoundedReader(const __FlashStringHelper* ptr, size_t size)
|
||||||
: _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {}
|
: _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
if (_ptr < _end)
|
if (_ptr < _end)
|
||||||
return pgm_read_byte(_ptr++);
|
return pgm_read_byte(_ptr++);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
size_t available = static_cast<size_t>(_end - _ptr);
|
size_t available = static_cast<size_t>(_end - _ptr);
|
||||||
if (available < length)
|
if (available < length)
|
||||||
length = available;
|
length = available;
|
||||||
memcpy_P(buffer, _ptr, length);
|
memcpy_P(buffer, _ptr, length);
|
||||||
_ptr += length;
|
_ptr += length;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,43 +1,43 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TIterator>
|
template <typename TIterator>
|
||||||
class IteratorReader {
|
class IteratorReader {
|
||||||
TIterator _ptr, _end;
|
TIterator _ptr, _end;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit IteratorReader(TIterator begin, TIterator end)
|
explicit IteratorReader(TIterator begin, TIterator end)
|
||||||
: _ptr(begin), _end(end) {}
|
: _ptr(begin), _end(end) {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
if (_ptr < _end)
|
if (_ptr < _end)
|
||||||
return static_cast<unsigned char>(*_ptr++);
|
return static_cast<unsigned char>(*_ptr++);
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
while (i < length && _ptr < _end) buffer[i++] = *_ptr++;
|
while (i < length && _ptr < _end) buffer[i++] = *_ptr++;
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct void_ {
|
struct void_ {
|
||||||
typedef void type;
|
typedef void type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TSource>
|
template <typename TSource>
|
||||||
struct Reader<TSource, typename void_<typename TSource::const_iterator>::type>
|
struct Reader<TSource, typename void_<typename TSource::const_iterator>::type>
|
||||||
: IteratorReader<typename TSource::const_iterator> {
|
: IteratorReader<typename TSource::const_iterator> {
|
||||||
explicit Reader(const TSource& source)
|
explicit Reader(const TSource& source)
|
||||||
: IteratorReader<typename TSource::const_iterator>(source.begin(),
|
: IteratorReader<typename TSource::const_iterator>(source.begin(),
|
||||||
source.end()) {}
|
source.end()) {}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,50 +1,50 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct IsCharOrVoid {
|
struct IsCharOrVoid {
|
||||||
static const bool value =
|
static const bool value =
|
||||||
is_same<T, void>::value || is_same<T, char>::value ||
|
is_same<T, void>::value || is_same<T, char>::value ||
|
||||||
is_same<T, unsigned char>::value || is_same<T, signed char>::value;
|
is_same<T, unsigned char>::value || is_same<T, signed char>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct IsCharOrVoid<const T> : IsCharOrVoid<T> {};
|
struct IsCharOrVoid<const T> : IsCharOrVoid<T> {};
|
||||||
|
|
||||||
template <typename TSource>
|
template <typename TSource>
|
||||||
struct Reader<TSource*,
|
struct Reader<TSource*,
|
||||||
typename enable_if<IsCharOrVoid<TSource>::value>::type> {
|
typename enable_if<IsCharOrVoid<TSource>::value>::type> {
|
||||||
const char* _ptr;
|
const char* _ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Reader(const void* ptr)
|
explicit Reader(const void* ptr)
|
||||||
: _ptr(ptr ? reinterpret_cast<const char*>(ptr) : "") {}
|
: _ptr(ptr ? reinterpret_cast<const char*>(ptr) : "") {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
return static_cast<unsigned char>(*_ptr++);
|
return static_cast<unsigned char>(*_ptr++);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
for (size_t i = 0; i < length; i++) buffer[i] = *_ptr++;
|
for (size_t i = 0; i < length; i++) buffer[i] = *_ptr++;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TSource>
|
template <typename TSource>
|
||||||
struct BoundedReader<TSource*,
|
struct BoundedReader<TSource*,
|
||||||
typename enable_if<IsCharOrVoid<TSource>::value>::type>
|
typename enable_if<IsCharOrVoid<TSource>::value>::type>
|
||||||
: public IteratorReader<const char*> {
|
: public IteratorReader<const char*> {
|
||||||
public:
|
public:
|
||||||
explicit BoundedReader(const void* ptr, size_t len)
|
explicit BoundedReader(const void* ptr, size_t len)
|
||||||
: IteratorReader<const char*>(reinterpret_cast<const char*>(ptr),
|
: IteratorReader<const char*>(reinterpret_cast<const char*>(ptr),
|
||||||
reinterpret_cast<const char*>(ptr) + len) {}
|
reinterpret_cast<const char*>(ptr) + len) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <istream>
|
#include <istream>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TSource>
|
template <typename TSource>
|
||||||
struct Reader<TSource, typename enable_if<
|
struct Reader<TSource, typename enable_if<
|
||||||
is_base_of<std::istream, TSource>::value>::type> {
|
is_base_of<std::istream, TSource>::value>::type> {
|
||||||
public:
|
public:
|
||||||
explicit Reader(std::istream& stream) : _stream(&stream) {}
|
explicit Reader(std::istream& stream) : _stream(&stream) {}
|
||||||
|
|
||||||
int read() {
|
int read() {
|
||||||
return _stream->get();
|
return _stream->get();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t readBytes(char* buffer, size_t length) {
|
size_t readBytes(char* buffer, size_t length) {
|
||||||
_stream->read(buffer, static_cast<std::streamsize>(length));
|
_stream->read(buffer, static_cast<std::streamsize>(length));
|
||||||
return static_cast<size_t>(_stream->gcount());
|
return static_cast<size_t>(_stream->gcount());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::istream* _stream;
|
std::istream* _stream;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,34 +1,34 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Object/MemberProxy.hpp>
|
#include <ArduinoJson/Object/MemberProxy.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TArray>
|
template <typename TArray>
|
||||||
struct Reader<ElementProxy<TArray>, void> : Reader<char*, void> {
|
struct Reader<ElementProxy<TArray>, void> : Reader<char*, void> {
|
||||||
explicit Reader(const ElementProxy<TArray>& x)
|
explicit Reader(const ElementProxy<TArray>& x)
|
||||||
: Reader<char*, void>(x.template as<const char*>()) {}
|
: Reader<char*, void>(x.template as<const char*>()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TObject, typename TStringRef>
|
template <typename TObject, typename TStringRef>
|
||||||
struct Reader<MemberProxy<TObject, TStringRef>, void> : Reader<char*, void> {
|
struct Reader<MemberProxy<TObject, TStringRef>, void> : Reader<char*, void> {
|
||||||
explicit Reader(const MemberProxy<TObject, TStringRef>& x)
|
explicit Reader(const MemberProxy<TObject, TStringRef>& x)
|
||||||
: Reader<char*, void>(x.template as<const char*>()) {}
|
: Reader<char*, void>(x.template as<const char*>()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Reader<VariantRef, void> : Reader<char*, void> {
|
struct Reader<VariantRef, void> : Reader<char*, void> {
|
||||||
explicit Reader(VariantRef x) : Reader<char*, void>(x.as<const char*>()) {}
|
explicit Reader(VariantRef x) : Reader<char*, void>(x.as<const char*>()) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct Reader<VariantConstRef, void> : Reader<char*, void> {
|
struct Reader<VariantConstRef, void> : Reader<char*, void> {
|
||||||
explicit Reader(VariantConstRef x)
|
explicit Reader(VariantConstRef x)
|
||||||
: Reader<char*, void>(x.as<const char*>()) {}
|
: Reader<char*, void>(x.as<const char*>()) {}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,68 +1,71 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Deserialization/DeserializationError.hpp>
|
#include <ArduinoJson/Deserialization/DeserializationError.hpp>
|
||||||
#include <ArduinoJson/Deserialization/Filter.hpp>
|
#include <ArduinoJson/Deserialization/Filter.hpp>
|
||||||
#include <ArduinoJson/Deserialization/NestingLimit.hpp>
|
#include <ArduinoJson/Deserialization/NestingLimit.hpp>
|
||||||
#include <ArduinoJson/Deserialization/Reader.hpp>
|
#include <ArduinoJson/Deserialization/Reader.hpp>
|
||||||
#include <ArduinoJson/StringStorage/StringStorage.hpp>
|
#include <ArduinoJson/StringStorage/StringStorage.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <template <typename, typename> class TDeserializer, typename TReader,
|
template <template <typename, typename> class TDeserializer, typename TReader,
|
||||||
typename TWriter>
|
typename TWriter>
|
||||||
TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool &pool,
|
TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool &pool,
|
||||||
TReader reader,
|
TReader reader,
|
||||||
TWriter writer) {
|
TWriter writer) {
|
||||||
return TDeserializer<TReader, TWriter>(pool, reader, writer);
|
return TDeserializer<TReader, TWriter>(pool, reader, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
// deserialize(JsonDocument&, const std::string&, NestingLimit, Filter);
|
// deserialize(JsonDocument&, const std::string&, NestingLimit, Filter);
|
||||||
// deserialize(JsonDocument&, const String&, NestingLimit, Filter);
|
// deserialize(JsonDocument&, const String&, NestingLimit, Filter);
|
||||||
// deserialize(JsonDocument&, char*, NestingLimit, Filter);
|
// deserialize(JsonDocument&, char*, NestingLimit, Filter);
|
||||||
// deserialize(JsonDocument&, const char*, NestingLimit, Filter);
|
// deserialize(JsonDocument&, const char*, NestingLimit, Filter);
|
||||||
// deserialize(JsonDocument&, const __FlashStringHelper*, NestingLimit, Filter);
|
// deserialize(JsonDocument&, const __FlashStringHelper*, NestingLimit, Filter);
|
||||||
template <template <typename, typename> class TDeserializer, typename TString,
|
template <template <typename, typename> class TDeserializer, typename TString,
|
||||||
typename TFilter>
|
typename TFilter>
|
||||||
typename enable_if<!is_array<TString>::value, DeserializationError>::type
|
typename enable_if<!is_array<TString>::value, DeserializationError>::type
|
||||||
deserialize(JsonDocument &doc, const TString &input, NestingLimit nestingLimit,
|
deserialize(JsonDocument &doc, const TString &input, NestingLimit nestingLimit,
|
||||||
TFilter filter) {
|
TFilter filter) {
|
||||||
Reader<TString> reader(input);
|
Reader<TString> reader(input);
|
||||||
doc.clear();
|
doc.clear();
|
||||||
return makeDeserializer<TDeserializer>(doc.memoryPool(), reader,
|
return makeDeserializer<TDeserializer>(
|
||||||
makeStringStorage(input))
|
doc.memoryPool(), reader,
|
||||||
.parse(doc.data(), filter, nestingLimit);
|
makeStringStorage(input, doc.memoryPool()))
|
||||||
}
|
.parse(doc.data(), filter, nestingLimit);
|
||||||
//
|
}
|
||||||
// deserialize(JsonDocument&, char*, size_t, NestingLimit, Filter);
|
//
|
||||||
// deserialize(JsonDocument&, const char*, size_t, NestingLimit, Filter);
|
// deserialize(JsonDocument&, char*, size_t, NestingLimit, Filter);
|
||||||
// deserialize(JsonDocument&, const __FlashStringHelper*, size_t, NL, Filter);
|
// deserialize(JsonDocument&, const char*, size_t, NestingLimit, Filter);
|
||||||
template <template <typename, typename> class TDeserializer, typename TChar,
|
// deserialize(JsonDocument&, const __FlashStringHelper*, size_t, NL, Filter);
|
||||||
typename TFilter>
|
template <template <typename, typename> class TDeserializer, typename TChar,
|
||||||
DeserializationError deserialize(JsonDocument &doc, TChar *input,
|
typename TFilter>
|
||||||
size_t inputSize, NestingLimit nestingLimit,
|
DeserializationError deserialize(JsonDocument &doc, TChar *input,
|
||||||
TFilter filter) {
|
size_t inputSize, NestingLimit nestingLimit,
|
||||||
BoundedReader<TChar *> reader(input, inputSize);
|
TFilter filter) {
|
||||||
doc.clear();
|
BoundedReader<TChar *> reader(input, inputSize);
|
||||||
return makeDeserializer<TDeserializer>(doc.memoryPool(), reader,
|
doc.clear();
|
||||||
makeStringStorage(input))
|
return makeDeserializer<TDeserializer>(
|
||||||
.parse(doc.data(), filter, nestingLimit);
|
doc.memoryPool(), reader,
|
||||||
}
|
makeStringStorage(input, doc.memoryPool()))
|
||||||
//
|
.parse(doc.data(), filter, nestingLimit);
|
||||||
// deserialize(JsonDocument&, std::istream&, NestingLimit, Filter);
|
}
|
||||||
// deserialize(JsonDocument&, Stream&, NestingLimit, Filter);
|
//
|
||||||
template <template <typename, typename> class TDeserializer, typename TStream,
|
// deserialize(JsonDocument&, std::istream&, NestingLimit, Filter);
|
||||||
typename TFilter>
|
// deserialize(JsonDocument&, Stream&, NestingLimit, Filter);
|
||||||
DeserializationError deserialize(JsonDocument &doc, TStream &input,
|
template <template <typename, typename> class TDeserializer, typename TStream,
|
||||||
NestingLimit nestingLimit, TFilter filter) {
|
typename TFilter>
|
||||||
Reader<TStream> reader(input);
|
DeserializationError deserialize(JsonDocument &doc, TStream &input,
|
||||||
doc.clear();
|
NestingLimit nestingLimit, TFilter filter) {
|
||||||
return makeDeserializer<TDeserializer>(doc.memoryPool(), reader,
|
Reader<TStream> reader(input);
|
||||||
makeStringStorage(input))
|
doc.clear();
|
||||||
.parse(doc.data(), filter, nestingLimit);
|
return makeDeserializer<TDeserializer>(
|
||||||
}
|
doc.memoryPool(), reader,
|
||||||
|
makeStringStorage(input, doc.memoryPool()))
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
.parse(doc.data(), filter, nestingLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,164 +1,164 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// Helper to implement the "base-from-member" idiom
|
// Helper to implement the "base-from-member" idiom
|
||||||
// (we need to store the allocator before constructing JsonDocument)
|
// (we need to store the allocator before constructing JsonDocument)
|
||||||
template <typename TAllocator>
|
template <typename TAllocator>
|
||||||
class AllocatorOwner {
|
class AllocatorOwner {
|
||||||
public:
|
public:
|
||||||
AllocatorOwner() {}
|
AllocatorOwner() {}
|
||||||
AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {}
|
AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {}
|
||||||
AllocatorOwner(TAllocator a) : _allocator(a) {}
|
AllocatorOwner(TAllocator a) : _allocator(a) {}
|
||||||
|
|
||||||
void* allocate(size_t size) {
|
void* allocate(size_t size) {
|
||||||
return _allocator.allocate(size);
|
return _allocator.allocate(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(void* ptr) {
|
void deallocate(void* ptr) {
|
||||||
if (ptr)
|
if (ptr)
|
||||||
_allocator.deallocate(ptr);
|
_allocator.deallocate(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* reallocate(void* ptr, size_t new_size) {
|
void* reallocate(void* ptr, size_t new_size) {
|
||||||
return _allocator.reallocate(ptr, new_size);
|
return _allocator.reallocate(ptr, new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAllocator& allocator() {
|
TAllocator& allocator() {
|
||||||
return _allocator;
|
return _allocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TAllocator _allocator;
|
TAllocator _allocator;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TAllocator>
|
template <typename TAllocator>
|
||||||
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
|
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
|
||||||
public:
|
public:
|
||||||
explicit BasicJsonDocument(size_t capa, TAllocator alloc = TAllocator())
|
explicit BasicJsonDocument(size_t capa, TAllocator alloc = TAllocator())
|
||||||
: AllocatorOwner<TAllocator>(alloc), JsonDocument(allocPool(capa)) {}
|
: AllocatorOwner<TAllocator>(alloc), JsonDocument(allocPool(capa)) {}
|
||||||
|
|
||||||
// Copy-constructor
|
// Copy-constructor
|
||||||
BasicJsonDocument(const BasicJsonDocument& src)
|
BasicJsonDocument(const BasicJsonDocument& src)
|
||||||
: AllocatorOwner<TAllocator>(src), JsonDocument() {
|
: AllocatorOwner<TAllocator>(src), JsonDocument() {
|
||||||
copyAssignFrom(src);
|
copyAssignFrom(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move-constructor
|
// Move-constructor
|
||||||
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
||||||
BasicJsonDocument(BasicJsonDocument&& src) : AllocatorOwner<TAllocator>(src) {
|
BasicJsonDocument(BasicJsonDocument&& src) : AllocatorOwner<TAllocator>(src) {
|
||||||
moveAssignFrom(src);
|
moveAssignFrom(src);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
BasicJsonDocument(const JsonDocument& src) {
|
BasicJsonDocument(const JsonDocument& src) {
|
||||||
copyAssignFrom(src);
|
copyAssignFrom(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct from variant, array, or object
|
// Construct from variant, array, or object
|
||||||
template <typename T>
|
template <typename T>
|
||||||
BasicJsonDocument(
|
BasicJsonDocument(
|
||||||
const T& src,
|
const T& src,
|
||||||
typename enable_if<
|
typename enable_if<
|
||||||
is_same<T, VariantRef>::value || is_same<T, VariantConstRef>::value ||
|
is_same<T, VariantRef>::value || is_same<T, VariantConstRef>::value ||
|
||||||
is_same<T, ArrayRef>::value || is_same<T, ArrayConstRef>::value ||
|
is_same<T, ArrayRef>::value || is_same<T, ArrayConstRef>::value ||
|
||||||
is_same<T, ObjectRef>::value ||
|
is_same<T, ObjectRef>::value ||
|
||||||
is_same<T, ObjectConstRef>::value>::type* = 0)
|
is_same<T, ObjectConstRef>::value>::type* = 0)
|
||||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||||
set(src);
|
set(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disambiguate
|
// disambiguate
|
||||||
BasicJsonDocument(VariantRef src)
|
BasicJsonDocument(VariantRef src)
|
||||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||||
set(src);
|
set(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
~BasicJsonDocument() {
|
~BasicJsonDocument() {
|
||||||
freePool();
|
freePool();
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicJsonDocument& operator=(const BasicJsonDocument& src) {
|
BasicJsonDocument& operator=(const BasicJsonDocument& src) {
|
||||||
copyAssignFrom(src);
|
copyAssignFrom(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
#if ARDUINOJSON_HAS_RVALUE_REFERENCES
|
||||||
BasicJsonDocument& operator=(BasicJsonDocument&& src) {
|
BasicJsonDocument& operator=(BasicJsonDocument&& src) {
|
||||||
moveAssignFrom(src);
|
moveAssignFrom(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
BasicJsonDocument& operator=(const T& src) {
|
BasicJsonDocument& operator=(const T& src) {
|
||||||
reallocPoolIfTooSmall(src.memoryUsage());
|
reallocPoolIfTooSmall(src.memoryUsage());
|
||||||
set(src);
|
set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void shrinkToFit() {
|
void shrinkToFit() {
|
||||||
ptrdiff_t bytes_reclaimed = _pool.squash();
|
ptrdiff_t bytes_reclaimed = _pool.squash();
|
||||||
if (bytes_reclaimed == 0)
|
if (bytes_reclaimed == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
void* old_ptr = _pool.buffer();
|
void* old_ptr = _pool.buffer();
|
||||||
void* new_ptr = this->reallocate(old_ptr, _pool.capacity());
|
void* new_ptr = this->reallocate(old_ptr, _pool.capacity());
|
||||||
|
|
||||||
ptrdiff_t ptr_offset =
|
ptrdiff_t ptr_offset =
|
||||||
static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr);
|
static_cast<char*>(new_ptr) - static_cast<char*>(old_ptr);
|
||||||
|
|
||||||
_pool.movePointers(ptr_offset);
|
_pool.movePointers(ptr_offset);
|
||||||
_data.movePointers(ptr_offset, ptr_offset - bytes_reclaimed);
|
_data.movePointers(ptr_offset, ptr_offset - bytes_reclaimed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool garbageCollect() {
|
bool garbageCollect() {
|
||||||
// make a temporary clone and move assign
|
// make a temporary clone and move assign
|
||||||
BasicJsonDocument tmp(*this);
|
BasicJsonDocument tmp(*this);
|
||||||
if (!tmp.capacity())
|
if (!tmp.capacity())
|
||||||
return false;
|
return false;
|
||||||
tmp.set(*this);
|
tmp.set(*this);
|
||||||
moveAssignFrom(tmp);
|
moveAssignFrom(tmp);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
using AllocatorOwner<TAllocator>::allocator;
|
using AllocatorOwner<TAllocator>::allocator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool allocPool(size_t requiredSize) {
|
MemoryPool allocPool(size_t requiredSize) {
|
||||||
size_t capa = addPadding(requiredSize);
|
size_t capa = addPadding(requiredSize);
|
||||||
return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa);
|
return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reallocPoolIfTooSmall(size_t requiredSize) {
|
void reallocPoolIfTooSmall(size_t requiredSize) {
|
||||||
if (requiredSize <= capacity())
|
if (requiredSize <= capacity())
|
||||||
return;
|
return;
|
||||||
freePool();
|
freePool();
|
||||||
replacePool(allocPool(addPadding(requiredSize)));
|
replacePool(allocPool(addPadding(requiredSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void freePool() {
|
void freePool() {
|
||||||
this->deallocate(memoryPool().buffer());
|
this->deallocate(memoryPool().buffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyAssignFrom(const JsonDocument& src) {
|
void copyAssignFrom(const JsonDocument& src) {
|
||||||
reallocPoolIfTooSmall(src.capacity());
|
reallocPoolIfTooSmall(src.capacity());
|
||||||
set(src);
|
set(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveAssignFrom(BasicJsonDocument& src) {
|
void moveAssignFrom(BasicJsonDocument& src) {
|
||||||
freePool();
|
freePool();
|
||||||
_data = src._data;
|
_data = src._data;
|
||||||
_pool = src._pool;
|
_pool = src._pool;
|
||||||
src._data.setNull();
|
src._data.setNull();
|
||||||
src._pool = MemoryPool(0, 0);
|
src._pool = MemoryPool(0, 0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Document/BasicJsonDocument.hpp>
|
#include <ArduinoJson/Document/BasicJsonDocument.hpp>
|
||||||
|
|
||||||
#include <stdlib.h> // malloc, free
|
#include <stdlib.h> // malloc, free
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
struct DefaultAllocator {
|
struct DefaultAllocator {
|
||||||
void* allocate(size_t size) {
|
void* allocate(size_t size) {
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(void* ptr) {
|
void deallocate(void* ptr) {
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* reallocate(void* ptr, size_t new_size) {
|
void* reallocate(void* ptr, size_t new_size) {
|
||||||
return realloc(ptr, new_size);
|
return realloc(ptr, new_size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument;
|
typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument;
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,328 +1,333 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Array/ElementProxy.hpp>
|
#include <ArduinoJson/Array/ElementProxy.hpp>
|
||||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
||||||
#include <ArduinoJson/Object/MemberProxy.hpp>
|
#include <ArduinoJson/Object/MemberProxy.hpp>
|
||||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class JsonDocument : public Visitable {
|
class JsonDocument : public Visitable {
|
||||||
public:
|
public:
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor& visitor) const {
|
typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
return getVariant().accept(visitor);
|
return getVariant().accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename VariantAs<T>::type as() {
|
typename VariantAs<T>::type as() {
|
||||||
return getVariant().template as<T>();
|
return getVariant().template as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename VariantConstAs<T>::type as() const {
|
typename VariantConstAs<T>::type as() const {
|
||||||
return getVariant().template as<T>();
|
return getVariant().template as<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_pool.clear();
|
_pool.clear();
|
||||||
_data.setNull();
|
_data.setNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool is() const {
|
bool is() const {
|
||||||
return getVariant().template is<T>();
|
return getVariant().template is<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNull() const {
|
bool isNull() const {
|
||||||
return getVariant().isNull();
|
return getVariant().isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t memoryUsage() const {
|
size_t memoryUsage() const {
|
||||||
return _pool.size();
|
return _pool.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t nesting() const {
|
bool overflowed() const {
|
||||||
return _data.nesting();
|
return _pool.overflowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t capacity() const {
|
size_t nesting() const {
|
||||||
return _pool.capacity();
|
return _data.nesting();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t capacity() const {
|
||||||
return _data.size();
|
return _pool.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool set(const JsonDocument& src) {
|
size_t size() const {
|
||||||
return to<VariantRef>().set(src.as<VariantRef>());
|
return _data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
bool set(const JsonDocument& src) {
|
||||||
typename enable_if<!is_base_of<JsonDocument, T>::value, bool>::type set(
|
return to<VariantRef>().set(src.as<VariantRef>());
|
||||||
const T& src) {
|
}
|
||||||
return to<VariantRef>().set(src);
|
|
||||||
}
|
template <typename T>
|
||||||
|
typename enable_if<!is_base_of<JsonDocument, T>::value, bool>::type set(
|
||||||
template <typename T>
|
const T& src) {
|
||||||
typename VariantTo<T>::type to() {
|
return to<VariantRef>().set(src);
|
||||||
clear();
|
}
|
||||||
return getVariant().template to<T>();
|
|
||||||
}
|
template <typename T>
|
||||||
|
typename VariantTo<T>::type to() {
|
||||||
// for internal use only
|
clear();
|
||||||
MemoryPool& memoryPool() {
|
return getVariant().template to<T>();
|
||||||
return _pool;
|
}
|
||||||
}
|
|
||||||
|
// for internal use only
|
||||||
VariantData& data() {
|
MemoryPool& memoryPool() {
|
||||||
return _data;
|
return _pool;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayRef createNestedArray() {
|
// for internal use only
|
||||||
return addElement().to<ArrayRef>();
|
VariantData& data() {
|
||||||
}
|
return _data;
|
||||||
|
}
|
||||||
// createNestedArray(char*)
|
|
||||||
// createNestedArray(const char*)
|
ArrayRef createNestedArray() {
|
||||||
// createNestedArray(const __FlashStringHelper*)
|
return addElement().to<ArrayRef>();
|
||||||
template <typename TChar>
|
}
|
||||||
ArrayRef createNestedArray(TChar* key) {
|
|
||||||
return getOrAddMember(key).template to<ArrayRef>();
|
// createNestedArray(char*)
|
||||||
}
|
// createNestedArray(const char*)
|
||||||
|
// createNestedArray(const __FlashStringHelper*)
|
||||||
// createNestedArray(const std::string&)
|
template <typename TChar>
|
||||||
// createNestedArray(const String&)
|
ArrayRef createNestedArray(TChar* key) {
|
||||||
template <typename TString>
|
return getOrAddMember(key).template to<ArrayRef>();
|
||||||
ArrayRef createNestedArray(const TString& key) {
|
}
|
||||||
return getOrAddMember(key).template to<ArrayRef>();
|
|
||||||
}
|
// createNestedArray(const std::string&)
|
||||||
|
// createNestedArray(const String&)
|
||||||
ObjectRef createNestedObject() {
|
template <typename TString>
|
||||||
return addElement().to<ObjectRef>();
|
ArrayRef createNestedArray(const TString& key) {
|
||||||
}
|
return getOrAddMember(key).template to<ArrayRef>();
|
||||||
|
}
|
||||||
// createNestedObject(char*)
|
|
||||||
// createNestedObject(const char*)
|
ObjectRef createNestedObject() {
|
||||||
// createNestedObject(const __FlashStringHelper*)
|
return addElement().to<ObjectRef>();
|
||||||
template <typename TChar>
|
}
|
||||||
ObjectRef createNestedObject(TChar* key) {
|
|
||||||
return getOrAddMember(key).template to<ObjectRef>();
|
// createNestedObject(char*)
|
||||||
}
|
// createNestedObject(const char*)
|
||||||
|
// createNestedObject(const __FlashStringHelper*)
|
||||||
// createNestedObject(const std::string&)
|
template <typename TChar>
|
||||||
// createNestedObject(const String&)
|
ObjectRef createNestedObject(TChar* key) {
|
||||||
template <typename TString>
|
return getOrAddMember(key).template to<ObjectRef>();
|
||||||
ObjectRef createNestedObject(const TString& key) {
|
}
|
||||||
return getOrAddMember(key).template to<ObjectRef>();
|
|
||||||
}
|
// createNestedObject(const std::string&)
|
||||||
|
// createNestedObject(const String&)
|
||||||
// containsKey(char*) const
|
template <typename TString>
|
||||||
// containsKey(const char*) const
|
ObjectRef createNestedObject(const TString& key) {
|
||||||
// containsKey(const __FlashStringHelper*) const
|
return getOrAddMember(key).template to<ObjectRef>();
|
||||||
template <typename TChar>
|
}
|
||||||
bool containsKey(TChar* key) const {
|
|
||||||
return !getMember(key).isUndefined();
|
// containsKey(char*) const
|
||||||
}
|
// containsKey(const char*) const
|
||||||
|
// containsKey(const __FlashStringHelper*) const
|
||||||
// containsKey(const std::string&) const
|
template <typename TChar>
|
||||||
// containsKey(const String&) const
|
bool containsKey(TChar* key) const {
|
||||||
template <typename TString>
|
return !getMember(key).isUndefined();
|
||||||
bool containsKey(const TString& key) const {
|
}
|
||||||
return !getMember(key).isUndefined();
|
|
||||||
}
|
// containsKey(const std::string&) const
|
||||||
|
// containsKey(const String&) const
|
||||||
// operator[](const std::string&)
|
template <typename TString>
|
||||||
// operator[](const String&)
|
bool containsKey(const TString& key) const {
|
||||||
template <typename TString>
|
return !getMember(key).isUndefined();
|
||||||
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
}
|
||||||
MemberProxy<JsonDocument&, TString> >::type
|
|
||||||
operator[](const TString& key) {
|
// operator[](const std::string&)
|
||||||
return MemberProxy<JsonDocument&, TString>(*this, key);
|
// operator[](const String&)
|
||||||
}
|
template <typename TString>
|
||||||
|
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||||
// operator[](char*)
|
MemberProxy<JsonDocument&, TString> >::type
|
||||||
// operator[](const char*)
|
operator[](const TString& key) {
|
||||||
// operator[](const __FlashStringHelper*)
|
return MemberProxy<JsonDocument&, TString>(*this, key);
|
||||||
template <typename TChar>
|
}
|
||||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value,
|
|
||||||
MemberProxy<JsonDocument&, TChar*> >::type
|
// operator[](char*)
|
||||||
operator[](TChar* key) {
|
// operator[](const char*)
|
||||||
return MemberProxy<JsonDocument&, TChar*>(*this, key);
|
// operator[](const __FlashStringHelper*)
|
||||||
}
|
template <typename TChar>
|
||||||
|
FORCE_INLINE typename enable_if<IsString<TChar*>::value,
|
||||||
// operator[](const std::string&) const
|
MemberProxy<JsonDocument&, TChar*> >::type
|
||||||
// operator[](const String&) const
|
operator[](TChar* key) {
|
||||||
template <typename TString>
|
return MemberProxy<JsonDocument&, TChar*>(*this, key);
|
||||||
FORCE_INLINE
|
}
|
||||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
|
||||||
operator[](const TString& key) const {
|
// operator[](const std::string&) const
|
||||||
return getMember(key);
|
// operator[](const String&) const
|
||||||
}
|
template <typename TString>
|
||||||
|
FORCE_INLINE
|
||||||
// operator[](char*) const
|
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||||
// operator[](const char*) const
|
operator[](const TString& key) const {
|
||||||
// operator[](const __FlashStringHelper*) const
|
return getMember(key);
|
||||||
template <typename TChar>
|
}
|
||||||
FORCE_INLINE
|
|
||||||
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
// operator[](char*) const
|
||||||
operator[](TChar* key) const {
|
// operator[](const char*) const
|
||||||
return getMember(key);
|
// operator[](const __FlashStringHelper*) const
|
||||||
}
|
template <typename TChar>
|
||||||
|
FORCE_INLINE
|
||||||
FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
|
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
||||||
return ElementProxy<JsonDocument&>(*this, index);
|
operator[](TChar* key) const {
|
||||||
}
|
return getMember(key);
|
||||||
|
}
|
||||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
|
||||||
return getElement(index);
|
FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
|
||||||
}
|
return ElementProxy<JsonDocument&>(*this, index);
|
||||||
|
}
|
||||||
FORCE_INLINE VariantRef getElement(size_t index) {
|
|
||||||
return VariantRef(&_pool, _data.getElement(index));
|
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||||
}
|
return getElement(index);
|
||||||
|
}
|
||||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
|
||||||
return VariantConstRef(_data.getElement(index));
|
FORCE_INLINE VariantRef getElement(size_t index) {
|
||||||
}
|
return VariantRef(&_pool, _data.getElement(index));
|
||||||
|
}
|
||||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) {
|
|
||||||
return VariantRef(&_pool, _data.getOrAddElement(index, &_pool));
|
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||||
}
|
return VariantConstRef(_data.getElement(index));
|
||||||
|
}
|
||||||
// JsonVariantConst getMember(char*) const
|
|
||||||
// JsonVariantConst getMember(const char*) const
|
FORCE_INLINE VariantRef getOrAddElement(size_t index) {
|
||||||
// JsonVariantConst getMember(const __FlashStringHelper*) const
|
return VariantRef(&_pool, _data.getOrAddElement(index, &_pool));
|
||||||
template <typename TChar>
|
}
|
||||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
|
||||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
// JsonVariantConst getMember(char*) const
|
||||||
}
|
// JsonVariantConst getMember(const char*) const
|
||||||
|
// JsonVariantConst getMember(const __FlashStringHelper*) const
|
||||||
// JsonVariantConst getMember(const std::string&) const
|
template <typename TChar>
|
||||||
// JsonVariantConst getMember(const String&) const
|
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||||
template <typename TString>
|
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||||
FORCE_INLINE
|
}
|
||||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
|
||||||
getMember(const TString& key) const {
|
// JsonVariantConst getMember(const std::string&) const
|
||||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
// JsonVariantConst getMember(const String&) const
|
||||||
}
|
template <typename TString>
|
||||||
|
FORCE_INLINE
|
||||||
// JsonVariant getMember(char*)
|
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||||
// JsonVariant getMember(const char*)
|
getMember(const TString& key) const {
|
||||||
// JsonVariant getMember(const __FlashStringHelper*)
|
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||||
template <typename TChar>
|
}
|
||||||
FORCE_INLINE VariantRef getMember(TChar* key) {
|
|
||||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
// JsonVariant getMember(char*)
|
||||||
}
|
// JsonVariant getMember(const char*)
|
||||||
|
// JsonVariant getMember(const __FlashStringHelper*)
|
||||||
// JsonVariant getMember(const std::string&)
|
template <typename TChar>
|
||||||
// JsonVariant getMember(const String&)
|
FORCE_INLINE VariantRef getMember(TChar* key) {
|
||||||
template <typename TString>
|
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||||
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
|
}
|
||||||
getMember(const TString& key) {
|
|
||||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
// JsonVariant getMember(const std::string&)
|
||||||
}
|
// JsonVariant getMember(const String&)
|
||||||
|
template <typename TString>
|
||||||
// getOrAddMember(char*)
|
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
|
||||||
// getOrAddMember(const char*)
|
getMember(const TString& key) {
|
||||||
// getOrAddMember(const __FlashStringHelper*)
|
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||||
template <typename TChar>
|
}
|
||||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) {
|
|
||||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
// getOrAddMember(char*)
|
||||||
}
|
// getOrAddMember(const char*)
|
||||||
|
// getOrAddMember(const __FlashStringHelper*)
|
||||||
// getOrAddMember(const std::string&)
|
template <typename TChar>
|
||||||
// getOrAddMember(const String&)
|
FORCE_INLINE VariantRef getOrAddMember(TChar* key) {
|
||||||
template <typename TString>
|
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) {
|
}
|
||||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
|
||||||
}
|
// getOrAddMember(const std::string&)
|
||||||
|
// getOrAddMember(const String&)
|
||||||
FORCE_INLINE VariantRef addElement() {
|
template <typename TString>
|
||||||
return VariantRef(&_pool, _data.addElement(&_pool));
|
FORCE_INLINE VariantRef getOrAddMember(const TString& key) {
|
||||||
}
|
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||||
|
}
|
||||||
template <typename TValue>
|
|
||||||
FORCE_INLINE bool add(const TValue& value) {
|
FORCE_INLINE VariantRef addElement() {
|
||||||
return addElement().set(value);
|
return VariantRef(&_pool, _data.addElement(&_pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
// add(char*) const
|
template <typename TValue>
|
||||||
// add(const char*) const
|
FORCE_INLINE bool add(const TValue& value) {
|
||||||
// add(const __FlashStringHelper*) const
|
return addElement().set(value);
|
||||||
template <typename TChar>
|
}
|
||||||
FORCE_INLINE bool add(TChar* value) {
|
|
||||||
return addElement().set(value);
|
// add(char*) const
|
||||||
}
|
// add(const char*) const
|
||||||
|
// add(const __FlashStringHelper*) const
|
||||||
FORCE_INLINE void remove(size_t index) {
|
template <typename TChar>
|
||||||
_data.remove(index);
|
FORCE_INLINE bool add(TChar* value) {
|
||||||
}
|
return addElement().set(value);
|
||||||
// remove(char*)
|
}
|
||||||
// remove(const char*)
|
|
||||||
// remove(const __FlashStringHelper*)
|
FORCE_INLINE void remove(size_t index) {
|
||||||
template <typename TChar>
|
_data.remove(index);
|
||||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
}
|
||||||
TChar* key) {
|
// remove(char*)
|
||||||
_data.remove(adaptString(key));
|
// remove(const char*)
|
||||||
}
|
// remove(const __FlashStringHelper*)
|
||||||
// remove(const std::string&)
|
template <typename TChar>
|
||||||
// remove(const String&)
|
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||||
template <typename TString>
|
TChar* key) {
|
||||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
_data.remove(adaptString(key));
|
||||||
const TString& key) {
|
}
|
||||||
_data.remove(adaptString(key));
|
// remove(const std::string&)
|
||||||
}
|
// remove(const String&)
|
||||||
|
template <typename TString>
|
||||||
FORCE_INLINE operator VariantConstRef() const {
|
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||||
return VariantConstRef(&_data);
|
const TString& key) {
|
||||||
}
|
_data.remove(adaptString(key));
|
||||||
|
}
|
||||||
bool operator==(VariantConstRef rhs) const {
|
|
||||||
return getVariant() == rhs;
|
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) {
|
bool operator!=(VariantConstRef rhs) const {
|
||||||
_data.setNull();
|
return getVariant() != rhs;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonDocument(MemoryPool pool) : _pool(pool) {
|
protected:
|
||||||
_data.setNull();
|
JsonDocument() : _pool(0, 0) {
|
||||||
}
|
_data.setNull();
|
||||||
|
}
|
||||||
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
|
|
||||||
_data.setNull();
|
JsonDocument(MemoryPool pool) : _pool(pool) {
|
||||||
}
|
_data.setNull();
|
||||||
|
}
|
||||||
void replacePool(MemoryPool pool) {
|
|
||||||
_pool = pool;
|
JsonDocument(char* buf, size_t capa) : _pool(buf, capa) {
|
||||||
}
|
_data.setNull();
|
||||||
|
}
|
||||||
VariantRef getVariant() {
|
|
||||||
return VariantRef(&_pool, &_data);
|
void replacePool(MemoryPool pool) {
|
||||||
}
|
_pool = pool;
|
||||||
|
}
|
||||||
VariantConstRef getVariant() const {
|
|
||||||
return VariantConstRef(&_data);
|
VariantRef getVariant() {
|
||||||
}
|
return VariantRef(&_pool, &_data);
|
||||||
|
}
|
||||||
MemoryPool _pool;
|
|
||||||
VariantData _data;
|
VariantConstRef getVariant() const {
|
||||||
|
return VariantConstRef(&_data);
|
||||||
private:
|
}
|
||||||
JsonDocument(const JsonDocument&);
|
|
||||||
JsonDocument& operator=(const JsonDocument&);
|
MemoryPool _pool;
|
||||||
};
|
VariantData _data;
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
private:
|
||||||
|
JsonDocument(const JsonDocument&);
|
||||||
|
JsonDocument& operator=(const JsonDocument&);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,56 +1,56 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Document/JsonDocument.hpp>
|
#include <ArduinoJson/Document/JsonDocument.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <size_t desiredCapacity>
|
template <size_t desiredCapacity>
|
||||||
class StaticJsonDocument : public JsonDocument {
|
class StaticJsonDocument : public JsonDocument {
|
||||||
static const size_t _capacity =
|
static const size_t _capacity =
|
||||||
AddPadding<Max<1, desiredCapacity>::value>::value;
|
AddPadding<Max<1, desiredCapacity>::value>::value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {}
|
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {}
|
||||||
|
|
||||||
StaticJsonDocument(const StaticJsonDocument& src)
|
StaticJsonDocument(const StaticJsonDocument& src)
|
||||||
: JsonDocument(_buffer, _capacity) {
|
: JsonDocument(_buffer, _capacity) {
|
||||||
set(src);
|
set(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
StaticJsonDocument(const T& src,
|
StaticJsonDocument(const T& src,
|
||||||
typename enable_if<IsVisitable<T>::value>::type* = 0)
|
typename enable_if<IsVisitable<T>::value>::type* = 0)
|
||||||
: JsonDocument(_buffer, _capacity) {
|
: JsonDocument(_buffer, _capacity) {
|
||||||
set(src);
|
set(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
// disambiguate
|
// disambiguate
|
||||||
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) {
|
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) {
|
||||||
set(src);
|
set(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticJsonDocument operator=(const StaticJsonDocument& src) {
|
StaticJsonDocument operator=(const StaticJsonDocument& src) {
|
||||||
set(src);
|
set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
StaticJsonDocument operator=(const T& src) {
|
StaticJsonDocument operator=(const T& src) {
|
||||||
set(src);
|
set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCollect() {
|
void garbageCollect() {
|
||||||
StaticJsonDocument tmp(*this);
|
StaticJsonDocument tmp(*this);
|
||||||
set(tmp);
|
set(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char _buffer[_capacity];
|
char _buffer[_capacity];
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class EscapeSequence {
|
class EscapeSequence {
|
||||||
public:
|
public:
|
||||||
// Optimized for code size on a 8-bit AVR
|
// Optimized for code size on a 8-bit AVR
|
||||||
static char escapeChar(char c) {
|
static char escapeChar(char c) {
|
||||||
const char *p = escapeTable(true);
|
const char *p = escapeTable(true);
|
||||||
while (p[0] && p[1] != c) {
|
while (p[0] && p[1] != c) {
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
return p[0];
|
return p[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Optimized for code size on a 8-bit AVR
|
// Optimized for code size on a 8-bit AVR
|
||||||
static char unescapeChar(char c) {
|
static char unescapeChar(char c) {
|
||||||
const char *p = escapeTable(false);
|
const char *p = escapeTable(false);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (p[0] == '\0')
|
if (p[0] == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
if (p[0] == c)
|
if (p[0] == c)
|
||||||
return p[1];
|
return p[1];
|
||||||
p += 2;
|
p += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const char *escapeTable(bool excludeSolidus) {
|
static const char *escapeTable(bool excludeSolidus) {
|
||||||
return &"//\"\"\\\\b\bf\fn\nr\rt\t"[excludeSolidus ? 2 : 0];
|
return &"//\"\"\\\\b\bf\fn\nr\rt\t"[excludeSolidus ? 2 : 0];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,126 +1,135 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Json/TextFormatter.hpp>
|
#include <ArduinoJson/Json/TextFormatter.hpp>
|
||||||
#include <ArduinoJson/Misc/Visitable.hpp>
|
#include <ArduinoJson/Misc/Visitable.hpp>
|
||||||
#include <ArduinoJson/Serialization/measure.hpp>
|
#include <ArduinoJson/Serialization/measure.hpp>
|
||||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TWriter>
|
template <typename TWriter>
|
||||||
class JsonSerializer {
|
class JsonSerializer : public Visitor<size_t> {
|
||||||
public:
|
public:
|
||||||
JsonSerializer(TWriter writer) : _formatter(writer) {}
|
JsonSerializer(TWriter writer) : _formatter(writer) {}
|
||||||
|
|
||||||
FORCE_INLINE void visitArray(const CollectionData &array) {
|
FORCE_INLINE size_t visitArray(const CollectionData &array) {
|
||||||
write('[');
|
write('[');
|
||||||
|
|
||||||
VariantSlot *slot = array.head();
|
VariantSlot *slot = array.head();
|
||||||
|
|
||||||
while (slot != 0) {
|
while (slot != 0) {
|
||||||
slot->data()->accept(*this);
|
slot->data()->accept(*this);
|
||||||
|
|
||||||
slot = slot->next();
|
slot = slot->next();
|
||||||
if (slot == 0)
|
if (slot == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
write(',');
|
write(',');
|
||||||
}
|
}
|
||||||
|
|
||||||
write(']');
|
write(']');
|
||||||
}
|
return bytesWritten();
|
||||||
|
}
|
||||||
void visitObject(const CollectionData &object) {
|
|
||||||
write('{');
|
size_t visitObject(const CollectionData &object) {
|
||||||
|
write('{');
|
||||||
VariantSlot *slot = object.head();
|
|
||||||
|
VariantSlot *slot = object.head();
|
||||||
while (slot != 0) {
|
|
||||||
_formatter.writeString(slot->key());
|
while (slot != 0) {
|
||||||
write(':');
|
_formatter.writeString(slot->key());
|
||||||
slot->data()->accept(*this);
|
write(':');
|
||||||
|
slot->data()->accept(*this);
|
||||||
slot = slot->next();
|
|
||||||
if (slot == 0)
|
slot = slot->next();
|
||||||
break;
|
if (slot == 0)
|
||||||
|
break;
|
||||||
write(',');
|
|
||||||
}
|
write(',');
|
||||||
|
}
|
||||||
write('}');
|
|
||||||
}
|
write('}');
|
||||||
|
return bytesWritten();
|
||||||
void visitFloat(Float value) {
|
}
|
||||||
_formatter.writeFloat(value);
|
|
||||||
}
|
size_t visitFloat(Float value) {
|
||||||
|
_formatter.writeFloat(value);
|
||||||
void visitString(const char *value) {
|
return bytesWritten();
|
||||||
_formatter.writeString(value);
|
}
|
||||||
}
|
|
||||||
|
size_t visitString(const char *value) {
|
||||||
void visitRawJson(const char *data, size_t n) {
|
_formatter.writeString(value);
|
||||||
_formatter.writeRaw(data, n);
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void visitNegativeInteger(UInt value) {
|
size_t visitRawJson(const char *data, size_t n) {
|
||||||
_formatter.writeNegativeInteger(value);
|
_formatter.writeRaw(data, n);
|
||||||
}
|
return bytesWritten();
|
||||||
|
}
|
||||||
void visitPositiveInteger(UInt value) {
|
|
||||||
_formatter.writePositiveInteger(value);
|
size_t visitNegativeInteger(UInt value) {
|
||||||
}
|
_formatter.writeNegativeInteger(value);
|
||||||
|
return bytesWritten();
|
||||||
void visitBoolean(bool value) {
|
}
|
||||||
_formatter.writeBoolean(value);
|
|
||||||
}
|
size_t visitPositiveInteger(UInt value) {
|
||||||
|
_formatter.writePositiveInteger(value);
|
||||||
void visitNull() {
|
return bytesWritten();
|
||||||
_formatter.writeRaw("null");
|
}
|
||||||
}
|
|
||||||
|
size_t visitBoolean(bool value) {
|
||||||
size_t bytesWritten() const {
|
_formatter.writeBoolean(value);
|
||||||
return _formatter.bytesWritten();
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
size_t visitNull() {
|
||||||
void write(char c) {
|
_formatter.writeRaw("null");
|
||||||
_formatter.writeRaw(c);
|
return bytesWritten();
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const char *s) {
|
protected:
|
||||||
_formatter.writeRaw(s);
|
size_t bytesWritten() const {
|
||||||
}
|
return _formatter.bytesWritten();
|
||||||
|
}
|
||||||
private:
|
|
||||||
TextFormatter<TWriter> _formatter;
|
void write(char c) {
|
||||||
};
|
_formatter.writeRaw(c);
|
||||||
|
}
|
||||||
template <typename TSource, typename TDestination>
|
|
||||||
size_t serializeJson(const TSource &source, TDestination &destination) {
|
void write(const char *s) {
|
||||||
return serialize<JsonSerializer>(source, destination);
|
_formatter.writeRaw(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TSource>
|
private:
|
||||||
size_t serializeJson(const TSource &source, void *buffer, size_t bufferSize) {
|
TextFormatter<TWriter> _formatter;
|
||||||
return serialize<JsonSerializer>(source, buffer, bufferSize);
|
};
|
||||||
}
|
|
||||||
|
template <typename TSource, typename TDestination>
|
||||||
template <typename TSource>
|
size_t serializeJson(const TSource &source, TDestination &destination) {
|
||||||
size_t measureJson(const TSource &source) {
|
return serialize<JsonSerializer>(source, destination);
|
||||||
return measure<JsonSerializer>(source);
|
}
|
||||||
}
|
|
||||||
|
template <typename TSource>
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
size_t serializeJson(const TSource &source, void *buffer, size_t bufferSize) {
|
||||||
template <typename T>
|
return serialize<JsonSerializer>(source, buffer, bufferSize);
|
||||||
inline typename enable_if<IsVisitable<T>::value, std::ostream &>::type
|
}
|
||||||
operator<<(std::ostream &os, const T &source) {
|
|
||||||
serializeJson(source, os);
|
template <typename TSource>
|
||||||
return os;
|
size_t measureJson(const TSource &source) {
|
||||||
}
|
return measure<JsonSerializer>(source);
|
||||||
#endif
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
#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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TReader>
|
template <typename TReader>
|
||||||
class Latch {
|
class Latch {
|
||||||
public:
|
public:
|
||||||
Latch(TReader reader) : _reader(reader), _loaded(false) {
|
Latch(TReader reader) : _reader(reader), _loaded(false) {
|
||||||
#if ARDUINOJSON_DEBUG
|
#if ARDUINOJSON_DEBUG
|
||||||
_ended = false;
|
_ended = false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
_loaded = false;
|
_loaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int last() const {
|
int last() const {
|
||||||
return _current;
|
return _current;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE char current() {
|
FORCE_INLINE char current() {
|
||||||
if (!_loaded) {
|
if (!_loaded) {
|
||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
return _current;
|
return _current;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void load() {
|
void load() {
|
||||||
ARDUINOJSON_ASSERT(!_ended);
|
ARDUINOJSON_ASSERT(!_ended);
|
||||||
int c = _reader.read();
|
int c = _reader.read();
|
||||||
#if ARDUINOJSON_DEBUG
|
#if ARDUINOJSON_DEBUG
|
||||||
if (c <= 0)
|
if (c <= 0)
|
||||||
_ended = true;
|
_ended = true;
|
||||||
#endif
|
#endif
|
||||||
_current = static_cast<char>(c > 0 ? c : 0);
|
_current = static_cast<char>(c > 0 ? c : 0);
|
||||||
_loaded = true;
|
_loaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
TReader _reader;
|
TReader _reader;
|
||||||
char _current;
|
char _current;
|
||||||
bool _loaded;
|
bool _loaded;
|
||||||
#if ARDUINOJSON_DEBUG
|
#if ARDUINOJSON_DEBUG
|
||||||
bool _ended;
|
bool _ended;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,85 +1,89 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Json/JsonSerializer.hpp>
|
#include <ArduinoJson/Json/JsonSerializer.hpp>
|
||||||
#include <ArduinoJson/Serialization/measure.hpp>
|
#include <ArduinoJson/Serialization/measure.hpp>
|
||||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TWriter>
|
template <typename TWriter>
|
||||||
class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
class PrettyJsonSerializer : public JsonSerializer<TWriter> {
|
||||||
typedef JsonSerializer<TWriter> base;
|
typedef JsonSerializer<TWriter> base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {}
|
PrettyJsonSerializer(TWriter &writer) : base(writer), _nesting(0) {}
|
||||||
|
|
||||||
void visitArray(const CollectionData &array) {
|
size_t visitArray(const CollectionData &array) {
|
||||||
VariantSlot *slot = array.head();
|
VariantSlot *slot = array.head();
|
||||||
if (!slot)
|
if (slot) {
|
||||||
return base::write("[]");
|
base::write("[\r\n");
|
||||||
|
_nesting++;
|
||||||
base::write("[\r\n");
|
while (slot != 0) {
|
||||||
_nesting++;
|
indent();
|
||||||
while (slot != 0) {
|
slot->data()->accept(*this);
|
||||||
indent();
|
|
||||||
slot->data()->accept(*this);
|
slot = slot->next();
|
||||||
|
base::write(slot ? ",\r\n" : "\r\n");
|
||||||
slot = slot->next();
|
}
|
||||||
base::write(slot ? ",\r\n" : "\r\n");
|
_nesting--;
|
||||||
}
|
indent();
|
||||||
_nesting--;
|
base::write("]");
|
||||||
indent();
|
} else {
|
||||||
base::write("]");
|
base::write("[]");
|
||||||
}
|
}
|
||||||
|
return this->bytesWritten();
|
||||||
void visitObject(const CollectionData &object) {
|
}
|
||||||
VariantSlot *slot = object.head();
|
|
||||||
if (!slot)
|
size_t visitObject(const CollectionData &object) {
|
||||||
return base::write("{}");
|
VariantSlot *slot = object.head();
|
||||||
|
if (slot) {
|
||||||
base::write("{\r\n");
|
base::write("{\r\n");
|
||||||
_nesting++;
|
_nesting++;
|
||||||
while (slot != 0) {
|
while (slot != 0) {
|
||||||
indent();
|
indent();
|
||||||
base::visitString(slot->key());
|
base::visitString(slot->key());
|
||||||
base::write(": ");
|
base::write(": ");
|
||||||
slot->data()->accept(*this);
|
slot->data()->accept(*this);
|
||||||
|
|
||||||
slot = slot->next();
|
slot = slot->next();
|
||||||
base::write(slot ? ",\r\n" : "\r\n");
|
base::write(slot ? ",\r\n" : "\r\n");
|
||||||
}
|
}
|
||||||
_nesting--;
|
_nesting--;
|
||||||
indent();
|
indent();
|
||||||
base::write("}");
|
base::write("}");
|
||||||
}
|
} else {
|
||||||
|
base::write("{}");
|
||||||
private:
|
}
|
||||||
void indent() {
|
return this->bytesWritten();
|
||||||
for (uint8_t i = 0; i < _nesting; i++) base::write(ARDUINOJSON_TAB);
|
}
|
||||||
}
|
|
||||||
|
private:
|
||||||
uint8_t _nesting;
|
void indent() {
|
||||||
};
|
for (uint8_t i = 0; i < _nesting; i++) base::write(ARDUINOJSON_TAB);
|
||||||
|
}
|
||||||
template <typename TSource, typename TDestination>
|
|
||||||
size_t serializeJsonPretty(const TSource &source, TDestination &destination) {
|
uint8_t _nesting;
|
||||||
return serialize<PrettyJsonSerializer>(source, destination);
|
};
|
||||||
}
|
|
||||||
|
template <typename TSource, typename TDestination>
|
||||||
template <typename TSource>
|
size_t serializeJsonPretty(const TSource &source, TDestination &destination) {
|
||||||
size_t serializeJsonPretty(const TSource &source, void *buffer,
|
return serialize<PrettyJsonSerializer>(source, destination);
|
||||||
size_t bufferSize) {
|
}
|
||||||
return serialize<PrettyJsonSerializer>(source, buffer, bufferSize);
|
|
||||||
}
|
template <typename TSource>
|
||||||
|
size_t serializeJsonPretty(const TSource &source, void *buffer,
|
||||||
template <typename TSource>
|
size_t bufferSize) {
|
||||||
size_t measureJsonPretty(const TSource &source) {
|
return serialize<PrettyJsonSerializer>(source, buffer, bufferSize);
|
||||||
return measure<PrettyJsonSerializer>(source);
|
}
|
||||||
}
|
|
||||||
|
template <typename TSource>
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
size_t measureJsonPretty(const TSource &source) {
|
||||||
|
return measure<PrettyJsonSerializer>(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,158 +1,159 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h> // for strlen
|
#include <string.h> // for strlen
|
||||||
|
|
||||||
#include <ArduinoJson/Json/EscapeSequence.hpp>
|
#include <ArduinoJson/Json/EscapeSequence.hpp>
|
||||||
#include <ArduinoJson/Numbers/FloatParts.hpp>
|
#include <ArduinoJson/Numbers/FloatParts.hpp>
|
||||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||||
|
#include <ArduinoJson/Serialization/CountingDecorator.hpp>
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
template <typename TWriter>
|
|
||||||
class TextFormatter {
|
template <typename TWriter>
|
||||||
public:
|
class TextFormatter {
|
||||||
explicit TextFormatter(TWriter writer) : _writer(writer), _length(0) {}
|
public:
|
||||||
|
explicit TextFormatter(TWriter writer) : _writer(writer) {}
|
||||||
// Returns the number of bytes sent to the TWriter implementation.
|
|
||||||
size_t bytesWritten() const {
|
// Returns the number of bytes sent to the TWriter implementation.
|
||||||
return _length;
|
size_t bytesWritten() const {
|
||||||
}
|
return _writer.count();
|
||||||
|
}
|
||||||
void writeBoolean(bool value) {
|
|
||||||
if (value)
|
void writeBoolean(bool value) {
|
||||||
writeRaw("true");
|
if (value)
|
||||||
else
|
writeRaw("true");
|
||||||
writeRaw("false");
|
else
|
||||||
}
|
writeRaw("false");
|
||||||
|
}
|
||||||
void writeString(const char *value) {
|
|
||||||
ARDUINOJSON_ASSERT(value != NULL);
|
void writeString(const char *value) {
|
||||||
writeRaw('\"');
|
ARDUINOJSON_ASSERT(value != NULL);
|
||||||
while (*value) writeChar(*value++);
|
writeRaw('\"');
|
||||||
writeRaw('\"');
|
while (*value) writeChar(*value++);
|
||||||
}
|
writeRaw('\"');
|
||||||
|
}
|
||||||
void writeChar(char c) {
|
|
||||||
char specialChar = EscapeSequence::escapeChar(c);
|
void writeChar(char c) {
|
||||||
if (specialChar) {
|
char specialChar = EscapeSequence::escapeChar(c);
|
||||||
writeRaw('\\');
|
if (specialChar) {
|
||||||
writeRaw(specialChar);
|
writeRaw('\\');
|
||||||
} else {
|
writeRaw(specialChar);
|
||||||
writeRaw(c);
|
} else {
|
||||||
}
|
writeRaw(c);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
template <typename T>
|
|
||||||
void writeFloat(T value) {
|
template <typename T>
|
||||||
if (isnan(value))
|
void writeFloat(T value) {
|
||||||
return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null");
|
if (isnan(value))
|
||||||
|
return writeRaw(ARDUINOJSON_ENABLE_NAN ? "NaN" : "null");
|
||||||
#if ARDUINOJSON_ENABLE_INFINITY
|
|
||||||
if (value < 0.0) {
|
#if ARDUINOJSON_ENABLE_INFINITY
|
||||||
writeRaw('-');
|
if (value < 0.0) {
|
||||||
value = -value;
|
writeRaw('-');
|
||||||
}
|
value = -value;
|
||||||
|
}
|
||||||
if (isinf(value))
|
|
||||||
return writeRaw("Infinity");
|
if (isinf(value))
|
||||||
#else
|
return writeRaw("Infinity");
|
||||||
if (isinf(value))
|
#else
|
||||||
return writeRaw("null");
|
if (isinf(value))
|
||||||
|
return writeRaw("null");
|
||||||
if (value < 0.0) {
|
|
||||||
writeRaw('-');
|
if (value < 0.0) {
|
||||||
value = -value;
|
writeRaw('-');
|
||||||
}
|
value = -value;
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
FloatParts<T> parts(value);
|
|
||||||
|
FloatParts<T> parts(value);
|
||||||
writePositiveInteger(parts.integral);
|
|
||||||
if (parts.decimalPlaces)
|
writePositiveInteger(parts.integral);
|
||||||
writeDecimals(parts.decimal, parts.decimalPlaces);
|
if (parts.decimalPlaces)
|
||||||
|
writeDecimals(parts.decimal, parts.decimalPlaces);
|
||||||
if (parts.exponent < 0) {
|
|
||||||
writeRaw("e-");
|
if (parts.exponent < 0) {
|
||||||
writePositiveInteger(-parts.exponent);
|
writeRaw("e-");
|
||||||
}
|
writePositiveInteger(-parts.exponent);
|
||||||
|
}
|
||||||
if (parts.exponent > 0) {
|
|
||||||
writeRaw('e');
|
if (parts.exponent > 0) {
|
||||||
writePositiveInteger(parts.exponent);
|
writeRaw('e');
|
||||||
}
|
writePositiveInteger(parts.exponent);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
void writeNegativeInteger(UInt value) {
|
|
||||||
writeRaw('-');
|
void writeNegativeInteger(UInt value) {
|
||||||
writePositiveInteger(value);
|
writeRaw('-');
|
||||||
}
|
writePositiveInteger(value);
|
||||||
|
}
|
||||||
template <typename T>
|
|
||||||
void writePositiveInteger(T value) {
|
template <typename T>
|
||||||
char buffer[22];
|
void writePositiveInteger(T value) {
|
||||||
char *end = buffer + sizeof(buffer);
|
char buffer[22];
|
||||||
char *begin = end;
|
char *end = buffer + sizeof(buffer);
|
||||||
|
char *begin = end;
|
||||||
// write the string in reverse order
|
|
||||||
do {
|
// write the string in reverse order
|
||||||
*--begin = char(value % 10 + '0');
|
do {
|
||||||
value = T(value / 10);
|
*--begin = char(value % 10 + '0');
|
||||||
} while (value);
|
value = T(value / 10);
|
||||||
|
} while (value);
|
||||||
// and dump it in the right order
|
|
||||||
writeRaw(begin, end);
|
// 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
|
void writeDecimals(uint32_t value, int8_t width) {
|
||||||
char buffer[16];
|
// buffer should be big enough for all digits and the dot
|
||||||
char *end = buffer + sizeof(buffer);
|
char buffer[16];
|
||||||
char *begin = end;
|
char *end = buffer + sizeof(buffer);
|
||||||
|
char *begin = end;
|
||||||
// write the string in reverse order
|
|
||||||
while (width--) {
|
// write the string in reverse order
|
||||||
*--begin = char(value % 10 + '0');
|
while (width--) {
|
||||||
value /= 10;
|
*--begin = char(value % 10 + '0');
|
||||||
}
|
value /= 10;
|
||||||
*--begin = '.';
|
}
|
||||||
|
*--begin = '.';
|
||||||
// and dump it in the right order
|
|
||||||
writeRaw(begin, end);
|
// 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) {
|
||||||
}
|
_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 *s, size_t n) {
|
||||||
}
|
_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),
|
void writeRaw(const char *begin, const char *end) {
|
||||||
static_cast<size_t>(end - begin));
|
_writer.write(reinterpret_cast<const uint8_t *>(begin),
|
||||||
}
|
static_cast<size_t>(end - begin));
|
||||||
|
}
|
||||||
template <size_t N>
|
|
||||||
void writeRaw(const char (&s)[N]) {
|
template <size_t N>
|
||||||
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1);
|
void writeRaw(const char (&s)[N]) {
|
||||||
}
|
_writer.write(reinterpret_cast<const uint8_t *>(s), N - 1);
|
||||||
void writeRaw(char c) {
|
}
|
||||||
_length += _writer.write(static_cast<uint8_t>(c));
|
void writeRaw(char c) {
|
||||||
}
|
_writer.write(static_cast<uint8_t>(c));
|
||||||
|
}
|
||||||
protected:
|
|
||||||
TWriter _writer;
|
protected:
|
||||||
size_t _length;
|
CountingDecorator<TWriter> _writer;
|
||||||
|
size_t _length;
|
||||||
private:
|
|
||||||
TextFormatter &operator=(const TextFormatter &); // cannot be assigned
|
private:
|
||||||
};
|
TextFormatter &operator=(const TextFormatter &); // cannot be assigned
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,67 +1,67 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
#include <stdint.h> // uint16_t, uint32_t
|
#include <stdint.h> // uint16_t, uint32_t
|
||||||
|
|
||||||
// The high surrogate may be uninitialized if the pair is invalid,
|
// The high surrogate may be uninitialized if the pair is invalid,
|
||||||
// we choose to ignore the problem to reduce the size of the code
|
// we choose to ignore the problem to reduce the size of the code
|
||||||
// Garbage in => Garbage out
|
// Garbage in => Garbage out
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if __GNUC__ >= 7
|
#if __GNUC__ >= 7
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
namespace Utf16 {
|
namespace Utf16 {
|
||||||
inline bool isHighSurrogate(uint16_t codeunit) {
|
inline bool isHighSurrogate(uint16_t codeunit) {
|
||||||
return codeunit >= 0xD800 && codeunit < 0xDC00;
|
return codeunit >= 0xD800 && codeunit < 0xDC00;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool isLowSurrogate(uint16_t codeunit) {
|
inline bool isLowSurrogate(uint16_t codeunit) {
|
||||||
return codeunit >= 0xDC00 && codeunit < 0xE000;
|
return codeunit >= 0xDC00 && codeunit < 0xE000;
|
||||||
}
|
}
|
||||||
|
|
||||||
class Codepoint {
|
class Codepoint {
|
||||||
public:
|
public:
|
||||||
Codepoint() : _highSurrogate(0) {}
|
Codepoint() : _highSurrogate(0) {}
|
||||||
|
|
||||||
bool append(uint16_t codeunit) {
|
bool append(uint16_t codeunit) {
|
||||||
if (isHighSurrogate(codeunit)) {
|
if (isHighSurrogate(codeunit)) {
|
||||||
_highSurrogate = codeunit & 0x3FF;
|
_highSurrogate = codeunit & 0x3FF;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLowSurrogate(codeunit)) {
|
if (isLowSurrogate(codeunit)) {
|
||||||
_codepoint =
|
_codepoint =
|
||||||
uint32_t(0x10000 + ((_highSurrogate << 10) | (codeunit & 0x3FF)));
|
uint32_t(0x10000 + ((_highSurrogate << 10) | (codeunit & 0x3FF)));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_codepoint = codeunit;
|
_codepoint = codeunit;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t value() const {
|
uint32_t value() const {
|
||||||
return _codepoint;
|
return _codepoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint16_t _highSurrogate;
|
uint16_t _highSurrogate;
|
||||||
uint32_t _codepoint;
|
uint32_t _codepoint;
|
||||||
};
|
};
|
||||||
} // namespace Utf16
|
} // namespace Utf16
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
#if __GNUC__ >= 8
|
#if __GNUC__ >= 8
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,46 +1,46 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
namespace Utf8 {
|
namespace Utf8 {
|
||||||
template <typename TStringBuilder>
|
template <typename TStringBuilder>
|
||||||
inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) {
|
inline void encodeCodepoint(uint32_t codepoint32, TStringBuilder& str) {
|
||||||
// this function was optimize for code size on AVR
|
// this function was optimize for code size on AVR
|
||||||
|
|
||||||
// a buffer to store the string in reverse
|
// a buffer to store the string in reverse
|
||||||
char buf[5];
|
char buf[5];
|
||||||
char* p = buf;
|
char* p = buf;
|
||||||
|
|
||||||
*(p++) = 0;
|
*(p++) = 0;
|
||||||
if (codepoint32 < 0x80) {
|
if (codepoint32 < 0x80) {
|
||||||
*(p++) = char((codepoint32));
|
*(p++) = char((codepoint32));
|
||||||
} else {
|
} else {
|
||||||
*(p++) = char((codepoint32 | 0x80) & 0xBF);
|
*(p++) = char((codepoint32 | 0x80) & 0xBF);
|
||||||
uint16_t codepoint16 = uint16_t(codepoint32 >> 6);
|
uint16_t codepoint16 = uint16_t(codepoint32 >> 6);
|
||||||
if (codepoint16 < 0x20) { // 0x800
|
if (codepoint16 < 0x20) { // 0x800
|
||||||
*(p++) = char(codepoint16 | 0xC0);
|
*(p++) = char(codepoint16 | 0xC0);
|
||||||
} else {
|
} else {
|
||||||
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
||||||
codepoint16 = uint16_t(codepoint16 >> 6);
|
codepoint16 = uint16_t(codepoint16 >> 6);
|
||||||
if (codepoint16 < 0x10) { // 0x10000
|
if (codepoint16 < 0x10) { // 0x10000
|
||||||
*(p++) = char(codepoint16 | 0xE0);
|
*(p++) = char(codepoint16 | 0xE0);
|
||||||
} else {
|
} else {
|
||||||
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
*(p++) = char((codepoint16 | 0x80) & 0xBF);
|
||||||
codepoint16 = uint16_t(codepoint16 >> 6);
|
codepoint16 = uint16_t(codepoint16 >> 6);
|
||||||
*(p++) = char(codepoint16 | 0xF0);
|
*(p++) = char(codepoint16 | 0xF0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*(--p)) {
|
while (*(--p)) {
|
||||||
str.append(*p);
|
str.append(*p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace Utf8
|
} // namespace Utf8
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,60 +1,60 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
#include <stddef.h> // size_t
|
#include <stddef.h> // size_t
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ALIGNMENT
|
#if ARDUINOJSON_ENABLE_ALIGNMENT
|
||||||
|
|
||||||
inline bool isAligned(size_t value) {
|
inline bool isAligned(size_t value) {
|
||||||
const size_t mask = sizeof(void *) - 1;
|
const size_t mask = sizeof(void *) - 1;
|
||||||
size_t addr = value;
|
size_t addr = value;
|
||||||
return (addr & mask) == 0;
|
return (addr & mask) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t addPadding(size_t bytes) {
|
inline size_t addPadding(size_t bytes) {
|
||||||
const size_t mask = sizeof(void *) - 1;
|
const size_t mask = sizeof(void *) - 1;
|
||||||
return (bytes + mask) & ~mask;
|
return (bytes + mask) & ~mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t bytes>
|
template <size_t bytes>
|
||||||
struct AddPadding {
|
struct AddPadding {
|
||||||
static const size_t mask = sizeof(void *) - 1;
|
static const size_t mask = sizeof(void *) - 1;
|
||||||
static const size_t value = (bytes + mask) & ~mask;
|
static const size_t value = (bytes + mask) & ~mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
inline bool isAligned(size_t) {
|
inline bool isAligned(size_t) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t addPadding(size_t bytes) {
|
inline size_t addPadding(size_t bytes) {
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t bytes>
|
template <size_t bytes>
|
||||||
struct AddPadding {
|
struct AddPadding {
|
||||||
static const size_t value = bytes;
|
static const size_t value = bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline bool isAligned(T *ptr) {
|
inline bool isAligned(T *ptr) {
|
||||||
return isAligned(reinterpret_cast<size_t>(ptr));
|
return isAligned(reinterpret_cast<size_t>(ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T *addPadding(T *p) {
|
inline T *addPadding(T *p) {
|
||||||
size_t address = addPadding(reinterpret_cast<size_t>(p));
|
size_t address = addPadding(reinterpret_cast<size_t>(p));
|
||||||
return reinterpret_cast<T *>(address);
|
return reinterpret_cast<T *>(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,200 +1,212 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/Alignment.hpp>
|
#include <ArduinoJson/Memory/Alignment.hpp>
|
||||||
#include <ArduinoJson/Memory/StringSlot.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/mpl/max.hpp>
|
||||||
#include <ArduinoJson/Polyfills/mpl/max.hpp>
|
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantSlot.hpp>
|
|
||||||
|
#include <string.h> // memmove
|
||||||
#include <string.h> // memmove
|
|
||||||
|
#define JSON_STRING_SIZE(SIZE) (SIZE + 1)
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
// _begin _end
|
|
||||||
// v v
|
// _begin _end
|
||||||
// +-------------+--------------+--------------+
|
// v v
|
||||||
// | strings... | (free) | ...variants |
|
// +-------------+--------------+--------------+
|
||||||
// +-------------+--------------+--------------+
|
// | strings... | (free) | ...variants |
|
||||||
// ^ ^
|
// +-------------+--------------+--------------+
|
||||||
// _left _right
|
// ^ ^
|
||||||
|
// _left _right
|
||||||
class MemoryPool {
|
|
||||||
public:
|
class MemoryPool {
|
||||||
MemoryPool(char* buf, size_t capa)
|
public:
|
||||||
: _begin(buf),
|
MemoryPool(char* buf, size_t capa)
|
||||||
_left(buf),
|
: _begin(buf),
|
||||||
_right(buf ? buf + capa : 0),
|
_left(buf),
|
||||||
_end(buf ? buf + capa : 0) {
|
_right(buf ? buf + capa : 0),
|
||||||
ARDUINOJSON_ASSERT(isAligned(_begin));
|
_end(buf ? buf + capa : 0),
|
||||||
ARDUINOJSON_ASSERT(isAligned(_right));
|
_overflowed(false) {
|
||||||
ARDUINOJSON_ASSERT(isAligned(_end));
|
ARDUINOJSON_ASSERT(isAligned(_begin));
|
||||||
}
|
ARDUINOJSON_ASSERT(isAligned(_right));
|
||||||
|
ARDUINOJSON_ASSERT(isAligned(_end));
|
||||||
void* buffer() {
|
}
|
||||||
return _begin;
|
|
||||||
}
|
void* buffer() {
|
||||||
|
return _begin;
|
||||||
// Gets the capacity of the memoryPool in bytes
|
}
|
||||||
size_t capacity() const {
|
|
||||||
return size_t(_end - _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);
|
|
||||||
}
|
size_t size() const {
|
||||||
|
return size_t(_left - _begin + _end - _right);
|
||||||
VariantSlot* allocVariant() {
|
}
|
||||||
return allocRight<VariantSlot>();
|
|
||||||
}
|
bool overflowed() const {
|
||||||
|
return _overflowed;
|
||||||
template <typename TAdaptedString>
|
}
|
||||||
const char* saveString(const TAdaptedString& str) {
|
|
||||||
if (str.isNull())
|
VariantSlot* allocVariant() {
|
||||||
return 0;
|
return allocRight<VariantSlot>();
|
||||||
|
}
|
||||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
|
||||||
const char* existingCopy = findString(str.begin());
|
template <typename TAdaptedString>
|
||||||
if (existingCopy)
|
const char* saveString(const TAdaptedString& str) {
|
||||||
return existingCopy;
|
if (str.isNull())
|
||||||
#endif
|
return 0;
|
||||||
|
|
||||||
size_t n = str.size();
|
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||||
|
const char* existingCopy = findString(str.begin());
|
||||||
char* newCopy = allocString(n + 1);
|
if (existingCopy)
|
||||||
if (newCopy) {
|
return existingCopy;
|
||||||
str.copyTo(newCopy, n);
|
#endif
|
||||||
newCopy[n] = 0; // force null-terminator
|
|
||||||
}
|
size_t n = str.size();
|
||||||
return newCopy;
|
|
||||||
}
|
char* newCopy = allocString(n + 1);
|
||||||
|
if (newCopy) {
|
||||||
void getFreeZone(char** zoneStart, size_t* zoneSize) const {
|
str.copyTo(newCopy, n);
|
||||||
*zoneStart = _left;
|
newCopy[n] = 0; // force null-terminator
|
||||||
*zoneSize = size_t(_right - _left);
|
}
|
||||||
}
|
return newCopy;
|
||||||
|
}
|
||||||
const char* saveStringFromFreeZone(size_t len) {
|
|
||||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
void getFreeZone(char** zoneStart, size_t* zoneSize) const {
|
||||||
const char* dup = findString(_left);
|
*zoneStart = _left;
|
||||||
if (dup)
|
*zoneSize = size_t(_right - _left);
|
||||||
return dup;
|
}
|
||||||
#endif
|
|
||||||
|
const char* saveStringFromFreeZone(size_t len) {
|
||||||
const char* str = _left;
|
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||||
_left += len;
|
const char* dup = findString(_left);
|
||||||
checkInvariants();
|
if (dup)
|
||||||
return str;
|
return dup;
|
||||||
}
|
#endif
|
||||||
|
|
||||||
void clear() {
|
const char* str = _left;
|
||||||
_left = _begin;
|
_left += len;
|
||||||
_right = _end;
|
checkInvariants();
|
||||||
}
|
return str;
|
||||||
|
}
|
||||||
bool canAlloc(size_t bytes) const {
|
|
||||||
return _left + bytes <= _right;
|
void markAsOverflowed() {
|
||||||
}
|
_overflowed = true;
|
||||||
|
}
|
||||||
bool owns(void* p) const {
|
|
||||||
return _begin <= p && p < _end;
|
void clear() {
|
||||||
}
|
_left = _begin;
|
||||||
|
_right = _end;
|
||||||
// Workaround for missing placement new
|
_overflowed = false;
|
||||||
void* operator new(size_t, void* p) {
|
}
|
||||||
return p;
|
|
||||||
}
|
bool canAlloc(size_t bytes) const {
|
||||||
|
return _left + bytes <= _right;
|
||||||
// Squash the free space between strings and variants
|
}
|
||||||
//
|
|
||||||
// _begin _end
|
bool owns(void* p) const {
|
||||||
// v v
|
return _begin <= p && p < _end;
|
||||||
// +-------------+--------------+
|
}
|
||||||
// | strings... | ...variants |
|
|
||||||
// +-------------+--------------+
|
// Workaround for missing placement new
|
||||||
// ^
|
void* operator new(size_t, void* p) {
|
||||||
// _left _right
|
return p;
|
||||||
//
|
}
|
||||||
// This funcion is called before a realloc.
|
|
||||||
ptrdiff_t squash() {
|
// Squash the free space between strings and variants
|
||||||
char* new_right = addPadding(_left);
|
//
|
||||||
if (new_right >= _right)
|
// _begin _end
|
||||||
return 0;
|
// v v
|
||||||
|
// +-------------+--------------+
|
||||||
size_t right_size = static_cast<size_t>(_end - _right);
|
// | strings... | ...variants |
|
||||||
memmove(new_right, _right, right_size);
|
// +-------------+--------------+
|
||||||
|
// ^
|
||||||
ptrdiff_t bytes_reclaimed = _right - new_right;
|
// _left _right
|
||||||
_right = new_right;
|
//
|
||||||
_end = new_right + right_size;
|
// This funcion is called before a realloc.
|
||||||
return bytes_reclaimed;
|
ptrdiff_t squash() {
|
||||||
}
|
char* new_right = addPadding(_left);
|
||||||
|
if (new_right >= _right)
|
||||||
// Move all pointers together
|
return 0;
|
||||||
// This funcion is called after a realloc.
|
|
||||||
void movePointers(ptrdiff_t offset) {
|
size_t right_size = static_cast<size_t>(_end - _right);
|
||||||
_begin += offset;
|
memmove(new_right, _right, right_size);
|
||||||
_left += offset;
|
|
||||||
_right += offset;
|
ptrdiff_t bytes_reclaimed = _right - new_right;
|
||||||
_end += offset;
|
_right = new_right;
|
||||||
}
|
_end = new_right + right_size;
|
||||||
|
return bytes_reclaimed;
|
||||||
private:
|
}
|
||||||
StringSlot* allocStringSlot() {
|
|
||||||
return allocRight<StringSlot>();
|
// Move all pointers together
|
||||||
}
|
// This funcion is called after a realloc.
|
||||||
|
void movePointers(ptrdiff_t offset) {
|
||||||
void checkInvariants() {
|
_begin += offset;
|
||||||
ARDUINOJSON_ASSERT(_begin <= _left);
|
_left += offset;
|
||||||
ARDUINOJSON_ASSERT(_left <= _right);
|
_right += offset;
|
||||||
ARDUINOJSON_ASSERT(_right <= _end);
|
_end += offset;
|
||||||
ARDUINOJSON_ASSERT(isAligned(_right));
|
}
|
||||||
}
|
|
||||||
|
private:
|
||||||
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
void checkInvariants() {
|
||||||
template <typename TIterator>
|
ARDUINOJSON_ASSERT(_begin <= _left);
|
||||||
const char* findString(TIterator str) {
|
ARDUINOJSON_ASSERT(_left <= _right);
|
||||||
for (char* next = _begin; next < _left; ++next) {
|
ARDUINOJSON_ASSERT(_right <= _end);
|
||||||
char* begin = next;
|
ARDUINOJSON_ASSERT(isAligned(_right));
|
||||||
|
}
|
||||||
// try to match
|
|
||||||
for (TIterator it = str; *it == *next; ++it) {
|
#if ARDUINOJSON_ENABLE_STRING_DEDUPLICATION
|
||||||
if (*next++ == 0)
|
template <typename TIterator>
|
||||||
return begin;
|
const char* findString(TIterator str) {
|
||||||
}
|
for (char* next = _begin; next < _left; ++next) {
|
||||||
|
char* begin = next;
|
||||||
// jump to next terminator
|
|
||||||
while (*next) ++next;
|
// try to match
|
||||||
}
|
for (TIterator it = str; *it == *next; ++it) {
|
||||||
return 0;
|
if (*next++ == 0)
|
||||||
}
|
return begin;
|
||||||
#endif
|
}
|
||||||
|
|
||||||
char* allocString(size_t n) {
|
// jump to next terminator
|
||||||
if (!canAlloc(n))
|
while (*next) ++next;
|
||||||
return 0;
|
}
|
||||||
char* s = _left;
|
return 0;
|
||||||
_left += n;
|
}
|
||||||
checkInvariants();
|
#endif
|
||||||
return s;
|
|
||||||
}
|
char* allocString(size_t n) {
|
||||||
|
if (!canAlloc(n)) {
|
||||||
template <typename T>
|
_overflowed = true;
|
||||||
T* allocRight() {
|
return 0;
|
||||||
return reinterpret_cast<T*>(allocRight(sizeof(T)));
|
}
|
||||||
}
|
char* s = _left;
|
||||||
|
_left += n;
|
||||||
void* allocRight(size_t bytes) {
|
checkInvariants();
|
||||||
if (!canAlloc(bytes))
|
return s;
|
||||||
return 0;
|
}
|
||||||
_right -= bytes;
|
|
||||||
return _right;
|
template <typename T>
|
||||||
}
|
T* allocRight() {
|
||||||
|
return reinterpret_cast<T*>(allocRight(sizeof(T)));
|
||||||
char *_begin, *_left, *_right, *_end;
|
}
|
||||||
};
|
|
||||||
|
void* allocRight(size_t bytes) {
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
if (!canAlloc(bytes)) {
|
||||||
|
_overflowed = true;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
_right -= bytes;
|
||||||
|
return _right;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *_begin, *_left, *_right, *_end;
|
||||||
|
bool _overflowed;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
// 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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// A special type of data that can be used to insert pregenerated JSON portions.
|
// A special type of data that can be used to insert pregenerated JSON portions.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class SerializedValue {
|
class SerializedValue {
|
||||||
public:
|
public:
|
||||||
explicit SerializedValue(T str) : _str(str) {}
|
explicit SerializedValue(T str) : _str(str) {}
|
||||||
operator T() const {
|
operator T() const {
|
||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* data() const {
|
const char* data() const {
|
||||||
return _str.c_str();
|
return _str.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
// CAUTION: the old Arduino String doesn't have size()
|
// CAUTION: the old Arduino String doesn't have size()
|
||||||
return _str.length();
|
return _str.length();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T _str;
|
T _str;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
class SerializedValue<TChar*> {
|
class SerializedValue<TChar*> {
|
||||||
public:
|
public:
|
||||||
explicit SerializedValue(TChar* p, size_t n) : _data(p), _size(n) {}
|
explicit SerializedValue(TChar* p, size_t n) : _data(p), _size(n) {}
|
||||||
operator TChar*() const {
|
operator TChar*() const {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
TChar* data() const {
|
TChar* data() const {
|
||||||
return _data;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
return _size;
|
return _size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TChar* _data;
|
TChar* _data;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline SerializedValue<T> serialized(T str) {
|
inline SerializedValue<T> serialized(T str) {
|
||||||
return SerializedValue<T>(str);
|
return SerializedValue<T>(str);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
inline SerializedValue<TChar*> serialized(TChar* p) {
|
inline SerializedValue<TChar*> serialized(TChar* p) {
|
||||||
return SerializedValue<TChar*>(p, adaptString(p).size());
|
return SerializedValue<TChar*>(p, adaptString(p).size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
inline SerializedValue<TChar*> serialized(TChar* p, size_t n) {
|
inline SerializedValue<TChar*> serialized(TChar* p, size_t n) {
|
||||||
return SerializedValue<TChar*>(p, n);
|
return SerializedValue<TChar*>(p, n);
|
||||||
}
|
}
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
struct Visitable {
|
template <typename TResult>
|
||||||
// template<Visitor>
|
struct Visitor {
|
||||||
// void accept(Visitor&) const;
|
typedef TResult result_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
struct Visitable {
|
||||||
struct IsVisitable : is_base_of<Visitable, T> {};
|
// template<Visitor>
|
||||||
|
// void accept(Visitor&) const;
|
||||||
template <typename T>
|
};
|
||||||
struct IsVisitable<T&> : IsVisitable<T> {};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
template <typename T>
|
||||||
|
struct IsVisitable : is_base_of<Visitable, T> {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsVisitable<T&> : IsVisitable<T> {};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,193 +1,203 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/MsgPack/endianess.hpp>
|
#include <ArduinoJson/MsgPack/endianess.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Serialization/measure.hpp>
|
#include <ArduinoJson/Serialization/CountingDecorator.hpp>
|
||||||
#include <ArduinoJson/Serialization/serialize.hpp>
|
#include <ArduinoJson/Serialization/measure.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Serialization/serialize.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
template <typename TWriter>
|
|
||||||
class MsgPackSerializer {
|
template <typename TWriter>
|
||||||
public:
|
class MsgPackSerializer : public Visitor<size_t> {
|
||||||
MsgPackSerializer(TWriter writer) : _writer(writer), _bytesWritten(0) {}
|
public:
|
||||||
|
MsgPackSerializer(TWriter writer) : _writer(writer) {}
|
||||||
template <typename T>
|
|
||||||
typename enable_if<sizeof(T) == 4>::type visitFloat(T value32) {
|
template <typename T>
|
||||||
writeByte(0xCA);
|
typename enable_if<sizeof(T) == 4, size_t>::type visitFloat(T value32) {
|
||||||
writeInteger(value32);
|
writeByte(0xCA);
|
||||||
}
|
writeInteger(value32);
|
||||||
|
return bytesWritten();
|
||||||
template <typename T>
|
}
|
||||||
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
|
||||||
typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) {
|
template <typename T>
|
||||||
float value32 = float(value64);
|
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
||||||
if (value32 == value64) {
|
typename enable_if<sizeof(T) == 8, size_t>::type visitFloat(T value64) {
|
||||||
writeByte(0xCA);
|
float value32 = float(value64);
|
||||||
writeInteger(value32);
|
if (value32 == value64) {
|
||||||
} else {
|
writeByte(0xCA);
|
||||||
writeByte(0xCB);
|
writeInteger(value32);
|
||||||
writeInteger(value64);
|
} else {
|
||||||
}
|
writeByte(0xCB);
|
||||||
}
|
writeInteger(value64);
|
||||||
|
}
|
||||||
void visitArray(const CollectionData& array) {
|
return bytesWritten();
|
||||||
size_t n = array.size();
|
}
|
||||||
if (n < 0x10) {
|
|
||||||
writeByte(uint8_t(0x90 + array.size()));
|
size_t visitArray(const CollectionData& array) {
|
||||||
} else if (n < 0x10000) {
|
size_t n = array.size();
|
||||||
writeByte(0xDC);
|
if (n < 0x10) {
|
||||||
writeInteger(uint16_t(n));
|
writeByte(uint8_t(0x90 + array.size()));
|
||||||
} else {
|
} else if (n < 0x10000) {
|
||||||
writeByte(0xDD);
|
writeByte(0xDC);
|
||||||
writeInteger(uint32_t(n));
|
writeInteger(uint16_t(n));
|
||||||
}
|
} else {
|
||||||
for (VariantSlot* slot = array.head(); slot; slot = slot->next()) {
|
writeByte(0xDD);
|
||||||
slot->data()->accept(*this);
|
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();
|
return bytesWritten();
|
||||||
if (n < 0x10) {
|
}
|
||||||
writeByte(uint8_t(0x80 + n));
|
|
||||||
} else if (n < 0x10000) {
|
size_t visitObject(const CollectionData& object) {
|
||||||
writeByte(0xDE);
|
size_t n = object.size();
|
||||||
writeInteger(uint16_t(n));
|
if (n < 0x10) {
|
||||||
} else {
|
writeByte(uint8_t(0x80 + n));
|
||||||
writeByte(0xDF);
|
} else if (n < 0x10000) {
|
||||||
writeInteger(uint32_t(n));
|
writeByte(0xDE);
|
||||||
}
|
writeInteger(uint16_t(n));
|
||||||
for (VariantSlot* slot = object.head(); slot; slot = slot->next()) {
|
} else {
|
||||||
visitString(slot->key());
|
writeByte(0xDF);
|
||||||
slot->data()->accept(*this);
|
writeInteger(uint32_t(n));
|
||||||
}
|
}
|
||||||
}
|
for (VariantSlot* slot = object.head(); slot; slot = slot->next()) {
|
||||||
|
visitString(slot->key());
|
||||||
void visitString(const char* value) {
|
slot->data()->accept(*this);
|
||||||
ARDUINOJSON_ASSERT(value != NULL);
|
}
|
||||||
|
return bytesWritten();
|
||||||
size_t n = strlen(value);
|
}
|
||||||
|
|
||||||
if (n < 0x20) {
|
size_t visitString(const char* value) {
|
||||||
writeByte(uint8_t(0xA0 + n));
|
ARDUINOJSON_ASSERT(value != NULL);
|
||||||
} else if (n < 0x100) {
|
|
||||||
writeByte(0xD9);
|
size_t n = strlen(value);
|
||||||
writeInteger(uint8_t(n));
|
|
||||||
} else if (n < 0x10000) {
|
if (n < 0x20) {
|
||||||
writeByte(0xDA);
|
writeByte(uint8_t(0xA0 + n));
|
||||||
writeInteger(uint16_t(n));
|
} else if (n < 0x100) {
|
||||||
} else {
|
writeByte(0xD9);
|
||||||
writeByte(0xDB);
|
writeInteger(uint8_t(n));
|
||||||
writeInteger(uint32_t(n));
|
} else if (n < 0x10000) {
|
||||||
}
|
writeByte(0xDA);
|
||||||
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
writeInteger(uint16_t(n));
|
||||||
}
|
} else {
|
||||||
|
writeByte(0xDB);
|
||||||
void visitRawJson(const char* data, size_t size) {
|
writeInteger(uint32_t(n));
|
||||||
writeBytes(reinterpret_cast<const uint8_t*>(data), size);
|
}
|
||||||
}
|
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
||||||
|
return bytesWritten();
|
||||||
void visitNegativeInteger(UInt value) {
|
}
|
||||||
UInt negated = UInt(~value + 1);
|
|
||||||
if (value <= 0x20) {
|
size_t visitRawJson(const char* data, size_t size) {
|
||||||
writeInteger(int8_t(negated));
|
writeBytes(reinterpret_cast<const uint8_t*>(data), size);
|
||||||
} else if (value <= 0x80) {
|
return bytesWritten();
|
||||||
writeByte(0xD0);
|
}
|
||||||
writeInteger(int8_t(negated));
|
|
||||||
} else if (value <= 0x8000) {
|
size_t visitNegativeInteger(UInt value) {
|
||||||
writeByte(0xD1);
|
UInt negated = UInt(~value + 1);
|
||||||
writeInteger(int16_t(negated));
|
if (value <= 0x20) {
|
||||||
} else if (value <= 0x80000000) {
|
writeInteger(int8_t(negated));
|
||||||
writeByte(0xD2);
|
} else if (value <= 0x80) {
|
||||||
writeInteger(int32_t(negated));
|
writeByte(0xD0);
|
||||||
}
|
writeInteger(int8_t(negated));
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
} else if (value <= 0x8000) {
|
||||||
else {
|
writeByte(0xD1);
|
||||||
writeByte(0xD3);
|
writeInteger(int16_t(negated));
|
||||||
writeInteger(int64_t(negated));
|
} else if (value <= 0x80000000) {
|
||||||
}
|
writeByte(0xD2);
|
||||||
#endif
|
writeInteger(int32_t(negated));
|
||||||
}
|
}
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
void visitPositiveInteger(UInt value) {
|
else {
|
||||||
if (value <= 0x7F) {
|
writeByte(0xD3);
|
||||||
writeInteger(uint8_t(value));
|
writeInteger(int64_t(negated));
|
||||||
} else if (value <= 0xFF) {
|
}
|
||||||
writeByte(0xCC);
|
#endif
|
||||||
writeInteger(uint8_t(value));
|
return bytesWritten();
|
||||||
} else if (value <= 0xFFFF) {
|
}
|
||||||
writeByte(0xCD);
|
|
||||||
writeInteger(uint16_t(value));
|
size_t visitPositiveInteger(UInt value) {
|
||||||
}
|
if (value <= 0x7F) {
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
writeInteger(uint8_t(value));
|
||||||
else if (value <= 0xFFFFFFFF)
|
} else if (value <= 0xFF) {
|
||||||
#else
|
writeByte(0xCC);
|
||||||
else
|
writeInteger(uint8_t(value));
|
||||||
#endif
|
} else if (value <= 0xFFFF) {
|
||||||
{
|
writeByte(0xCD);
|
||||||
writeByte(0xCE);
|
writeInteger(uint16_t(value));
|
||||||
writeInteger(uint32_t(value));
|
}
|
||||||
}
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
else if (value <= 0xFFFFFFFF)
|
||||||
else {
|
#else
|
||||||
writeByte(0xCF);
|
else
|
||||||
writeInteger(uint64_t(value));
|
#endif
|
||||||
}
|
{
|
||||||
#endif
|
writeByte(0xCE);
|
||||||
}
|
writeInteger(uint32_t(value));
|
||||||
|
}
|
||||||
void visitBoolean(bool value) {
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
writeByte(value ? 0xC3 : 0xC2);
|
else {
|
||||||
}
|
writeByte(0xCF);
|
||||||
|
writeInteger(uint64_t(value));
|
||||||
void visitNull() {
|
}
|
||||||
writeByte(0xC0);
|
#endif
|
||||||
}
|
return bytesWritten();
|
||||||
|
}
|
||||||
size_t bytesWritten() const {
|
|
||||||
return _bytesWritten;
|
size_t visitBoolean(bool value) {
|
||||||
}
|
writeByte(value ? 0xC3 : 0xC2);
|
||||||
|
return bytesWritten();
|
||||||
private:
|
}
|
||||||
void writeByte(uint8_t c) {
|
|
||||||
_bytesWritten += _writer.write(c);
|
size_t visitNull() {
|
||||||
}
|
writeByte(0xC0);
|
||||||
|
return bytesWritten();
|
||||||
void writeBytes(const uint8_t* p, size_t n) {
|
}
|
||||||
_bytesWritten += _writer.write(p, n);
|
|
||||||
}
|
private:
|
||||||
|
size_t bytesWritten() const {
|
||||||
template <typename T>
|
return _writer.count();
|
||||||
void writeInteger(T value) {
|
}
|
||||||
fixEndianess(value);
|
|
||||||
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
void writeByte(uint8_t c) {
|
||||||
}
|
_writer.write(c);
|
||||||
|
}
|
||||||
TWriter _writer;
|
|
||||||
size_t _bytesWritten;
|
void writeBytes(const uint8_t* p, size_t n) {
|
||||||
};
|
_writer.write(p, n);
|
||||||
|
}
|
||||||
template <typename TSource, typename TDestination>
|
|
||||||
inline size_t serializeMsgPack(const TSource& source, TDestination& output) {
|
template <typename T>
|
||||||
return serialize<MsgPackSerializer>(source, output);
|
void writeInteger(T value) {
|
||||||
}
|
fixEndianess(value);
|
||||||
|
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
||||||
template <typename TSource>
|
}
|
||||||
inline size_t serializeMsgPack(const TSource& source, void* output,
|
|
||||||
size_t size) {
|
CountingDecorator<TWriter> _writer;
|
||||||
return serialize<MsgPackSerializer>(source, output, size);
|
};
|
||||||
}
|
|
||||||
|
template <typename TSource, typename TDestination>
|
||||||
template <typename TSource>
|
inline size_t serializeMsgPack(const TSource& source, TDestination& output) {
|
||||||
inline size_t measureMsgPack(const TSource& source) {
|
return serialize<MsgPackSerializer>(source, output);
|
||||||
return measure<MsgPackSerializer>(source);
|
}
|
||||||
}
|
|
||||||
|
template <typename TSource>
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Polyfills/utility.hpp>
|
#include <ArduinoJson/Polyfills/utility.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
#if ARDUINOJSON_LITTLE_ENDIAN
|
#if ARDUINOJSON_LITTLE_ENDIAN
|
||||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) {
|
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) {
|
||||||
swap(p[0], p[7]);
|
swap(p[0], p[7]);
|
||||||
swap(p[1], p[6]);
|
swap(p[1], p[6]);
|
||||||
swap(p[2], p[5]);
|
swap(p[2], p[5]);
|
||||||
swap(p[3], p[4]);
|
swap(p[3], p[4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) {
|
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) {
|
||||||
swap(p[0], p[3]);
|
swap(p[0], p[3]);
|
||||||
swap(p[1], p[2]);
|
swap(p[1], p[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) {
|
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) {
|
||||||
swap(p[0], p[1]);
|
swap(p[0], p[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {}
|
inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void fixEndianess(T &value) {
|
inline void fixEndianess(T &value) {
|
||||||
fixEndianess(reinterpret_cast<uint8_t *>(&value),
|
fixEndianess(reinterpret_cast<uint8_t *>(&value),
|
||||||
integral_constant<size_t, sizeof(T)>());
|
integral_constant<size_t, sizeof(T)>());
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void fixEndianess(T &) {}
|
inline void fixEndianess(T &) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
inline void doubleToFloat(const uint8_t d[8], uint8_t f[4]) {
|
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[0] = uint8_t((d[0] & 0xC0) | (d[0] << 3 & 0x3f) | (d[1] >> 5));
|
||||||
f[1] = uint8_t((d[1] << 3) | (d[2] >> 5));
|
f[1] = uint8_t((d[1] << 3) | (d[2] >> 5));
|
||||||
f[2] = uint8_t((d[2] << 3) | (d[3] >> 5));
|
f[2] = uint8_t((d[2] << 3) | (d[3] >> 5));
|
||||||
f[3] = uint8_t((d[3] << 3) | (d[4] >> 5));
|
f[3] = uint8_t((d[3] << 3) | (d[4] >> 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,49 +1,26 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/version.hpp>
|
#include <ArduinoJson/Polyfills/preprocessor.hpp>
|
||||||
|
#include <ArduinoJson/version.hpp>
|
||||||
#ifndef ARDUINOJSON_NAMESPACE
|
|
||||||
|
#ifndef ARDUINOJSON_NAMESPACE
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0000() 0
|
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0001() 1
|
#define ARDUINOJSON_NAMESPACE \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0010() 2
|
ARDUINOJSON_CONCAT4( \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0011() 3
|
ARDUINOJSON_CONCAT4(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0100() 4
|
ARDUINOJSON_VERSION_MINOR, \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0101() 5
|
ARDUINOJSON_VERSION_REVISION), \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0110() 6
|
_, \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_0111() 7
|
ARDUINOJSON_HEX_DIGIT(ARDUINOJSON_ENABLE_PROGMEM, \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_1000() 8
|
ARDUINOJSON_USE_LONG_LONG, ARDUINOJSON_USE_DOUBLE, \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_1001() 9
|
ARDUINOJSON_ENABLE_STRING_DEDUPLICATION), \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_1010() A
|
ARDUINOJSON_HEX_DIGIT( \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_1011() B
|
ARDUINOJSON_ENABLE_NAN, ARDUINOJSON_ENABLE_INFINITY, \
|
||||||
#define ARDUINOJSON_HEX_DIGIT_1100() C
|
ARDUINOJSON_ENABLE_COMMENTS, ARDUINOJSON_DECODE_UNICODE))
|
||||||
#define ARDUINOJSON_HEX_DIGIT_1101() D
|
|
||||||
#define ARDUINOJSON_HEX_DIGIT_1110() E
|
#endif
|
||||||
#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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
typedef double Float;
|
typedef double Float;
|
||||||
#else
|
#else
|
||||||
typedef float Float;
|
typedef float Float;
|
||||||
#endif
|
#endif
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,87 +1,87 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||||
#include <ArduinoJson/Polyfills/math.hpp>
|
#include <ArduinoJson/Polyfills/math.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TFloat>
|
template <typename TFloat>
|
||||||
struct FloatParts {
|
struct FloatParts {
|
||||||
uint32_t integral;
|
uint32_t integral;
|
||||||
uint32_t decimal;
|
uint32_t decimal;
|
||||||
int16_t exponent;
|
int16_t exponent;
|
||||||
int8_t decimalPlaces;
|
int8_t decimalPlaces;
|
||||||
|
|
||||||
FloatParts(TFloat value) {
|
FloatParts(TFloat value) {
|
||||||
uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000;
|
uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000;
|
||||||
decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6;
|
decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6;
|
||||||
|
|
||||||
exponent = normalize(value);
|
exponent = normalize(value);
|
||||||
|
|
||||||
integral = uint32_t(value);
|
integral = uint32_t(value);
|
||||||
// reduce number of decimal places by the number of integral places
|
// reduce number of decimal places by the number of integral places
|
||||||
for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
|
for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
|
||||||
maxDecimalPart /= 10;
|
maxDecimalPart /= 10;
|
||||||
decimalPlaces--;
|
decimalPlaces--;
|
||||||
}
|
}
|
||||||
|
|
||||||
TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart);
|
TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart);
|
||||||
|
|
||||||
decimal = uint32_t(remainder);
|
decimal = uint32_t(remainder);
|
||||||
remainder = remainder - TFloat(decimal);
|
remainder = remainder - TFloat(decimal);
|
||||||
|
|
||||||
// rounding:
|
// rounding:
|
||||||
// increment by 1 if remainder >= 0.5
|
// increment by 1 if remainder >= 0.5
|
||||||
decimal += uint32_t(remainder * 2);
|
decimal += uint32_t(remainder * 2);
|
||||||
if (decimal >= maxDecimalPart) {
|
if (decimal >= maxDecimalPart) {
|
||||||
decimal = 0;
|
decimal = 0;
|
||||||
integral++;
|
integral++;
|
||||||
if (exponent && integral >= 10) {
|
if (exponent && integral >= 10) {
|
||||||
exponent++;
|
exponent++;
|
||||||
integral = 1;
|
integral = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove trailing zeros
|
// remove trailing zeros
|
||||||
while (decimal % 10 == 0 && decimalPlaces > 0) {
|
while (decimal % 10 == 0 && decimalPlaces > 0) {
|
||||||
decimal /= 10;
|
decimal /= 10;
|
||||||
decimalPlaces--;
|
decimalPlaces--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int16_t normalize(TFloat& value) {
|
static int16_t normalize(TFloat& value) {
|
||||||
typedef FloatTraits<TFloat> traits;
|
typedef FloatTraits<TFloat> traits;
|
||||||
int16_t powersOf10 = 0;
|
int16_t powersOf10 = 0;
|
||||||
|
|
||||||
int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
|
int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
|
||||||
int bit = 1 << index;
|
int bit = 1 << index;
|
||||||
|
|
||||||
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
|
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
|
||||||
for (; index >= 0; index--) {
|
for (; index >= 0; index--) {
|
||||||
if (value >= traits::positiveBinaryPowerOfTen(index)) {
|
if (value >= traits::positiveBinaryPowerOfTen(index)) {
|
||||||
value *= traits::negativeBinaryPowerOfTen(index);
|
value *= traits::negativeBinaryPowerOfTen(index);
|
||||||
powersOf10 = int16_t(powersOf10 + bit);
|
powersOf10 = int16_t(powersOf10 + bit);
|
||||||
}
|
}
|
||||||
bit >>= 1;
|
bit >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
|
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
|
||||||
for (; index >= 0; index--) {
|
for (; index >= 0; index--) {
|
||||||
if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
|
if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
|
||||||
value *= traits::positiveBinaryPowerOfTen(index);
|
value *= traits::positiveBinaryPowerOfTen(index);
|
||||||
powersOf10 = int16_t(powersOf10 - bit);
|
powersOf10 = int16_t(powersOf10 - bit);
|
||||||
}
|
}
|
||||||
bit >>= 1;
|
bit >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return powersOf10;
|
return powersOf10;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,181 +1,201 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h> // for size_t
|
#include <stddef.h> // for size_t
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Polyfills/alias_cast.hpp>
|
#include <ArduinoJson/Polyfills/alias_cast.hpp>
|
||||||
#include <ArduinoJson/Polyfills/math.hpp>
|
#include <ArduinoJson/Polyfills/math.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/preprocessor.hpp>
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
#include <ArduinoJson/Polyfills/static_array.hpp>
|
||||||
|
|
||||||
template <typename T, size_t = sizeof(T)>
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
struct FloatTraits {};
|
|
||||||
|
template <typename T, size_t = sizeof(T)>
|
||||||
template <typename T>
|
struct FloatTraits {};
|
||||||
struct FloatTraits<T, 8 /*64bits*/> {
|
|
||||||
typedef uint64_t mantissa_type;
|
template <typename T>
|
||||||
static const short mantissa_bits = 52;
|
struct FloatTraits<T, 8 /*64bits*/> {
|
||||||
static const mantissa_type mantissa_max =
|
typedef uint64_t mantissa_type;
|
||||||
(mantissa_type(1) << mantissa_bits) - 1;
|
static const short mantissa_bits = 52;
|
||||||
|
static const mantissa_type mantissa_max =
|
||||||
typedef int16_t exponent_type;
|
(mantissa_type(1) << mantissa_bits) - 1;
|
||||||
static const exponent_type exponent_max = 308;
|
|
||||||
|
typedef int16_t exponent_type;
|
||||||
template <typename TExponent>
|
static const exponent_type exponent_max = 308;
|
||||||
static T make_float(T m, TExponent e) {
|
|
||||||
if (e > 0) {
|
template <typename TExponent>
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
static T make_float(T m, TExponent e) {
|
||||||
if (e & 1)
|
if (e > 0) {
|
||||||
m *= positiveBinaryPowerOfTen(index);
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
e >>= 1;
|
if (e & 1)
|
||||||
}
|
m *= positiveBinaryPowerOfTen(index);
|
||||||
} else {
|
e >>= 1;
|
||||||
e = TExponent(-e);
|
}
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
} else {
|
||||||
if (e & 1)
|
e = TExponent(-e);
|
||||||
m *= negativeBinaryPowerOfTen(index);
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
e >>= 1;
|
if (e & 1)
|
||||||
}
|
m *= negativeBinaryPowerOfTen(index);
|
||||||
}
|
e >>= 1;
|
||||||
return m;
|
}
|
||||||
}
|
}
|
||||||
|
return m;
|
||||||
static T positiveBinaryPowerOfTen(int index) {
|
}
|
||||||
static T factors[] = {
|
|
||||||
1e1,
|
static T positiveBinaryPowerOfTen(int index) {
|
||||||
1e2,
|
ARDUINOJSON_DEFINE_STATIC_ARRAY( //
|
||||||
1e4,
|
uint32_t, factors,
|
||||||
1e8,
|
ARDUINOJSON_EXPAND18({
|
||||||
1e16,
|
0x40240000, 0x00000000, // 1e1
|
||||||
forge(0x4693B8B5, 0xB5056E17), // 1e32
|
0x40590000, 0x00000000, // 1e2
|
||||||
forge(0x4D384F03, 0xE93FF9F5), // 1e64
|
0x40C38800, 0x00000000, // 1e4
|
||||||
forge(0x5A827748, 0xF9301D32), // 1e128
|
0x4197D784, 0x00000000, // 1e8
|
||||||
forge(0x75154FDD, 0x7F73BF3C) // 1e256
|
0x4341C379, 0x37E08000, // 1e16
|
||||||
};
|
0x4693B8B5, 0xB5056E17, // 1e32
|
||||||
return factors[index];
|
0x4D384F03, 0xE93FF9F5, // 1e64
|
||||||
}
|
0x5A827748, 0xF9301D32, // 1e128
|
||||||
|
0x75154FDD, 0x7F73BF3C // 1e256
|
||||||
static T negativeBinaryPowerOfTen(int index) {
|
}));
|
||||||
static T factors[] = {
|
return forge(
|
||||||
forge(0x3FB99999, 0x9999999A), // 1e-1
|
ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
|
||||||
forge(0x3F847AE1, 0x47AE147B), // 1e-2
|
ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
|
||||||
forge(0x3F1A36E2, 0xEB1C432D), // 1e-4
|
}
|
||||||
forge(0x3E45798E, 0xE2308C3A), // 1e-8
|
|
||||||
forge(0x3C9CD2B2, 0x97D889BC), // 1e-16
|
static T negativeBinaryPowerOfTen(int index) {
|
||||||
forge(0x3949F623, 0xD5A8A733), // 1e-32
|
ARDUINOJSON_DEFINE_STATIC_ARRAY( //
|
||||||
forge(0x32A50FFD, 0x44F4A73D), // 1e-64
|
uint32_t, factors,
|
||||||
forge(0x255BBA08, 0xCF8C979D), // 1e-128
|
ARDUINOJSON_EXPAND18({
|
||||||
forge(0x0AC80628, 0x64AC6F43) // 1e-256
|
0x3FB99999, 0x9999999A, // 1e-1
|
||||||
};
|
0x3F847AE1, 0x47AE147B, // 1e-2
|
||||||
return factors[index];
|
0x3F1A36E2, 0xEB1C432D, // 1e-4
|
||||||
}
|
0x3E45798E, 0xE2308C3A, // 1e-8
|
||||||
|
0x3C9CD2B2, 0x97D889BC, // 1e-16
|
||||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
0x3949F623, 0xD5A8A733, // 1e-32
|
||||||
static T factors[] = {
|
0x32A50FFD, 0x44F4A73D, // 1e-64
|
||||||
1e0,
|
0x255BBA08, 0xCF8C979D, // 1e-128
|
||||||
forge(0x3FB99999, 0x9999999A), // 1e-1
|
0x0AC80628, 0x64AC6F43 // 1e-256
|
||||||
forge(0x3F50624D, 0xD2F1A9FC), // 1e-3
|
}));
|
||||||
forge(0x3E7AD7F2, 0x9ABCAF48), // 1e-7
|
return forge(
|
||||||
forge(0x3CD203AF, 0x9EE75616), // 1e-15
|
ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
|
||||||
forge(0x398039D6, 0x65896880), // 1e-31
|
ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
|
||||||
forge(0x32DA53FC, 0x9631D10D), // 1e-63
|
}
|
||||||
forge(0x25915445, 0x81B7DEC2), // 1e-127
|
|
||||||
forge(0x0AFE07B2, 0x7DD78B14) // 1e-255
|
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
||||||
};
|
ARDUINOJSON_DEFINE_STATIC_ARRAY( //
|
||||||
return factors[index];
|
uint32_t, factors,
|
||||||
}
|
ARDUINOJSON_EXPAND18({
|
||||||
|
0x3FF00000, 0x00000000, // 1e0
|
||||||
static T nan() {
|
0x3FB99999, 0x9999999A, // 1e-1
|
||||||
return forge(0x7ff80000, 0x00000000);
|
0x3F50624D, 0xD2F1A9FC, // 1e-3
|
||||||
}
|
0x3E7AD7F2, 0x9ABCAF48, // 1e-7
|
||||||
|
0x3CD203AF, 0x9EE75616, // 1e-15
|
||||||
static T inf() {
|
0x398039D6, 0x65896880, // 1e-31
|
||||||
return forge(0x7ff00000, 0x00000000);
|
0x32DA53FC, 0x9631D10D, // 1e-63
|
||||||
}
|
0x25915445, 0x81B7DEC2, // 1e-127
|
||||||
|
0x0AFE07B2, 0x7DD78B14 // 1e-255
|
||||||
static T highest() {
|
}));
|
||||||
return forge(0x7FEFFFFF, 0xFFFFFFFF);
|
return forge(
|
||||||
}
|
ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index),
|
||||||
|
ARDUINOJSON_READ_STATIC_ARRAY(uint32_t, factors, 2 * index + 1));
|
||||||
static T lowest() {
|
}
|
||||||
return forge(0xFFEFFFFF, 0xFFFFFFFF);
|
|
||||||
}
|
static T nan() {
|
||||||
|
return forge(0x7ff80000, 0x00000000);
|
||||||
// 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 inf() {
|
||||||
static T forge(uint32_t msb, uint32_t lsb) {
|
return forge(0x7ff00000, 0x00000000);
|
||||||
return alias_cast<T>((uint64_t(msb) << 32) | lsb);
|
}
|
||||||
}
|
|
||||||
};
|
static T highest() {
|
||||||
|
return forge(0x7FEFFFFF, 0xFFFFFFFF);
|
||||||
template <typename T>
|
}
|
||||||
struct FloatTraits<T, 4 /*32bits*/> {
|
|
||||||
typedef uint32_t mantissa_type;
|
static T lowest() {
|
||||||
static const short mantissa_bits = 23;
|
return forge(0xFFEFFFFF, 0xFFFFFFFF);
|
||||||
static const mantissa_type mantissa_max =
|
}
|
||||||
(mantissa_type(1) << mantissa_bits) - 1;
|
|
||||||
|
// constructs a double floating point values from its binary representation
|
||||||
typedef int8_t exponent_type;
|
// we use this function to workaround platforms with single precision literals
|
||||||
static const exponent_type exponent_max = 38;
|
// (for example, when -fsingle-precision-constant is passed to GCC)
|
||||||
|
static T forge(uint32_t msb, uint32_t lsb) {
|
||||||
template <typename TExponent>
|
return alias_cast<T>((uint64_t(msb) << 32) | lsb);
|
||||||
static T make_float(T m, TExponent e) {
|
}
|
||||||
if (e > 0) {
|
};
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
|
||||||
if (e & 1)
|
template <typename T>
|
||||||
m *= positiveBinaryPowerOfTen(index);
|
struct FloatTraits<T, 4 /*32bits*/> {
|
||||||
e >>= 1;
|
typedef uint32_t mantissa_type;
|
||||||
}
|
static const short mantissa_bits = 23;
|
||||||
} else {
|
static const mantissa_type mantissa_max =
|
||||||
e = -e;
|
(mantissa_type(1) << mantissa_bits) - 1;
|
||||||
for (uint8_t index = 0; e != 0; index++) {
|
|
||||||
if (e & 1)
|
typedef int8_t exponent_type;
|
||||||
m *= negativeBinaryPowerOfTen(index);
|
static const exponent_type exponent_max = 38;
|
||||||
e >>= 1;
|
|
||||||
}
|
template <typename TExponent>
|
||||||
}
|
static T make_float(T m, TExponent e) {
|
||||||
return m;
|
if (e > 0) {
|
||||||
}
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
|
if (e & 1)
|
||||||
static T positiveBinaryPowerOfTen(int index) {
|
m *= positiveBinaryPowerOfTen(index);
|
||||||
static T factors[] = {1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f};
|
e >>= 1;
|
||||||
return factors[index];
|
}
|
||||||
}
|
} else {
|
||||||
|
e = -e;
|
||||||
static T negativeBinaryPowerOfTen(int index) {
|
for (uint8_t index = 0; e != 0; index++) {
|
||||||
static T factors[] = {1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f};
|
if (e & 1)
|
||||||
return factors[index];
|
m *= negativeBinaryPowerOfTen(index);
|
||||||
}
|
e >>= 1;
|
||||||
|
}
|
||||||
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
}
|
||||||
static T factors[] = {1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f};
|
return m;
|
||||||
return factors[index];
|
}
|
||||||
}
|
|
||||||
|
static T positiveBinaryPowerOfTen(int index) {
|
||||||
static T forge(uint32_t bits) {
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(
|
||||||
return alias_cast<T>(bits);
|
T, factors,
|
||||||
}
|
ARDUINOJSON_EXPAND6({1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f}));
|
||||||
|
return ARDUINOJSON_READ_STATIC_ARRAY(T, factors, index);
|
||||||
static T nan() {
|
}
|
||||||
return forge(0x7fc00000);
|
|
||||||
}
|
static T negativeBinaryPowerOfTen(int index) {
|
||||||
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(
|
||||||
static T inf() {
|
T, factors,
|
||||||
return forge(0x7f800000);
|
ARDUINOJSON_EXPAND6({1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f}));
|
||||||
}
|
return ARDUINOJSON_READ_STATIC_ARRAY(T, factors, index);
|
||||||
|
}
|
||||||
static T highest() {
|
|
||||||
return forge(0x7f7fffff);
|
static T negativeBinaryPowerOfTenPlusOne(int index) {
|
||||||
}
|
ARDUINOJSON_DEFINE_STATIC_ARRAY(
|
||||||
|
T, factors,
|
||||||
static T lowest() {
|
ARDUINOJSON_EXPAND6({1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f}));
|
||||||
return forge(0xFf7fffff);
|
return ARDUINOJSON_READ_STATIC_ARRAY(T, factors, index);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
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
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
#include <stdint.h> // int64_t
|
#include <stdint.h> // int64_t
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
typedef int64_t Integer;
|
typedef int64_t Integer;
|
||||||
typedef uint64_t UInt;
|
typedef uint64_t UInt;
|
||||||
#else
|
#else
|
||||||
typedef long Integer;
|
typedef long Integer;
|
||||||
typedef unsigned long UInt;
|
typedef unsigned long UInt;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
#if ARDUINOJSON_HAS_LONG_LONG && !ARDUINOJSON_USE_LONG_LONG
|
#if ARDUINOJSON_HAS_LONG_LONG && !ARDUINOJSON_USE_LONG_LONG
|
||||||
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
|
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T) \
|
||||||
static_assert(sizeof(T) <= sizeof(ARDUINOJSON_NAMESPACE::Integer), \
|
static_assert(sizeof(T) <= sizeof(ARDUINOJSON_NAMESPACE::Integer), \
|
||||||
"To use 64-bit integers with ArduinoJson, you must set " \
|
"To use 64-bit integers with ArduinoJson, you must set " \
|
||||||
"ARDUINOJSON_USE_LONG_LONG to 1. See " \
|
"ARDUINOJSON_USE_LONG_LONG to 1. See " \
|
||||||
"https://arduinojson.org/v6/api/config/use_long_long/");
|
"https://arduinojson.org/v6/api/config/use_long_long/");
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T)
|
#define ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,121 +1,121 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
enum CompareResult {
|
enum CompareResult {
|
||||||
COMPARE_RESULT_DIFFER = 0,
|
COMPARE_RESULT_DIFFER = 0,
|
||||||
COMPARE_RESULT_EQUAL = 1,
|
COMPARE_RESULT_EQUAL = 1,
|
||||||
COMPARE_RESULT_GREATER = 2,
|
COMPARE_RESULT_GREATER = 2,
|
||||||
COMPARE_RESULT_LESS = 4,
|
COMPARE_RESULT_LESS = 4,
|
||||||
|
|
||||||
COMPARE_RESULT_GREATER_OR_EQUAL = 3,
|
COMPARE_RESULT_GREATER_OR_EQUAL = 3,
|
||||||
COMPARE_RESULT_LESS_OR_EQUAL = 5
|
COMPARE_RESULT_LESS_OR_EQUAL = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
CompareResult arithmeticCompare(const T &lhs, const T &rhs) {
|
CompareResult arithmeticCompare(const T &lhs, const T &rhs) {
|
||||||
if (lhs < rhs)
|
if (lhs < rhs)
|
||||||
return COMPARE_RESULT_LESS;
|
return COMPARE_RESULT_LESS;
|
||||||
else if (lhs > rhs)
|
else if (lhs > rhs)
|
||||||
return COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
else
|
else
|
||||||
return COMPARE_RESULT_EQUAL;
|
return COMPARE_RESULT_EQUAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
CompareResult arithmeticCompare(
|
CompareResult arithmeticCompare(
|
||||||
const T1 &lhs, const T2 &rhs,
|
const T1 &lhs, const T2 &rhs,
|
||||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||||
sizeof(T1) < sizeof(T2),
|
sizeof(T1) < sizeof(T2),
|
||||||
int // Using int instead of void to avoid C2572 on
|
int // Using int instead of void to avoid C2572 on
|
||||||
// Visual Studio 2012, 2013, and 2015
|
// Visual Studio 2012, 2013, and 2015
|
||||||
>::type * = 0) {
|
>::type * = 0) {
|
||||||
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
CompareResult arithmeticCompare(
|
CompareResult arithmeticCompare(
|
||||||
const T1 &lhs, const T2 &rhs,
|
const T1 &lhs, const T2 &rhs,
|
||||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||||
sizeof(T2) < sizeof(T1)>::type * = 0) {
|
sizeof(T2) < sizeof(T1)>::type * = 0) {
|
||||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
CompareResult arithmeticCompare(
|
CompareResult arithmeticCompare(
|
||||||
const T1 &lhs, const T2 &rhs,
|
const T1 &lhs, const T2 &rhs,
|
||||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||||
is_signed<T1>::value == is_signed<T2>::value &&
|
is_signed<T1>::value == is_signed<T2>::value &&
|
||||||
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
||||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
CompareResult arithmeticCompare(
|
CompareResult arithmeticCompare(
|
||||||
const T1 &lhs, const T2 &rhs,
|
const T1 &lhs, const T2 &rhs,
|
||||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||||
is_unsigned<T1>::value && is_signed<T2>::value &&
|
is_unsigned<T1>::value && is_signed<T2>::value &&
|
||||||
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
||||||
if (rhs < 0)
|
if (rhs < 0)
|
||||||
return COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
return arithmeticCompare<T1>(lhs, static_cast<T1>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
CompareResult arithmeticCompare(
|
CompareResult arithmeticCompare(
|
||||||
const T1 &lhs, const T2 &rhs,
|
const T1 &lhs, const T2 &rhs,
|
||||||
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
typename enable_if<is_integral<T1>::value && is_integral<T2>::value &&
|
||||||
is_signed<T1>::value && is_unsigned<T2>::value &&
|
is_signed<T1>::value && is_unsigned<T2>::value &&
|
||||||
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
sizeof(T2) == sizeof(T1)>::type * = 0) {
|
||||||
if (lhs < 0)
|
if (lhs < 0)
|
||||||
return COMPARE_RESULT_LESS;
|
return COMPARE_RESULT_LESS;
|
||||||
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
return arithmeticCompare<T2>(static_cast<T2>(lhs), rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
CompareResult arithmeticCompare(
|
CompareResult arithmeticCompare(
|
||||||
const T1 &lhs, const T2 &rhs,
|
const T1 &lhs, const T2 &rhs,
|
||||||
typename enable_if<is_floating_point<T1>::value ||
|
typename enable_if<is_floating_point<T1>::value ||
|
||||||
is_floating_point<T2>::value>::type * = 0) {
|
is_floating_point<T2>::value>::type * = 0) {
|
||||||
return arithmeticCompare<double>(static_cast<double>(lhs),
|
return arithmeticCompare<double>(static_cast<double>(lhs),
|
||||||
static_cast<double>(rhs));
|
static_cast<double>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T2>
|
template <typename T2>
|
||||||
CompareResult arithmeticCompareNegateLeft(
|
CompareResult arithmeticCompareNegateLeft(
|
||||||
UInt, const T2 &, typename enable_if<is_unsigned<T2>::value>::type * = 0) {
|
UInt, const T2 &, typename enable_if<is_unsigned<T2>::value>::type * = 0) {
|
||||||
return COMPARE_RESULT_LESS;
|
return COMPARE_RESULT_LESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T2>
|
template <typename T2>
|
||||||
CompareResult arithmeticCompareNegateLeft(
|
CompareResult arithmeticCompareNegateLeft(
|
||||||
UInt lhs, const T2 &rhs,
|
UInt lhs, const T2 &rhs,
|
||||||
typename enable_if<is_signed<T2>::value>::type * = 0) {
|
typename enable_if<is_signed<T2>::value>::type * = 0) {
|
||||||
if (rhs > 0)
|
if (rhs > 0)
|
||||||
return COMPARE_RESULT_LESS;
|
return COMPARE_RESULT_LESS;
|
||||||
return arithmeticCompare(-rhs, static_cast<T2>(lhs));
|
return arithmeticCompare(-rhs, static_cast<T2>(lhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
CompareResult arithmeticCompareNegateRight(
|
CompareResult arithmeticCompareNegateRight(
|
||||||
const T1 &, UInt, typename enable_if<is_unsigned<T1>::value>::type * = 0) {
|
const T1 &, UInt, typename enable_if<is_unsigned<T1>::value>::type * = 0) {
|
||||||
return COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T1>
|
template <typename T1>
|
||||||
CompareResult arithmeticCompareNegateRight(
|
CompareResult arithmeticCompareNegateRight(
|
||||||
const T1 &lhs, UInt rhs,
|
const T1 &lhs, UInt rhs,
|
||||||
typename enable_if<is_signed<T1>::value>::type * = 0) {
|
typename enable_if<is_signed<T1>::value>::type * = 0) {
|
||||||
if (lhs > 0)
|
if (lhs > 0)
|
||||||
return COMPARE_RESULT_GREATER;
|
return COMPARE_RESULT_GREATER;
|
||||||
return arithmeticCompare(static_cast<T1>(rhs), -lhs);
|
return arithmeticCompare(static_cast<T1>(rhs), -lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,105 +1,105 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic push
|
#pragma clang diagnostic push
|
||||||
#pragma clang diagnostic ignored "-Wconversion"
|
#pragma clang diagnostic ignored "-Wconversion"
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#endif
|
#endif
|
||||||
#pragma GCC diagnostic ignored "-Wconversion"
|
#pragma GCC diagnostic ignored "-Wconversion"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ArduinoJson/Numbers/Float.hpp>
|
#include <ArduinoJson/Numbers/Float.hpp>
|
||||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||||
#include <ArduinoJson/Numbers/Integer.hpp>
|
#include <ArduinoJson/Numbers/Integer.hpp>
|
||||||
#include <ArduinoJson/Polyfills/limits.hpp>
|
#include <ArduinoJson/Polyfills/limits.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
|
typename enable_if<is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
|
||||||
bool>::type
|
bool>::type
|
||||||
canStorePositiveInteger(TIn value) {
|
canStorePositiveInteger(TIn value) {
|
||||||
return value <= TIn(numeric_limits<TOut>::highest());
|
return value <= TIn(numeric_limits<TOut>::highest());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
|
typename enable_if<is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
|
||||||
bool>::type
|
bool>::type
|
||||||
canStorePositiveInteger(TIn) {
|
canStorePositiveInteger(TIn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||||
canStorePositiveInteger(TIn) {
|
canStorePositiveInteger(TIn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||||
canStoreNegativeInteger(TIn) {
|
canStoreNegativeInteger(TIn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||||
sizeof(TOut) <= sizeof(TIn),
|
sizeof(TOut) <= sizeof(TIn),
|
||||||
bool>::type
|
bool>::type
|
||||||
canStoreNegativeInteger(TIn value) {
|
canStoreNegativeInteger(TIn value) {
|
||||||
return value <= TIn(numeric_limits<TOut>::highest()) + 1;
|
return value <= TIn(numeric_limits<TOut>::highest()) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||||
sizeof(TIn) < sizeof(TOut),
|
sizeof(TIn) < sizeof(TOut),
|
||||||
bool>::type
|
bool>::type
|
||||||
canStoreNegativeInteger(TIn) {
|
canStoreNegativeInteger(TIn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value,
|
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value,
|
||||||
bool>::type
|
bool>::type
|
||||||
canStoreNegativeInteger(TIn) {
|
canStoreNegativeInteger(TIn) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
TOut convertPositiveInteger(TIn value) {
|
TOut convertPositiveInteger(TIn value) {
|
||||||
return canStorePositiveInteger<TOut>(value) ? TOut(value) : 0;
|
return canStorePositiveInteger<TOut>(value) ? TOut(value) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
TOut convertNegativeInteger(TIn value) {
|
TOut convertNegativeInteger(TIn value) {
|
||||||
return canStoreNegativeInteger<TOut>(value) ? TOut(~value + 1) : 0;
|
return canStoreNegativeInteger<TOut>(value) ? TOut(~value + 1) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<is_floating_point<TOut>::value, TOut>::type convertFloat(
|
typename enable_if<is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||||
TIn value) {
|
TIn value) {
|
||||||
return TOut(value);
|
return TOut(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TOut, typename TIn>
|
template <typename TOut, typename TIn>
|
||||||
typename enable_if<!is_floating_point<TOut>::value, TOut>::type convertFloat(
|
typename enable_if<!is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||||
TIn value) {
|
TIn value) {
|
||||||
return value >= numeric_limits<TOut>::lowest() &&
|
return value >= numeric_limits<TOut>::lowest() &&
|
||||||
value <= numeric_limits<TOut>::highest()
|
value <= numeric_limits<TOut>::highest()
|
||||||
? TOut(value)
|
? TOut(value)
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
// 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,21 +0,0 @@
|
|||||||
// 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,177 +1,147 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
#include <ArduinoJson/Numbers/FloatTraits.hpp>
|
||||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Polyfills/ctype.hpp>
|
#include <ArduinoJson/Polyfills/ctype.hpp>
|
||||||
#include <ArduinoJson/Polyfills/math.hpp>
|
#include <ArduinoJson/Polyfills/math.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantContent.hpp>
|
#include <ArduinoJson/Variant/VariantAs.hpp>
|
||||||
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
template <typename TFloat, typename TUInt>
|
|
||||||
struct ParsedNumber {
|
template <typename A, typename B>
|
||||||
ParsedNumber() : _type(VALUE_IS_NULL) {}
|
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {};
|
||||||
|
|
||||||
void setInteger(TUInt value, bool is_negative) {
|
inline bool parseNumber(const char* s, VariantData& result) {
|
||||||
uintValue = value;
|
typedef FloatTraits<Float> traits;
|
||||||
_type = uint8_t(is_negative ? VALUE_IS_NEGATIVE_INTEGER
|
typedef choose_largest<traits::mantissa_type, UInt>::type mantissa_t;
|
||||||
: VALUE_IS_POSITIVE_INTEGER);
|
typedef traits::exponent_type exponent_t;
|
||||||
}
|
|
||||||
|
ARDUINOJSON_ASSERT(s != 0);
|
||||||
void setFloat(TFloat value) {
|
|
||||||
floatValue = value;
|
bool is_negative = false;
|
||||||
_type = VALUE_IS_FLOAT;
|
switch (*s) {
|
||||||
}
|
case '-':
|
||||||
|
is_negative = true;
|
||||||
template <typename T>
|
s++;
|
||||||
T as() const {
|
break;
|
||||||
switch (_type) {
|
case '+':
|
||||||
case VALUE_IS_NEGATIVE_INTEGER:
|
s++;
|
||||||
return convertNegativeInteger<T>(uintValue);
|
break;
|
||||||
case VALUE_IS_POSITIVE_INTEGER:
|
}
|
||||||
return convertPositiveInteger<T>(uintValue);
|
|
||||||
case VALUE_IS_FLOAT:
|
#if ARDUINOJSON_ENABLE_NAN
|
||||||
return convertFloat<T>(floatValue);
|
if (*s == 'n' || *s == 'N') {
|
||||||
default:
|
result.setFloat(traits::nan());
|
||||||
return 0;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
uint8_t type() const {
|
#if ARDUINOJSON_ENABLE_INFINITY
|
||||||
return _type;
|
if (*s == 'i' || *s == 'I') {
|
||||||
}
|
result.setFloat(is_negative ? -traits::inf() : traits::inf());
|
||||||
|
return true;
|
||||||
union {
|
}
|
||||||
TUInt uintValue;
|
#endif
|
||||||
TFloat floatValue;
|
|
||||||
};
|
if (!isdigit(*s) && *s != '.')
|
||||||
uint8_t _type;
|
return false;
|
||||||
}; // namespace ARDUINOJSON_NAMESPACE
|
|
||||||
|
mantissa_t mantissa = 0;
|
||||||
template <typename A, typename B>
|
exponent_t exponent_offset = 0;
|
||||||
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {};
|
const mantissa_t maxUint = UInt(-1);
|
||||||
|
|
||||||
template <typename TFloat, typename TUInt>
|
while (isdigit(*s)) {
|
||||||
inline void parseNumber(const char* s, ParsedNumber<TFloat, TUInt>& result) {
|
uint8_t digit = uint8_t(*s - '0');
|
||||||
typedef FloatTraits<TFloat> traits;
|
if (mantissa > maxUint / 10)
|
||||||
typedef typename choose_largest<typename traits::mantissa_type, TUInt>::type
|
break;
|
||||||
mantissa_t;
|
mantissa *= 10;
|
||||||
typedef typename traits::exponent_type exponent_t;
|
if (mantissa > maxUint - digit)
|
||||||
|
break;
|
||||||
ARDUINOJSON_ASSERT(s != 0);
|
mantissa += digit;
|
||||||
|
s++;
|
||||||
bool is_negative = false;
|
}
|
||||||
switch (*s) {
|
|
||||||
case '-':
|
if (*s == '\0') {
|
||||||
is_negative = true;
|
if (is_negative)
|
||||||
s++;
|
result.setNegativeInteger(UInt(mantissa));
|
||||||
break;
|
else
|
||||||
case '+':
|
result.setPositiveInteger(UInt(mantissa));
|
||||||
s++;
|
return true;
|
||||||
break;
|
}
|
||||||
}
|
|
||||||
|
// avoid mantissa overflow
|
||||||
#if ARDUINOJSON_ENABLE_NAN
|
while (mantissa > traits::mantissa_max) {
|
||||||
if (*s == 'n' || *s == 'N') {
|
mantissa /= 10;
|
||||||
result.setFloat(traits::nan());
|
exponent_offset++;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
// remaing digits can't fit in the mantissa
|
||||||
#endif
|
while (isdigit(*s)) {
|
||||||
|
exponent_offset++;
|
||||||
#if ARDUINOJSON_ENABLE_INFINITY
|
s++;
|
||||||
if (*s == 'i' || *s == 'I') {
|
}
|
||||||
result.setFloat(is_negative ? -traits::inf() : traits::inf());
|
|
||||||
return;
|
if (*s == '.') {
|
||||||
}
|
s++;
|
||||||
#endif
|
while (isdigit(*s)) {
|
||||||
|
if (mantissa < traits::mantissa_max / 10) {
|
||||||
if (!isdigit(*s) && *s != '.')
|
mantissa = mantissa * 10 + uint8_t(*s - '0');
|
||||||
return;
|
exponent_offset--;
|
||||||
|
}
|
||||||
mantissa_t mantissa = 0;
|
s++;
|
||||||
exponent_t exponent_offset = 0;
|
}
|
||||||
const mantissa_t maxUint = TUInt(-1);
|
}
|
||||||
|
|
||||||
while (isdigit(*s)) {
|
int exponent = 0;
|
||||||
uint8_t digit = uint8_t(*s - '0');
|
if (*s == 'e' || *s == 'E') {
|
||||||
if (mantissa > maxUint / 10)
|
s++;
|
||||||
break;
|
bool negative_exponent = false;
|
||||||
mantissa *= 10;
|
if (*s == '-') {
|
||||||
if (mantissa > maxUint - digit)
|
negative_exponent = true;
|
||||||
break;
|
s++;
|
||||||
mantissa += digit;
|
} else if (*s == '+') {
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*s == '\0') {
|
while (isdigit(*s)) {
|
||||||
result.setInteger(TUInt(mantissa), is_negative);
|
exponent = exponent * 10 + (*s - '0');
|
||||||
return;
|
if (exponent + exponent_offset > traits::exponent_max) {
|
||||||
}
|
if (negative_exponent)
|
||||||
|
result.setFloat(is_negative ? -0.0f : 0.0f);
|
||||||
// avoid mantissa overflow
|
else
|
||||||
while (mantissa > traits::mantissa_max) {
|
result.setFloat(is_negative ? -traits::inf() : traits::inf());
|
||||||
mantissa /= 10;
|
return true;
|
||||||
exponent_offset++;
|
}
|
||||||
}
|
s++;
|
||||||
|
}
|
||||||
// remaing digits can't fit in the mantissa
|
if (negative_exponent)
|
||||||
while (isdigit(*s)) {
|
exponent = -exponent;
|
||||||
exponent_offset++;
|
}
|
||||||
s++;
|
exponent += exponent_offset;
|
||||||
}
|
|
||||||
|
// we should be at the end of the string, otherwise it's an error
|
||||||
if (*s == '.') {
|
if (*s != '\0')
|
||||||
s++;
|
return false;
|
||||||
while (isdigit(*s)) {
|
|
||||||
if (mantissa < traits::mantissa_max / 10) {
|
Float final_result =
|
||||||
mantissa = mantissa * 10 + uint8_t(*s - '0');
|
traits::make_float(static_cast<Float>(mantissa), exponent);
|
||||||
exponent_offset--;
|
|
||||||
}
|
result.setFloat(is_negative ? -final_result : final_result);
|
||||||
s++;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
template <typename T>
|
||||||
int exponent = 0;
|
inline T parseNumber(const char* s) {
|
||||||
if (*s == 'e' || *s == 'E') {
|
VariantData value;
|
||||||
s++;
|
value.init(); // VariantData is a POD, so it has no constructor
|
||||||
bool negative_exponent = false;
|
parseNumber(s, value);
|
||||||
if (*s == '-') {
|
return variantAs<T>(&value);
|
||||||
negative_exponent = true;
|
}
|
||||||
s++;
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
} 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,187 +1,187 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
#include <ArduinoJson/Variant/VariantOperators.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
#include <ArduinoJson/Variant/VariantShortcuts.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4522)
|
#pragma warning(disable : 4522)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TObject, typename TStringRef>
|
template <typename TObject, typename TStringRef>
|
||||||
class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||||
public VariantShortcuts<MemberProxy<TObject, TStringRef> >,
|
public VariantShortcuts<MemberProxy<TObject, TStringRef> >,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef MemberProxy<TObject, TStringRef> this_type;
|
typedef MemberProxy<TObject, TStringRef> this_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FORCE_INLINE MemberProxy(TObject variant, TStringRef key)
|
FORCE_INLINE MemberProxy(TObject variant, TStringRef key)
|
||||||
: _object(variant), _key(key) {}
|
: _object(variant), _key(key) {}
|
||||||
|
|
||||||
FORCE_INLINE MemberProxy(const MemberProxy &src)
|
FORCE_INLINE MemberProxy(const MemberProxy &src)
|
||||||
: _object(src._object), _key(src._key) {}
|
: _object(src._object), _key(src._key) {}
|
||||||
|
|
||||||
FORCE_INLINE operator VariantConstRef() const {
|
FORCE_INLINE operator VariantConstRef() const {
|
||||||
return getUpstreamMember();
|
return getUpstreamMember();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE this_type &operator=(const this_type &src) {
|
FORCE_INLINE this_type &operator=(const this_type &src) {
|
||||||
getOrAddUpstreamMember().set(src);
|
getOrAddUpstreamMember().set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type
|
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type
|
||||||
operator=(const TValue &src) {
|
operator=(const TValue &src) {
|
||||||
getOrAddUpstreamMember().set(src);
|
getOrAddUpstreamMember().set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator=(char*)
|
// operator=(char*)
|
||||||
// operator=(const char*)
|
// operator=(const char*)
|
||||||
// operator=(const __FlashStringHelper*)
|
// operator=(const __FlashStringHelper*)
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE this_type &operator=(TChar *src) {
|
FORCE_INLINE this_type &operator=(TChar *src) {
|
||||||
getOrAddUpstreamMember().set(src);
|
getOrAddUpstreamMember().set(src);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void clear() const {
|
FORCE_INLINE void clear() const {
|
||||||
getUpstreamMember().clear();
|
getUpstreamMember().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
return getUpstreamMember().isNull();
|
return getUpstreamMember().isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE typename VariantAs<TValue>::type as() const {
|
FORCE_INLINE typename VariantAs<TValue>::type as() const {
|
||||||
return getUpstreamMember().template as<TValue>();
|
return getUpstreamMember().template as<TValue>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE operator T() const {
|
FORCE_INLINE operator T() const {
|
||||||
return getUpstreamMember();
|
return getUpstreamMember();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE bool is() const {
|
FORCE_INLINE bool is() const {
|
||||||
return getUpstreamMember().template is<TValue>();
|
return getUpstreamMember().template is<TValue>();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t size() const {
|
FORCE_INLINE size_t size() const {
|
||||||
return getUpstreamMember().size();
|
return getUpstreamMember().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void remove(size_t index) const {
|
FORCE_INLINE void remove(size_t index) const {
|
||||||
getUpstreamMember().remove(index);
|
getUpstreamMember().remove(index);
|
||||||
}
|
}
|
||||||
// remove(char*) const
|
// remove(char*) const
|
||||||
// remove(const char*) const
|
// remove(const char*) const
|
||||||
// remove(const __FlashStringHelper*) const
|
// remove(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
|
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
|
||||||
TChar *key) const {
|
TChar *key) const {
|
||||||
getUpstreamMember().remove(key);
|
getUpstreamMember().remove(key);
|
||||||
}
|
}
|
||||||
// remove(const std::string&) const
|
// remove(const std::string&) const
|
||||||
// remove(const String&) const
|
// remove(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||||
const TString &key) const {
|
const TString &key) const {
|
||||||
getUpstreamMember().remove(key);
|
getUpstreamMember().remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
||||||
return getOrAddUpstreamMember().template to<TValue>();
|
return getOrAddUpstreamMember().template to<TValue>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE bool set(const TValue &value) {
|
FORCE_INLINE bool set(const TValue &value) {
|
||||||
return getOrAddUpstreamMember().set(value);
|
return getOrAddUpstreamMember().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set(char*) const
|
// set(char*) const
|
||||||
// set(const char*) const
|
// set(const char*) const
|
||||||
// set(const __FlashStringHelper*) const
|
// set(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE bool set(TChar *value) {
|
FORCE_INLINE bool set(TChar *value) {
|
||||||
return getOrAddUpstreamMember().set(value);
|
return getOrAddUpstreamMember().set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void accept(Visitor &visitor) const {
|
typename TVisitor::result_type accept(TVisitor &visitor) const {
|
||||||
return getUpstreamMember().accept(visitor);
|
return getUpstreamMember().accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantRef addElement() const {
|
FORCE_INLINE VariantRef addElement() const {
|
||||||
return getOrAddUpstreamMember().addElement();
|
return getOrAddUpstreamMember().addElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||||
return getUpstreamMember().getElement(index);
|
return getUpstreamMember().getElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
FORCE_INLINE VariantRef getOrAddElement(size_t index) const {
|
||||||
return getOrAddUpstreamMember().getOrAddElement(index);
|
return getOrAddUpstreamMember().getOrAddElement(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMember(char*) const
|
// getMember(char*) const
|
||||||
// getMember(const char*) const
|
// getMember(const char*) const
|
||||||
// getMember(const __FlashStringHelper*) const
|
// getMember(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE VariantRef getMember(TChar *key) const {
|
FORCE_INLINE VariantRef getMember(TChar *key) const {
|
||||||
return getUpstreamMember().getMember(key);
|
return getUpstreamMember().getMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMember(const std::string&) const
|
// getMember(const std::string&) const
|
||||||
// getMember(const String&) const
|
// getMember(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE VariantRef getMember(const TString &key) const {
|
FORCE_INLINE VariantRef getMember(const TString &key) const {
|
||||||
return getUpstreamMember().getMember(key);
|
return getUpstreamMember().getMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// getOrAddMember(char*) const
|
// getOrAddMember(char*) const
|
||||||
// getOrAddMember(const char*) const
|
// getOrAddMember(const char*) const
|
||||||
// getOrAddMember(const __FlashStringHelper*) const
|
// getOrAddMember(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE VariantRef getOrAddMember(TChar *key) const {
|
FORCE_INLINE VariantRef getOrAddMember(TChar *key) const {
|
||||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
// getOrAddMember(const std::string&) const
|
// getOrAddMember(const std::string&) const
|
||||||
// getOrAddMember(const String&) const
|
// getOrAddMember(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE VariantRef getOrAddMember(const TString &key) const {
|
FORCE_INLINE VariantRef getOrAddMember(const TString &key) const {
|
||||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FORCE_INLINE VariantRef getUpstreamMember() const {
|
FORCE_INLINE VariantRef getUpstreamMember() const {
|
||||||
return _object.getMember(_key);
|
return _object.getMember(_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE VariantRef getOrAddUpstreamMember() const {
|
FORCE_INLINE VariantRef getOrAddUpstreamMember() const {
|
||||||
return _object.getOrAddMember(_key);
|
return _object.getOrAddMember(_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
TObject _object;
|
TObject _object;
|
||||||
TStringRef _key;
|
TStringRef _key;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,50 +1,51 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
#include <ArduinoJson/Collection/CollectionData.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
void objectAccept(const CollectionData *obj, Visitor &visitor) {
|
typename TVisitor::result_type objectAccept(const CollectionData *obj,
|
||||||
if (obj)
|
TVisitor &visitor) {
|
||||||
visitor.visitObject(*obj);
|
if (obj)
|
||||||
else
|
return visitor.visitObject(*obj);
|
||||||
visitor.visitNull();
|
else
|
||||||
}
|
return visitor.visitNull();
|
||||||
|
}
|
||||||
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
|
||||||
if (lhs == rhs)
|
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||||
return true;
|
if (lhs == rhs)
|
||||||
if (!lhs || !rhs)
|
return true;
|
||||||
return false;
|
if (!lhs || !rhs)
|
||||||
return lhs->equalsObject(*rhs);
|
return false;
|
||||||
}
|
return lhs->equalsObject(*rhs);
|
||||||
|
}
|
||||||
template <typename TAdaptedString>
|
|
||||||
inline VariantData *objectGetMember(const CollectionData *obj,
|
template <typename TAdaptedString>
|
||||||
TAdaptedString key) {
|
inline VariantData *objectGetMember(const CollectionData *obj,
|
||||||
if (!obj)
|
TAdaptedString key) {
|
||||||
return 0;
|
if (!obj)
|
||||||
return obj->getMember(key);
|
return 0;
|
||||||
}
|
return obj->getMember(key);
|
||||||
|
}
|
||||||
template <typename TAdaptedString>
|
|
||||||
void objectRemove(CollectionData *obj, TAdaptedString key) {
|
template <typename TAdaptedString>
|
||||||
if (!obj)
|
void objectRemove(CollectionData *obj, TAdaptedString key) {
|
||||||
return;
|
if (!obj)
|
||||||
obj->removeMember(key);
|
return;
|
||||||
}
|
obj->removeMember(key);
|
||||||
|
}
|
||||||
template <typename TAdaptedString>
|
|
||||||
inline VariantData *objectGetOrAddMember(CollectionData *obj,
|
template <typename TAdaptedString>
|
||||||
TAdaptedString key, MemoryPool *pool) {
|
inline VariantData *objectGetOrAddMember(CollectionData *obj,
|
||||||
if (!obj)
|
TAdaptedString key, MemoryPool *pool) {
|
||||||
return 0;
|
if (!obj)
|
||||||
|
return 0;
|
||||||
return obj->getOrAddMember(key, pool);
|
|
||||||
}
|
return obj->getOrAddMember(key, pool);
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
}
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,69 +1,69 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Array/ArrayRef.hpp>
|
#include <ArduinoJson/Array/ArrayRef.hpp>
|
||||||
#include <ArduinoJson/Object/ObjectRef.hpp>
|
#include <ArduinoJson/Object/ObjectRef.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
|
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
|
||||||
const TString& key) const {
|
const TString& key) const {
|
||||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const {
|
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const {
|
||||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||||
const TString& key) const {
|
const TString& key) const {
|
||||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||||
TChar* key) const {
|
TChar* key) const {
|
||||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline typename enable_if<IsString<TString>::value, bool>::type
|
inline typename enable_if<IsString<TString>::value, bool>::type
|
||||||
ObjectShortcuts<TObject>::containsKey(const TString& key) const {
|
ObjectShortcuts<TObject>::containsKey(const TString& key) const {
|
||||||
return !impl()->getMember(key).isUndefined();
|
return !impl()->getMember(key).isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
inline typename enable_if<IsString<TChar*>::value, bool>::type
|
inline typename enable_if<IsString<TChar*>::value, bool>::type
|
||||||
ObjectShortcuts<TObject>::containsKey(TChar* key) const {
|
ObjectShortcuts<TObject>::containsKey(TChar* key) const {
|
||||||
return !impl()->getMember(key).isUndefined();
|
return !impl()->getMember(key).isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline typename enable_if<IsString<TString*>::value,
|
inline typename enable_if<IsString<TString*>::value,
|
||||||
MemberProxy<TObject, TString*> >::type
|
MemberProxy<TObject, TString*> >::type
|
||||||
ObjectShortcuts<TObject>::operator[](TString* key) const {
|
ObjectShortcuts<TObject>::operator[](TString* key) const {
|
||||||
return MemberProxy<TObject, TString*>(*impl(), key);
|
return MemberProxy<TObject, TString*>(*impl(), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline typename enable_if<IsString<TString>::value,
|
inline typename enable_if<IsString<TString>::value,
|
||||||
MemberProxy<TObject, TString> >::type
|
MemberProxy<TObject, TString> >::type
|
||||||
ObjectShortcuts<TObject>::operator[](const TString& key) const {
|
ObjectShortcuts<TObject>::operator[](const TString& key) const {
|
||||||
return MemberProxy<TObject, TString>(*impl(), key);
|
return MemberProxy<TObject, TString>(*impl(), key);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,123 +1,123 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Object/Pair.hpp>
|
#include <ArduinoJson/Object/Pair.hpp>
|
||||||
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
#include <ArduinoJson/Variant/SlotFunctions.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
class PairPtr {
|
class PairPtr {
|
||||||
public:
|
public:
|
||||||
PairPtr(MemoryPool *pool, VariantSlot *slot) : _pair(pool, slot) {}
|
PairPtr(MemoryPool *pool, VariantSlot *slot) : _pair(pool, slot) {}
|
||||||
|
|
||||||
const Pair *operator->() const {
|
const Pair *operator->() const {
|
||||||
return &_pair;
|
return &_pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Pair &operator*() const {
|
const Pair &operator*() const {
|
||||||
return _pair;
|
return _pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Pair _pair;
|
Pair _pair;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectIterator {
|
class ObjectIterator {
|
||||||
public:
|
public:
|
||||||
ObjectIterator() : _slot(0) {}
|
ObjectIterator() : _slot(0) {}
|
||||||
|
|
||||||
explicit ObjectIterator(MemoryPool *pool, VariantSlot *slot)
|
explicit ObjectIterator(MemoryPool *pool, VariantSlot *slot)
|
||||||
: _pool(pool), _slot(slot) {}
|
: _pool(pool), _slot(slot) {}
|
||||||
|
|
||||||
Pair operator*() const {
|
Pair operator*() const {
|
||||||
return Pair(_pool, _slot);
|
return Pair(_pool, _slot);
|
||||||
}
|
}
|
||||||
PairPtr operator->() {
|
PairPtr operator->() {
|
||||||
return PairPtr(_pool, _slot);
|
return PairPtr(_pool, _slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ObjectIterator &other) const {
|
bool operator==(const ObjectIterator &other) const {
|
||||||
return _slot == other._slot;
|
return _slot == other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ObjectIterator &other) const {
|
bool operator!=(const ObjectIterator &other) const {
|
||||||
return _slot != other._slot;
|
return _slot != other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectIterator &operator++() {
|
ObjectIterator &operator++() {
|
||||||
_slot = _slot->next();
|
_slot = _slot->next();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectIterator &operator+=(size_t distance) {
|
ObjectIterator &operator+=(size_t distance) {
|
||||||
_slot = _slot->next(distance);
|
_slot = _slot->next(distance);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantSlot *internal() {
|
VariantSlot *internal() {
|
||||||
return _slot;
|
return _slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool *_pool;
|
MemoryPool *_pool;
|
||||||
VariantSlot *_slot;
|
VariantSlot *_slot;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PairConstPtr {
|
class PairConstPtr {
|
||||||
public:
|
public:
|
||||||
PairConstPtr(const VariantSlot *slot) : _pair(slot) {}
|
PairConstPtr(const VariantSlot *slot) : _pair(slot) {}
|
||||||
|
|
||||||
const PairConst *operator->() const {
|
const PairConst *operator->() const {
|
||||||
return &_pair;
|
return &_pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PairConst &operator*() const {
|
const PairConst &operator*() const {
|
||||||
return _pair;
|
return _pair;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PairConst _pair;
|
PairConst _pair;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectConstIterator {
|
class ObjectConstIterator {
|
||||||
public:
|
public:
|
||||||
ObjectConstIterator() : _slot(0) {}
|
ObjectConstIterator() : _slot(0) {}
|
||||||
|
|
||||||
explicit ObjectConstIterator(const VariantSlot *slot) : _slot(slot) {}
|
explicit ObjectConstIterator(const VariantSlot *slot) : _slot(slot) {}
|
||||||
|
|
||||||
PairConst operator*() const {
|
PairConst operator*() const {
|
||||||
return PairConst(_slot);
|
return PairConst(_slot);
|
||||||
}
|
}
|
||||||
PairConstPtr operator->() {
|
PairConstPtr operator->() {
|
||||||
return PairConstPtr(_slot);
|
return PairConstPtr(_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const ObjectConstIterator &other) const {
|
bool operator==(const ObjectConstIterator &other) const {
|
||||||
return _slot == other._slot;
|
return _slot == other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const ObjectConstIterator &other) const {
|
bool operator!=(const ObjectConstIterator &other) const {
|
||||||
return _slot != other._slot;
|
return _slot != other._slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectConstIterator &operator++() {
|
ObjectConstIterator &operator++() {
|
||||||
_slot = _slot->next();
|
_slot = _slot->next();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectConstIterator &operator+=(size_t distance) {
|
ObjectConstIterator &operator+=(size_t distance) {
|
||||||
_slot = _slot->next(distance);
|
_slot = _slot->next(distance);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VariantSlot *internal() {
|
const VariantSlot *internal() {
|
||||||
return _slot;
|
return _slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const VariantSlot *_slot;
|
const VariantSlot *_slot;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,239 +1,239 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Object/ObjectFunctions.hpp>
|
#include <ArduinoJson/Object/ObjectFunctions.hpp>
|
||||||
#include <ArduinoJson/Object/ObjectIterator.hpp>
|
#include <ArduinoJson/Object/ObjectIterator.hpp>
|
||||||
|
|
||||||
// Returns the size (in bytes) of an object with n elements.
|
// Returns the size (in bytes) of an object with n elements.
|
||||||
// Can be very handy to determine the size of a StaticMemoryPool.
|
// Can be very handy to determine the size of a StaticMemoryPool.
|
||||||
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
|
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
|
||||||
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
((NUMBER_OF_ELEMENTS) * sizeof(ARDUINOJSON_NAMESPACE::VariantSlot))
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename TData>
|
template <typename TData>
|
||||||
class ObjectRefBase {
|
class ObjectRefBase {
|
||||||
public:
|
public:
|
||||||
operator VariantConstRef() const {
|
operator VariantConstRef() const {
|
||||||
const void* data = _data; // prevent warning cast-align
|
const void* data = _data; // prevent warning cast-align
|
||||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Visitor>
|
template <typename TVisitor>
|
||||||
FORCE_INLINE void accept(Visitor& visitor) const {
|
typename TVisitor::result_type accept(TVisitor& visitor) const {
|
||||||
objectAccept(_data, visitor);
|
return objectAccept(_data, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool isNull() const {
|
FORCE_INLINE bool isNull() const {
|
||||||
return _data == 0;
|
return _data == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE operator bool() const {
|
FORCE_INLINE operator bool() const {
|
||||||
return _data != 0;
|
return _data != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t memoryUsage() const {
|
FORCE_INLINE size_t memoryUsage() const {
|
||||||
return _data ? _data->memoryUsage() : 0;
|
return _data ? _data->memoryUsage() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t nesting() const {
|
FORCE_INLINE size_t nesting() const {
|
||||||
return _data ? _data->nesting() : 0;
|
return _data ? _data->nesting() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE size_t size() const {
|
FORCE_INLINE size_t size() const {
|
||||||
return _data ? _data->size() : 0;
|
return _data ? _data->size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ObjectRefBase(TData* data) : _data(data) {}
|
ObjectRefBase(TData* data) : _data(data) {}
|
||||||
TData* _data;
|
TData* _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectConstRef : public ObjectRefBase<const CollectionData>,
|
class ObjectConstRef : public ObjectRefBase<const CollectionData>,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
friend class ObjectRef;
|
friend class ObjectRef;
|
||||||
typedef ObjectRefBase<const CollectionData> base_type;
|
typedef ObjectRefBase<const CollectionData> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef ObjectConstIterator iterator;
|
typedef ObjectConstIterator iterator;
|
||||||
|
|
||||||
ObjectConstRef() : base_type(0) {}
|
ObjectConstRef() : base_type(0) {}
|
||||||
ObjectConstRef(const CollectionData* data) : base_type(data) {}
|
ObjectConstRef(const CollectionData* data) : base_type(data) {}
|
||||||
|
|
||||||
FORCE_INLINE iterator begin() const {
|
FORCE_INLINE iterator begin() const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return iterator();
|
return iterator();
|
||||||
return iterator(_data->head());
|
return iterator(_data->head());
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE iterator end() const {
|
FORCE_INLINE iterator end() const {
|
||||||
return iterator();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
// containsKey(const std::string&) const
|
// containsKey(const std::string&) const
|
||||||
// containsKey(const String&) const
|
// containsKey(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE bool containsKey(const TString& key) const {
|
FORCE_INLINE bool containsKey(const TString& key) const {
|
||||||
return !getMember(key).isUndefined();
|
return !getMember(key).isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// containsKey(char*) const
|
// containsKey(char*) const
|
||||||
// containsKey(const char*) const
|
// containsKey(const char*) const
|
||||||
// containsKey(const __FlashStringHelper*) const
|
// containsKey(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE bool containsKey(TChar* key) const {
|
FORCE_INLINE bool containsKey(TChar* key) const {
|
||||||
return !getMember(key).isUndefined();
|
return !getMember(key).isUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMember(const std::string&) const
|
// getMember(const std::string&) const
|
||||||
// getMember(const String&) const
|
// getMember(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE VariantConstRef getMember(const TString& key) const {
|
FORCE_INLINE VariantConstRef getMember(const TString& key) const {
|
||||||
return get_impl(adaptString(key));
|
return get_impl(adaptString(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMember(char*) const
|
// getMember(char*) const
|
||||||
// getMember(const char*) const
|
// getMember(const char*) const
|
||||||
// getMember(const __FlashStringHelper*) const
|
// getMember(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||||
return get_impl(adaptString(key));
|
return get_impl(adaptString(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator[](const std::string&) const
|
// operator[](const std::string&) const
|
||||||
// operator[](const String&) const
|
// operator[](const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||||
operator[](const TString& key) const {
|
operator[](const TString& key) const {
|
||||||
return get_impl(adaptString(key));
|
return get_impl(adaptString(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator[](char*) const
|
// operator[](char*) const
|
||||||
// operator[](const char*) const
|
// operator[](const char*) const
|
||||||
// operator[](const __FlashStringHelper*) const
|
// operator[](const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
||||||
operator[](TChar* key) const {
|
operator[](TChar* key) const {
|
||||||
return get_impl(adaptString(key));
|
return get_impl(adaptString(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool operator==(ObjectConstRef rhs) const {
|
FORCE_INLINE bool operator==(ObjectConstRef rhs) const {
|
||||||
return objectEquals(_data, rhs._data);
|
return objectEquals(_data, rhs._data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const {
|
FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const {
|
||||||
return VariantConstRef(objectGetMember(_data, key));
|
return VariantConstRef(objectGetMember(_data, key));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectRef : public ObjectRefBase<CollectionData>,
|
class ObjectRef : public ObjectRefBase<CollectionData>,
|
||||||
public ObjectShortcuts<ObjectRef>,
|
public ObjectShortcuts<ObjectRef>,
|
||||||
public Visitable {
|
public Visitable {
|
||||||
typedef ObjectRefBase<CollectionData> base_type;
|
typedef ObjectRefBase<CollectionData> base_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef ObjectIterator iterator;
|
typedef ObjectIterator iterator;
|
||||||
|
|
||||||
FORCE_INLINE ObjectRef() : base_type(0), _pool(0) {}
|
FORCE_INLINE ObjectRef() : base_type(0), _pool(0) {}
|
||||||
FORCE_INLINE ObjectRef(MemoryPool* buf, CollectionData* data)
|
FORCE_INLINE ObjectRef(MemoryPool* buf, CollectionData* data)
|
||||||
: base_type(data), _pool(buf) {}
|
: base_type(data), _pool(buf) {}
|
||||||
|
|
||||||
operator VariantRef() const {
|
operator VariantRef() const {
|
||||||
void* data = _data; // prevent warning cast-align
|
void* data = _data; // prevent warning cast-align
|
||||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
operator ObjectConstRef() const {
|
operator ObjectConstRef() const {
|
||||||
return ObjectConstRef(_data);
|
return ObjectConstRef(_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE iterator begin() const {
|
FORCE_INLINE iterator begin() const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return iterator();
|
return iterator();
|
||||||
return iterator(_pool, _data->head());
|
return iterator(_pool, _data->head());
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE iterator end() const {
|
FORCE_INLINE iterator end() const {
|
||||||
return iterator();
|
return iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() const {
|
void clear() const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return;
|
return;
|
||||||
_data->clear();
|
_data->clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool set(ObjectConstRef src) {
|
FORCE_INLINE bool set(ObjectConstRef src) {
|
||||||
if (!_data || !src._data)
|
if (!_data || !src._data)
|
||||||
return false;
|
return false;
|
||||||
return _data->copyFrom(*src._data, _pool);
|
return _data->copyFrom(*src._data, _pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMember(const std::string&) const
|
// getMember(const std::string&) const
|
||||||
// getMember(const String&) const
|
// getMember(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE VariantRef getMember(const TString& key) const {
|
FORCE_INLINE VariantRef getMember(const TString& key) const {
|
||||||
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// getMember(char*) const
|
// getMember(char*) const
|
||||||
// getMember(const char*) const
|
// getMember(const char*) const
|
||||||
// getMember(const __FlashStringHelper*) const
|
// getMember(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE VariantRef getMember(TChar* key) const {
|
FORCE_INLINE VariantRef getMember(TChar* key) const {
|
||||||
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
return VariantRef(_pool, objectGetMember(_data, adaptString(key)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// getOrAddMember(const std::string&) const
|
// getOrAddMember(const std::string&) const
|
||||||
// getOrAddMember(const String&) const
|
// getOrAddMember(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
|
FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
|
||||||
return VariantRef(_pool,
|
return VariantRef(_pool,
|
||||||
objectGetOrAddMember(_data, adaptString(key), _pool));
|
objectGetOrAddMember(_data, adaptString(key), _pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
// getOrAddMember(char*) const
|
// getOrAddMember(char*) const
|
||||||
// getOrAddMember(const char*) const
|
// getOrAddMember(const char*) const
|
||||||
// getOrAddMember(const __FlashStringHelper*) const
|
// getOrAddMember(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
|
FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
|
||||||
return VariantRef(_pool,
|
return VariantRef(_pool,
|
||||||
objectGetOrAddMember(_data, adaptString(key), _pool));
|
objectGetOrAddMember(_data, adaptString(key), _pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE bool operator==(ObjectRef rhs) const {
|
FORCE_INLINE bool operator==(ObjectRef rhs) const {
|
||||||
return objectEquals(_data, rhs._data);
|
return objectEquals(_data, rhs._data);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCE_INLINE void remove(iterator it) const {
|
FORCE_INLINE void remove(iterator it) const {
|
||||||
if (!_data)
|
if (!_data)
|
||||||
return;
|
return;
|
||||||
_data->removeSlot(it.internal());
|
_data->removeSlot(it.internal());
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove(const std::string&) const
|
// remove(const std::string&) const
|
||||||
// remove(const String&) const
|
// remove(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE void remove(const TString& key) const {
|
FORCE_INLINE void remove(const TString& key) const {
|
||||||
objectRemove(_data, adaptString(key));
|
objectRemove(_data, adaptString(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove(char*) const
|
// remove(char*) const
|
||||||
// remove(const char*) const
|
// remove(const char*) const
|
||||||
// remove(const __FlashStringHelper*) const
|
// remove(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE void remove(TChar* key) const {
|
FORCE_INLINE void remove(TChar* key) const {
|
||||||
objectRemove(_data, adaptString(key));
|
objectRemove(_data, adaptString(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MemoryPool* _pool;
|
MemoryPool* _pool;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,73 +1,73 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
template <typename TParent, typename TStringRef>
|
template <typename TParent, typename TStringRef>
|
||||||
class MemberProxy;
|
class MemberProxy;
|
||||||
|
|
||||||
template <typename TObject>
|
template <typename TObject>
|
||||||
class ObjectShortcuts {
|
class ObjectShortcuts {
|
||||||
public:
|
public:
|
||||||
// containsKey(const std::string&) const
|
// containsKey(const std::string&) const
|
||||||
// containsKey(const String&) const
|
// containsKey(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type
|
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type
|
||||||
containsKey(const TString &key) const;
|
containsKey(const TString &key) const;
|
||||||
|
|
||||||
// containsKey(char*) const
|
// containsKey(char*) const
|
||||||
// containsKey(const char*) const
|
// containsKey(const char*) const
|
||||||
// containsKey(const __FlashStringHelper*) const
|
// containsKey(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type
|
FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type
|
||||||
containsKey(TChar *key) const;
|
containsKey(TChar *key) const;
|
||||||
|
|
||||||
// operator[](const std::string&) const
|
// operator[](const std::string&) const
|
||||||
// operator[](const String&) const
|
// operator[](const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||||
MemberProxy<TObject, TString> >::type
|
MemberProxy<TObject, TString> >::type
|
||||||
operator[](const TString &key) const;
|
operator[](const TString &key) const;
|
||||||
|
|
||||||
// operator[](char*) const
|
// operator[](char*) const
|
||||||
// operator[](const char*) const
|
// operator[](const char*) const
|
||||||
// operator[](const __FlashStringHelper*) const
|
// operator[](const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value,
|
FORCE_INLINE typename enable_if<IsString<TChar *>::value,
|
||||||
MemberProxy<TObject, TChar *> >::type
|
MemberProxy<TObject, TChar *> >::type
|
||||||
operator[](TChar *key) const;
|
operator[](TChar *key) const;
|
||||||
|
|
||||||
// createNestedArray(const std::string&) const
|
// createNestedArray(const std::string&) const
|
||||||
// createNestedArray(const String&) const
|
// createNestedArray(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE ArrayRef createNestedArray(const TString &key) const;
|
FORCE_INLINE ArrayRef createNestedArray(const TString &key) const;
|
||||||
|
|
||||||
// createNestedArray(char*) const
|
// createNestedArray(char*) const
|
||||||
// createNestedArray(const char*) const
|
// createNestedArray(const char*) const
|
||||||
// createNestedArray(const __FlashStringHelper*) const
|
// createNestedArray(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
FORCE_INLINE ArrayRef createNestedArray(TChar *key) const;
|
FORCE_INLINE ArrayRef createNestedArray(TChar *key) const;
|
||||||
|
|
||||||
// createNestedObject(const std::string&) const
|
// createNestedObject(const std::string&) const
|
||||||
// createNestedObject(const String&) const
|
// createNestedObject(const String&) const
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
ObjectRef createNestedObject(const TString &key) const;
|
ObjectRef createNestedObject(const TString &key) const;
|
||||||
|
|
||||||
// createNestedObject(char*) const
|
// createNestedObject(char*) const
|
||||||
// createNestedObject(const char*) const
|
// createNestedObject(const char*) const
|
||||||
// createNestedObject(const __FlashStringHelper*) const
|
// createNestedObject(const __FlashStringHelper*) const
|
||||||
template <typename TChar>
|
template <typename TChar>
|
||||||
ObjectRef createNestedObject(TChar *key) const;
|
ObjectRef createNestedObject(TChar *key) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const TObject *impl() const {
|
const TObject *impl() const {
|
||||||
return static_cast<const TObject *>(this);
|
return static_cast<const TObject *>(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,55 +1,55 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Strings/String.hpp>
|
#include <ArduinoJson/Strings/String.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantRef.hpp>
|
#include <ArduinoJson/Variant/VariantRef.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
// A key value pair for CollectionData.
|
// A key value pair for CollectionData.
|
||||||
class Pair {
|
class Pair {
|
||||||
public:
|
public:
|
||||||
Pair(MemoryPool* pool, VariantSlot* slot) {
|
Pair(MemoryPool* pool, VariantSlot* slot) {
|
||||||
if (slot) {
|
if (slot) {
|
||||||
_key = String(slot->key(), !slot->ownsKey());
|
_key = String(slot->key(), !slot->ownsKey());
|
||||||
_value = VariantRef(pool, slot->data());
|
_value = VariantRef(pool, slot->data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String key() const {
|
String key() const {
|
||||||
return _key;
|
return _key;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantRef value() const {
|
VariantRef value() const {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String _key;
|
String _key;
|
||||||
VariantRef _value;
|
VariantRef _value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PairConst {
|
class PairConst {
|
||||||
public:
|
public:
|
||||||
PairConst(const VariantSlot* slot) {
|
PairConst(const VariantSlot* slot) {
|
||||||
if (slot) {
|
if (slot) {
|
||||||
_key = String(slot->key(), !slot->ownsKey());
|
_key = String(slot->key(), !slot->ownsKey());
|
||||||
_value = VariantConstRef(slot->data());
|
_value = VariantConstRef(slot->data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String key() const {
|
String key() const {
|
||||||
return _key;
|
return _key;
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantConstRef value() const {
|
VariantConstRef value() const {
|
||||||
return _value;
|
return _value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String _key;
|
String _key;
|
||||||
VariantConstRef _value;
|
VariantConstRef _value;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdlib.h> // for size_t
|
#include <stdlib.h> // for size_t
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include "math.hpp"
|
#include "math.hpp"
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename T, typename F>
|
template <typename T, typename F>
|
||||||
struct alias_cast_t {
|
struct alias_cast_t {
|
||||||
union {
|
union {
|
||||||
F raw;
|
F raw;
|
||||||
T data;
|
T data;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T, typename F>
|
template <typename T, typename F>
|
||||||
T alias_cast(F raw_data) {
|
T alias_cast(F raw_data) {
|
||||||
alias_cast_t<T, F> ac;
|
alias_cast_t<T, F> ac;
|
||||||
ac.raw = raw_data;
|
ac.raw = raw_data;
|
||||||
return ac.data;
|
return ac.data;
|
||||||
}
|
}
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Configuration.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
|
|
||||||
#if ARDUINOJSON_DEBUG
|
#if ARDUINOJSON_DEBUG
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#define ARDUINOJSON_ASSERT(X) assert(X)
|
#define ARDUINOJSON_ASSERT(X) assert(X)
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_ASSERT(X) ((void)0)
|
#define ARDUINOJSON_ASSERT(X) ((void)0)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,45 +1,45 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef _MSC_VER // Visual Studio
|
#ifdef _MSC_VER // Visual Studio
|
||||||
|
|
||||||
#define FORCE_INLINE // __forceinline causes C4714 when returning std::string
|
#define FORCE_INLINE // __forceinline causes C4714 when returning std::string
|
||||||
#define NO_INLINE __declspec(noinline)
|
#define NO_INLINE __declspec(noinline)
|
||||||
#define DEPRECATED(msg) __declspec(deprecated(msg))
|
#define DEPRECATED(msg) __declspec(deprecated(msg))
|
||||||
|
|
||||||
#elif defined(__GNUC__) // GCC or Clang
|
#elif defined(__GNUC__) // GCC or Clang
|
||||||
|
|
||||||
#define FORCE_INLINE __attribute__((always_inline))
|
#define FORCE_INLINE __attribute__((always_inline))
|
||||||
#define NO_INLINE __attribute__((noinline))
|
#define NO_INLINE __attribute__((noinline))
|
||||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||||
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
|
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
|
||||||
#else
|
#else
|
||||||
#define DEPRECATED(msg) __attribute__((deprecated))
|
#define DEPRECATED(msg) __attribute__((deprecated))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else // Other compilers
|
#else // Other compilers
|
||||||
|
|
||||||
#define FORCE_INLINE
|
#define FORCE_INLINE
|
||||||
#define NO_INLINE
|
#define NO_INLINE
|
||||||
#define DEPRECATED(msg)
|
#define DEPRECATED(msg)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
#define NOEXCEPT noexcept
|
#define NOEXCEPT noexcept
|
||||||
#else
|
#else
|
||||||
#define NOEXCEPT throw()
|
#define NOEXCEPT throw()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__has_attribute)
|
#if defined(__has_attribute)
|
||||||
#if __has_attribute(no_sanitize)
|
#if __has_attribute(no_sanitize)
|
||||||
#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
|
#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
inline bool isdigit(char c) {
|
inline bool isdigit(char c) {
|
||||||
return '0' <= c && c <= '9';
|
return '0' <= c && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool issign(char c) {
|
inline bool issign(char c) {
|
||||||
return '-' == c || c == '+';
|
return '-' == c || c == '+';
|
||||||
}
|
}
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
// 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
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "type_traits.hpp"
|
#include "type_traits.hpp"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable : 4310)
|
#pragma warning(disable : 4310)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// Differs from standard because we can't use the symbols "min" and "max"
|
// Differs from standard because we can't use the symbols "min" and "max"
|
||||||
template <typename T, typename Enable = void>
|
template <typename T, typename Enable = void>
|
||||||
struct numeric_limits;
|
struct numeric_limits;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
|
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
|
||||||
static T lowest() {
|
static T lowest() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static T highest() {
|
static T highest() {
|
||||||
return T(-1);
|
return T(-1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct numeric_limits<
|
struct numeric_limits<
|
||||||
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> {
|
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> {
|
||||||
static T lowest() {
|
static T lowest() {
|
||||||
return T(T(1) << (sizeof(T) * 8 - 1));
|
return T(T(1) << (sizeof(T) * 8 - 1));
|
||||||
}
|
}
|
||||||
static T highest() {
|
static T highest() {
|
||||||
return T(~lowest());
|
return T(~lowest());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// Some libraries #define isnan() and isinf() so we need to check before
|
// Some libraries #define isnan() and isinf() so we need to check before
|
||||||
// using this name
|
// using this name
|
||||||
|
|
||||||
#ifndef isnan
|
#ifndef isnan
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool isnan(T x) {
|
bool isnan(T x) {
|
||||||
return x != x;
|
return x != x;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef isinf
|
#ifndef isinf
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool isinf(T x) {
|
bool isinf(T x) {
|
||||||
return x != 0.0 && x * 2 == x;
|
return x != 0.0 && x * 2 == x;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
#include <stddef.h> // for size_t
|
#include <stddef.h> // for size_t
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// A meta-function that returns the highest value
|
// A meta-function that returns the highest value
|
||||||
template <size_t X, size_t Y, bool MaxIsX = (X > Y)>
|
template <size_t X, size_t Y, bool MaxIsX = (X > Y)>
|
||||||
struct Max {};
|
struct Max {};
|
||||||
|
|
||||||
template <size_t X, size_t Y>
|
template <size_t X, size_t Y>
|
||||||
struct Max<X, Y, true> {
|
struct Max<X, Y, true> {
|
||||||
static const size_t value = X;
|
static const size_t value = X;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t X, size_t Y>
|
template <size_t X, size_t Y>
|
||||||
struct Max<X, Y, false> {
|
struct Max<X, Y, false> {
|
||||||
static const size_t value = Y;
|
static const size_t value = Y;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,78 +1,79 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#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
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
// originals are missing
|
// Wraps a const char* so that the our functions are picked only if the
|
||||||
struct pgm_p {
|
// originals are missing
|
||||||
pgm_p(const char* p) : address(p) {}
|
struct pgm_p {
|
||||||
const char* address;
|
pgm_p(const char* p) : address(p) {}
|
||||||
};
|
const char* address;
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
};
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
#ifndef strlen_P
|
|
||||||
inline size_t strlen_P(ARDUINOJSON_NAMESPACE::pgm_p s) {
|
#ifndef strlen_P
|
||||||
const char* p = s.address;
|
inline size_t strlen_P(ARDUINOJSON_NAMESPACE::pgm_p s) {
|
||||||
ARDUINOJSON_ASSERT(p != NULL);
|
const char* p = s.address;
|
||||||
while (pgm_read_byte(p)) p++;
|
ARDUINOJSON_ASSERT(p != NULL);
|
||||||
return size_t(p - s.address);
|
while (pgm_read_byte(p)) p++;
|
||||||
}
|
return size_t(p - s.address);
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
#ifndef strncmp_P
|
|
||||||
inline int strncmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b, size_t n) {
|
#ifndef strncmp_P
|
||||||
const char* s1 = a;
|
inline int strncmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b, size_t n) {
|
||||||
const char* s2 = b.address;
|
const char* s1 = a;
|
||||||
ARDUINOJSON_ASSERT(s1 != NULL);
|
const char* s2 = b.address;
|
||||||
ARDUINOJSON_ASSERT(s2 != NULL);
|
ARDUINOJSON_ASSERT(s1 != NULL);
|
||||||
while (n-- > 0) {
|
ARDUINOJSON_ASSERT(s2 != NULL);
|
||||||
char c1 = *s1++;
|
while (n-- > 0) {
|
||||||
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
char c1 = *s1++;
|
||||||
if (c1 < c2)
|
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
||||||
return -1;
|
if (c1 < c2)
|
||||||
if (c1 > c2)
|
return -1;
|
||||||
return 1;
|
if (c1 > c2)
|
||||||
if (c1 == 0 /* and c2 as well */)
|
return 1;
|
||||||
return 0;
|
if (c1 == 0 /* and c2 as well */)
|
||||||
}
|
return 0;
|
||||||
return 0;
|
}
|
||||||
}
|
return 0;
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
#ifndef strcmp_P
|
|
||||||
inline int strcmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b) {
|
#ifndef strcmp_P
|
||||||
const char* s1 = a;
|
inline int strcmp_P(const char* a, ARDUINOJSON_NAMESPACE::pgm_p b) {
|
||||||
const char* s2 = b.address;
|
const char* s1 = a;
|
||||||
ARDUINOJSON_ASSERT(s1 != NULL);
|
const char* s2 = b.address;
|
||||||
ARDUINOJSON_ASSERT(s2 != NULL);
|
ARDUINOJSON_ASSERT(s1 != NULL);
|
||||||
for (;;) {
|
ARDUINOJSON_ASSERT(s2 != NULL);
|
||||||
char c1 = *s1++;
|
for (;;) {
|
||||||
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
char c1 = *s1++;
|
||||||
if (c1 < c2)
|
char c2 = static_cast<char>(pgm_read_byte(s2++));
|
||||||
return -1;
|
if (c1 < c2)
|
||||||
if (c1 > c2)
|
return -1;
|
||||||
return 1;
|
if (c1 > c2)
|
||||||
if (c1 == 0 /* and c2 as well */)
|
return 1;
|
||||||
return 0;
|
if (c1 == 0 /* and c2 as well */)
|
||||||
}
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
#ifndef memcpy_P
|
|
||||||
inline void* memcpy_P(void* dst, ARDUINOJSON_NAMESPACE::pgm_p src, size_t n) {
|
#ifndef memcpy_P
|
||||||
uint8_t* d = reinterpret_cast<uint8_t*>(dst);
|
inline void* memcpy_P(void* dst, ARDUINOJSON_NAMESPACE::pgm_p src, size_t n) {
|
||||||
const char* s = src.address;
|
uint8_t* d = reinterpret_cast<uint8_t*>(dst);
|
||||||
ARDUINOJSON_ASSERT(d != NULL);
|
const char* s = src.address;
|
||||||
ARDUINOJSON_ASSERT(s != NULL);
|
ARDUINOJSON_ASSERT(d != NULL);
|
||||||
while (n-- > 0) {
|
ARDUINOJSON_ASSERT(s != NULL);
|
||||||
*d++ = pgm_read_byte(s++);
|
while (n-- > 0) {
|
||||||
}
|
*d++ = pgm_read_byte(s++);
|
||||||
return dst;
|
}
|
||||||
}
|
return dst;
|
||||||
#endif
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
|
|
||||||
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename enable_if<is_pointer<T>::value, T>::type pgm_read(const void* p) {
|
||||||
|
return reinterpret_cast<T>(pgm_read_ptr(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename enable_if<is_floating_point<T>::value &&
|
||||||
|
sizeof(T) == sizeof(float), // on AVR sizeof(double) ==
|
||||||
|
// sizeof(float)
|
||||||
|
T>::type
|
||||||
|
pgm_read(const void* p) {
|
||||||
|
return pgm_read_float(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename enable_if<is_same<T, uint32_t>::value, T>::type pgm_read(
|
||||||
|
const void* p) {
|
||||||
|
return pgm_read_dword(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
36
lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp
Normal file
36
lib/ArduinoJson/src/ArduinoJson/Polyfills/preprocessor.hpp
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define ARDUINOJSON_EXPAND6(a, b, c, d, e, f) a, b, c, d, e, f
|
||||||
|
#define ARDUINOJSON_EXPAND7(a, b, c, d, e, f, g) a, b, c, d, e, f, g
|
||||||
|
#define ARDUINOJSON_EXPAND9(a, b, c, d, e, f, g, h, i) a, b, c, d, e, f, g, h, i
|
||||||
|
#define ARDUINOJSON_EXPAND18(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, \
|
||||||
|
q, r) \
|
||||||
|
a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r
|
||||||
|
|
||||||
|
#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_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)
|
||||||
@@ -1,32 +1,32 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
#include <stdint.h> // int8_t
|
#include <stdint.h> // int8_t
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
inline int safe_strcmp(const char* a, const char* b) {
|
inline int safe_strcmp(const char* a, const char* b) {
|
||||||
if (a == b)
|
if (a == b)
|
||||||
return 0;
|
return 0;
|
||||||
if (!a)
|
if (!a)
|
||||||
return -1;
|
return -1;
|
||||||
if (!b)
|
if (!b)
|
||||||
return 1;
|
return 1;
|
||||||
return strcmp(a, b);
|
return strcmp(a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int safe_strncmp(const char* a, const char* b, size_t n) {
|
inline int safe_strncmp(const char* a, const char* b, size_t n) {
|
||||||
if (a == b)
|
if (a == b)
|
||||||
return 0;
|
return 0;
|
||||||
if (!a)
|
if (!a)
|
||||||
return -1;
|
return -1;
|
||||||
if (!b)
|
if (!b)
|
||||||
return 1;
|
return 1;
|
||||||
return strncmp(a, b, n);
|
return strncmp(a, b, n);
|
||||||
}
|
}
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
34
lib/ArduinoJson/src/ArduinoJson/Polyfills/static_array.hpp
Normal file
34
lib/ArduinoJson/src/ArduinoJson/Polyfills/static_array.hpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ArduinoJson/Configuration.hpp>
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||||
|
|
||||||
|
#include <ArduinoJson/Polyfills/pgmspace_generic.hpp>
|
||||||
|
|
||||||
|
#ifndef ARDUINOJSON_DEFINE_STATIC_ARRAY
|
||||||
|
#define ARDUINOJSON_DEFINE_STATIC_ARRAY(type, name, value) \
|
||||||
|
static type const name[] PROGMEM = value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARDUINOJSON_READ_STATIC_ARRAY
|
||||||
|
#define ARDUINOJSON_READ_STATIC_ARRAY(type, name, index) \
|
||||||
|
pgm_read<type>(name + index)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else // i.e. ARDUINOJSON_ENABLE_PROGMEM == 0
|
||||||
|
|
||||||
|
#ifndef ARDUINOJSON_DEFINE_STATIC_ARRAY
|
||||||
|
#define ARDUINOJSON_DEFINE_STATIC_ARRAY(type, name, value) \
|
||||||
|
static type const name[] = value;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARDUINOJSON_READ_STATIC_ARRAY
|
||||||
|
#define ARDUINOJSON_READ_STATIC_ARRAY(type, name, index) name[index]
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,23 +1,24 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "type_traits/conditional.hpp"
|
#include "type_traits/conditional.hpp"
|
||||||
#include "type_traits/enable_if.hpp"
|
#include "type_traits/enable_if.hpp"
|
||||||
#include "type_traits/integral_constant.hpp"
|
#include "type_traits/integral_constant.hpp"
|
||||||
#include "type_traits/is_array.hpp"
|
#include "type_traits/is_array.hpp"
|
||||||
#include "type_traits/is_base_of.hpp"
|
#include "type_traits/is_base_of.hpp"
|
||||||
#include "type_traits/is_class.hpp"
|
#include "type_traits/is_class.hpp"
|
||||||
#include "type_traits/is_const.hpp"
|
#include "type_traits/is_const.hpp"
|
||||||
#include "type_traits/is_convertible.hpp"
|
#include "type_traits/is_convertible.hpp"
|
||||||
#include "type_traits/is_enum.hpp"
|
#include "type_traits/is_enum.hpp"
|
||||||
#include "type_traits/is_floating_point.hpp"
|
#include "type_traits/is_floating_point.hpp"
|
||||||
#include "type_traits/is_integral.hpp"
|
#include "type_traits/is_integral.hpp"
|
||||||
#include "type_traits/is_same.hpp"
|
#include "type_traits/is_pointer.hpp"
|
||||||
#include "type_traits/is_signed.hpp"
|
#include "type_traits/is_same.hpp"
|
||||||
#include "type_traits/is_unsigned.hpp"
|
#include "type_traits/is_signed.hpp"
|
||||||
#include "type_traits/make_unsigned.hpp"
|
#include "type_traits/is_unsigned.hpp"
|
||||||
#include "type_traits/remove_const.hpp"
|
#include "type_traits/make_unsigned.hpp"
|
||||||
#include "type_traits/remove_reference.hpp"
|
#include "type_traits/remove_const.hpp"
|
||||||
|
#include "type_traits/remove_reference.hpp"
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <bool Condition, class TrueType, class FalseType>
|
template <bool Condition, class TrueType, class FalseType>
|
||||||
struct conditional {
|
struct conditional {
|
||||||
typedef TrueType type;
|
typedef TrueType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class TrueType, class FalseType>
|
template <class TrueType, class FalseType>
|
||||||
struct conditional<false, TrueType, FalseType> {
|
struct conditional<false, TrueType, FalseType> {
|
||||||
typedef FalseType type;
|
typedef FalseType type;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T declval();
|
T declval();
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// A meta-function that return the type T if Condition is true.
|
// A meta-function that return the type T if Condition is true.
|
||||||
template <bool Condition, typename T = void>
|
template <bool Condition, typename T = void>
|
||||||
struct enable_if {};
|
struct enable_if {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct enable_if<true, T> {
|
struct enable_if<true, T> {
|
||||||
typedef T type;
|
typedef T type;
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename T, T v>
|
template <typename T, T v>
|
||||||
struct integral_constant {
|
struct integral_constant {
|
||||||
static const T value = v;
|
static const T value = v;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef integral_constant<bool, true> true_type;
|
typedef integral_constant<bool, true> true_type;
|
||||||
typedef integral_constant<bool, false> false_type;
|
typedef integral_constant<bool, false> false_type;
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,21 +1,21 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
#include <stddef.h> // size_t
|
#include <stddef.h> // size_t
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_array : false_type {};
|
struct is_array : false_type {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_array<T[]> : true_type {};
|
struct is_array<T[]> : true_type {};
|
||||||
|
|
||||||
template <typename T, size_t N>
|
template <typename T, size_t N>
|
||||||
struct is_array<T[N]> : true_type {};
|
struct is_array<T[N]> : true_type {};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Namespace.hpp>
|
#include <ArduinoJson/Namespace.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// A meta-function that returns true if Derived inherits from TBase is an
|
// A meta-function that returns true if Derived inherits from TBase is an
|
||||||
// integral type.
|
// integral type.
|
||||||
template <typename TBase, typename TDerived>
|
template <typename TBase, typename TDerived>
|
||||||
class is_base_of {
|
class is_base_of {
|
||||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||||
typedef char Yes[1];
|
typedef char Yes[1];
|
||||||
typedef char No[2];
|
typedef char No[2];
|
||||||
|
|
||||||
static Yes &probe(const TBase *);
|
static Yes &probe(const TBase *);
|
||||||
static No &probe(...);
|
static No &probe(...);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool value =
|
static const bool value =
|
||||||
sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes);
|
sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes);
|
||||||
};
|
};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,26 +1,26 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "declval.hpp"
|
#include "declval.hpp"
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_class {
|
struct is_class {
|
||||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||||
typedef char Yes[1];
|
typedef char Yes[1];
|
||||||
typedef char No[2];
|
typedef char No[2];
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
static Yes &probe(void (U::*)(void));
|
static Yes &probe(void (U::*)(void));
|
||||||
template <typename>
|
template <typename>
|
||||||
static No &probe(...);
|
static No &probe(...);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const bool value = sizeof(probe<T>(0)) == sizeof(Yes);
|
static const bool value = sizeof(probe<T>(0)) == sizeof(Yes);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
// ArduinoJson - arduinojson.org
|
||||||
// Copyright Benoit Blanchon 2014-2020
|
// Copyright Benoit Blanchon 2014-2020
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "integral_constant.hpp"
|
#include "integral_constant.hpp"
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
// A meta-function that return the type T without the const modifier
|
// A meta-function that return the type T without the const modifier
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_const : false_type {};
|
struct is_const : false_type {};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct is_const<const T> : true_type {};
|
struct is_const<const T> : true_type {};
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // 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