mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-28 01:37:34 +02:00
Compare commits
51 Commits
v6.8.0-bet
...
v6.10.1
Author | SHA1 | Date | |
---|---|---|---|
0588e578d5 | |||
12f9aac4ea | |||
81bb3fce97 | |||
6011a2f51a | |||
6071bd07ec | |||
1c814d3bb6 | |||
9862048a58 | |||
ebc52a5a65 | |||
eacad922df | |||
d910996613 | |||
2fc220fa33 | |||
8cabda551d | |||
afd033e9c9 | |||
6ec5ba521b | |||
c8e49a7e4e | |||
dee8c8e242 | |||
576543c4b4 | |||
746f2882f7 | |||
c4cbf9d0bb | |||
49bd51b5f9 | |||
e53ae0f9bb | |||
afdd913a2f | |||
3df4efd512 | |||
91dd45c387 | |||
136ee0d576 | |||
1ea8d92cc3 | |||
20fcb99830 | |||
f3265d2111 | |||
d6e7709866 | |||
d11019d9e1 | |||
cfd924622e | |||
27c08b785d | |||
77f38e4449 | |||
16ddfbc4e0 | |||
8dea900869 | |||
f342dee2b4 | |||
1d5721f3bd | |||
3170558d6d | |||
3530aa88d6 | |||
21998890d4 | |||
c9d6bd76c9 | |||
bc2ce178ea | |||
e22e62d184 | |||
4181de119c | |||
56bf24e1ec | |||
e9b4c6289b | |||
7ed92bebd3 | |||
c3f71c1a99 | |||
7050ef675d | |||
070cd5b6c0 | |||
2c2cc33c94 |
120
.travis.yml
120
.travis.yml
@ -2,122 +2,124 @@ sudo: false
|
||||
language: cpp
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
addons:
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.4']
|
||||
env: SCRIPT=test _CC=gcc-4.4 _CXX=g++-4.4
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.6']
|
||||
env: SCRIPT=cmake GCC=4.6
|
||||
- compiler: gcc
|
||||
addons:
|
||||
env: SCRIPT=test _CC=gcc-4.6 _CXX=g++-4.6
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.7']
|
||||
env: SCRIPT=cmake GCC=4.7
|
||||
- compiler: gcc
|
||||
addons:
|
||||
env: SCRIPT=test _CC=gcc-4.7 _CXX=g++-4.7
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.8']
|
||||
env: SCRIPT=cmake GCC=4.8 SANITIZE=address
|
||||
- compiler: gcc
|
||||
addons:
|
||||
env: SCRIPT=test _CC=gcc-4.8 _CXX=g++-4.8 SANITIZE=address
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.9']
|
||||
env: SCRIPT=cmake GCC=4.9 SANITIZE=leak
|
||||
- compiler: gcc
|
||||
addons:
|
||||
env: SCRIPT=test _CC=gcc-4.9 _CXX=g++-4.9 SANITIZE=leak
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5']
|
||||
env: SCRIPT=cmake GCC=5 # SANITIZE=undefined
|
||||
- compiler: gcc
|
||||
addons:
|
||||
env: SCRIPT=test _CC=gcc-5 _CXX=g++-5 # SANITIZE=undefined
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-6']
|
||||
env: SCRIPT=cmake GCC=6
|
||||
- compiler: gcc
|
||||
addons:
|
||||
env: SCRIPT=test _CC=gcc-6 _CXX=g++-6
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-7']
|
||||
env: SCRIPT=cmake GCC=7
|
||||
- compiler: clang
|
||||
env: SCRIPT=cmake
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=gcc-7 _CXX=g++-7
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-8']
|
||||
env: SCRIPT=test _CC=gcc-8 _CXX=g++-8
|
||||
- addons:
|
||||
apt:
|
||||
packages: ['g++-arm-linux-gnueabihf']
|
||||
env: SCRIPT=build _CC=arm-linux-gnueabihf-gcc _CXX=arm-linux-gnueabihf-g++
|
||||
- env: SCRIPT=test _CC=clang _CXX=clang++
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
|
||||
packages: ['clang-3.5']
|
||||
env: SCRIPT=cmake CLANG=3.5 SANITIZE=address
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=clang-3.5 _CXX=clang++-3.5 SANITIZE=address
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
|
||||
packages: ['clang-3.6']
|
||||
env: SCRIPT=cmake CLANG=3.6 SANITIZE=leak
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=clang-3.6 _CXX=clang++-3.6 SANITIZE=leak
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
|
||||
packages: ['clang-3.7']
|
||||
env: SCRIPT=cmake CLANG=3.7
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=clang-3.7 _CXX=clang++-3.7
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
|
||||
packages: ['clang-3.8']
|
||||
env: SCRIPT=cmake CLANG=3.8 SANITIZE=undefined
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=clang-3.8 _CXX=clang++-3.8 SANITIZE=undefined
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-3.9']
|
||||
packages: ['clang-3.9']
|
||||
env: SCRIPT=cmake CLANG=3.9
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=clang-3.9 _CXX=clang++-3.9
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-4.0']
|
||||
packages: ['clang-4.0']
|
||||
env: SCRIPT=cmake CLANG=4.0
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=clang-4.0 _CXX=clang++-4.0
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-5.0']
|
||||
packages: ['clang-5.0']
|
||||
env: SCRIPT=cmake CLANG=5.0
|
||||
- compiler: clang
|
||||
addons:
|
||||
env: SCRIPT=test _CC=clang-5.0 _CXX=clang++-5.0
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-6.0']
|
||||
packages: ['clang-6.0']
|
||||
env: SCRIPT=cmake CLANG=6.0
|
||||
- compiler: gcc
|
||||
env: SCRIPT=coverage
|
||||
env: SCRIPT=test _CC=clang-6.0 _CXX=clang++-6.0
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-7']
|
||||
packages: ['clang-7']
|
||||
env: SCRIPT=test _CC=clang-7 _CXX=clang++-7
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-8']
|
||||
packages: ['clang-8']
|
||||
env: SCRIPT=test _CC=clang-8 _CXX=clang++-8
|
||||
- env: SCRIPT=coverage
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake
|
||||
env: SCRIPT=test
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake
|
||||
env: SCRIPT=test
|
||||
- os: osx
|
||||
osx_image: xcode9.4
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake
|
||||
env: SCRIPT=test
|
||||
- os: osx
|
||||
osx_image: xcode10
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake SANITIZE=address
|
||||
env: SCRIPT=test SANITIZE=address
|
||||
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.8.2 BOARD=arduino:samd:mkr1000
|
||||
- env: SCRIPT=platformio BOARD=uno
|
||||
- env: SCRIPT=platformio BOARD=esp01
|
||||
- compiler: clang
|
||||
addons:
|
||||
- addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-6.0']
|
||||
packages: ['clang-6.0','llvm-6.0']
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#include "src/ArduinoJson.h"
|
||||
|
49
CHANGELOG.md
49
CHANGELOG.md
@ -1,6 +1,55 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
v6.10.1 (2019-04-23)
|
||||
-------
|
||||
|
||||
* Fixed error "attributes are not allowed on a function-definition"
|
||||
* Fixed `deserializeJson()` not being picky enough (issue #969)
|
||||
* Fixed error "no matching function for call to write(uint8_t)" (issue #972)
|
||||
|
||||
v6.10.0 (2019-03-22)
|
||||
-------
|
||||
|
||||
* Fixed an integer overflow in the JSON deserializer
|
||||
* Added overflow handling in `JsonVariant::as<T>()` and `JsonVariant::is<T>()`.
|
||||
- `as<T>()` returns `0` if the integer `T` overflows
|
||||
- `is<T>()` returns `false` if the integer `T` overflows
|
||||
* Added `BasicJsonDocument` to support custom allocator (issue #876)
|
||||
* Added `JsonDocument::containsKey()` (issue #938)
|
||||
* Added `JsonVariant::containsKey()`
|
||||
|
||||
v6.9.1 (2019-03-01)
|
||||
------
|
||||
|
||||
* Fixed warning "unused variable" with GCC 4.4 (issue #912)
|
||||
* Fixed warning "cast increases required alignment" (issue #914)
|
||||
* Fixed warning "conversion may alter value" (issue #914)
|
||||
* Fixed naming conflict with "CAPACITY" (issue #839)
|
||||
* Muted warning "will change in GCC 7.1" (issue #914)
|
||||
* Added a clear error message for `StaticJsonBuffer` and `DynamicJsonBuffer`
|
||||
* Marked ArduinoJson.h as a "system header"
|
||||
|
||||
v6.9.0 (2019-02-26)
|
||||
------
|
||||
|
||||
* Decode escaped Unicode characters like \u00DE (issue #304, PR #791)
|
||||
Many thanks to Daniel Schulte (aka @trilader) who implemented this feature.
|
||||
* Added option ARDUINOJSON_DECODE_UNICODE to enable it
|
||||
* Converted `JsonArray::copyFrom()/copyTo()` to free functions `copyArray()`
|
||||
* Renamed `JsonArray::copyFrom()` and `JsonObject::copyFrom()` to `set()`
|
||||
* Renamed `JsonArray::get()` to `getElement()`
|
||||
* Renamed `JsonArray::add()` (without arg) to `addElement()`
|
||||
* Renamed `JsonObject::get()` to `getMember()`
|
||||
* Renamed `JsonObject::getOrCreate()` to `getOrAddMember()`
|
||||
* Fixed `JsonVariant::isNull()` not returning `true` after `set((char*)0)`
|
||||
* Fixed segfault after `variant.set(serialized((char*)0))`
|
||||
* Detect `IncompleteInput` in `false`, `true`, and `null`
|
||||
* Added `JsonDocument::size()`
|
||||
* Added `JsonDocument::remove()`
|
||||
* Added `JsonVariant::clear()`
|
||||
* Added `JsonVariant::remove()`
|
||||
|
||||
v6.8.0-beta (2019-01-30)
|
||||
-----------
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# ArduinoJson - arduinojson.org
|
||||
# Copyright Benoit Blanchon 2014-2018
|
||||
# Copyright Benoit Blanchon 2014-2019
|
||||
# MIT License
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
|
@ -1,7 +1,7 @@
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright © 2014-2018 Benoit BLANCHON
|
||||
Copyright © 2014-2019 Benoit BLANCHON
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
|
18
README.md
18
README.md
@ -2,7 +2,7 @@
|
||||
|
||||
---
|
||||
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.7.0-beta)
|
||||
[](https://www.ardu-badge.com/ArduinoJson/6.10.1)
|
||||
[](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
|
||||
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||
[](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
|
||||
@ -67,11 +67,10 @@ char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302
|
||||
DynamicJsonDocument doc(1024);
|
||||
deserializeJson(doc, json);
|
||||
|
||||
JsonObjectRef root = doc.as<JsonObject>();
|
||||
const char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
const char* sensor = doc["sensor"];
|
||||
long time = doc["time"];
|
||||
double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
```
|
||||
|
||||
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_source=github&utm_medium=readme)
|
||||
@ -83,11 +82,10 @@ Here is a program that generates a JSON document with ArduinoJson:
|
||||
```c++
|
||||
DynamicJsonDocument doc(1024);
|
||||
|
||||
JsonObject root = doc.to<JsonObject>();
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
doc["sensor"] = "gps";
|
||||
doc["time"] = 1351824120;
|
||||
|
||||
JsonArray data = root.createNestedArray("data");
|
||||
JsonArray data = doc.createNestedArray("data");
|
||||
data.add(48.756080);
|
||||
data.add(2.302038);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
version: 6.4.0.{build}
|
||||
version: 6.10.1.{build}
|
||||
environment:
|
||||
matrix:
|
||||
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to store your project configuration in a file.
|
||||
@ -10,6 +10,8 @@
|
||||
// "hostname": "examples.com",
|
||||
// "port": 2731
|
||||
// }
|
||||
//
|
||||
// https://arduinojson.org/v6/example/config/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <SD.h>
|
||||
@ -19,7 +21,8 @@
|
||||
//
|
||||
// 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.
|
||||
// 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;
|
||||
@ -130,4 +133,15 @@ void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/config/ for more.
|
||||
// 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,8 +1,10 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to generate a JSON document with ArduinoJson.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/generator/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
@ -61,4 +63,15 @@ void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/generator/ for more.
|
||||
// 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,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to parse a JSON document in an HTTP response.
|
||||
@ -15,6 +15,8 @@
|
||||
// 2.302038
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// https://arduinojson.org/v6/example/http-client/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <Ethernet.h>
|
||||
@ -98,4 +100,16 @@ void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/http-client/ for more.
|
||||
// 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,8 +1,10 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to deserialize a JSON document with ArduinoJson.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/parser/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
@ -64,4 +66,15 @@ void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/parser/ for more.
|
||||
// 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,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to implement an HTTP server that sends a JSON document
|
||||
@ -12,6 +12,8 @@
|
||||
// "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>
|
||||
@ -94,4 +96,15 @@ void loop() {
|
||||
client.stop();
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/http-server/ for more.
|
||||
// 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,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to send a JSON document to a UDP socket.
|
||||
@ -16,6 +16,8 @@
|
||||
// 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>
|
||||
@ -84,4 +86,15 @@ void loop() {
|
||||
delay(10000);
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/udp-beacon/ for more.
|
||||
// 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,9 +1,11 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to deserialize a MessagePack document with
|
||||
// ArduinoJson.
|
||||
//
|
||||
// https://arduinojson.org/v6/example/msgpack-parser/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
@ -71,5 +73,3 @@ void setup() {
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/msgpack-parser/ for more.
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows the different ways you can use Flash strings with
|
||||
@ -8,6 +8,8 @@
|
||||
// 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>
|
||||
|
||||
@ -17,7 +19,7 @@ void setup() {
|
||||
DynamicJsonDocument doc(1024);
|
||||
|
||||
// You can use a Flash String as your JSON input.
|
||||
// WARNING: the string in the input will be duplicated in the JsonDocument.
|
||||
// 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>();
|
||||
@ -56,4 +58,15 @@ void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/progmem/ for more.
|
||||
// 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,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows the different ways you can use String with ArduinoJson.
|
||||
@ -7,6 +7,8 @@
|
||||
// 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>
|
||||
|
||||
@ -62,4 +64,14 @@ void loop() {
|
||||
// not used in this example
|
||||
}
|
||||
|
||||
// Visit https://arduinojson.org/v6/example/string/ for more.
|
||||
// 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,5 +1,5 @@
|
||||
# ArduinoJson - arduinojson.org
|
||||
# Copyright Benoit Blanchon 2014-2018
|
||||
# Copyright Benoit Blanchon 2014-2019
|
||||
# MIT License
|
||||
|
||||
if(MSVC)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
// This file is NOT use by Google's OSS fuzz
|
||||
|
1
fuzzing/json_seed_corpus/IntegerOverflow.json
Normal file
1
fuzzing/json_seed_corpus/IntegerOverflow.json
Normal file
@ -0,0 +1 @@
|
||||
9720730739393920739
|
@ -7,7 +7,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "6.8.0-beta",
|
||||
"version": "6.10.1",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "https://blog.benoitblanchon.fr"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=6.8.0-beta
|
||||
version=6.10.1
|
||||
author=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
sentence=An efficient and elegant JSON library for Arduino.
|
||||
|
@ -18,12 +18,16 @@ update_version_in_source () {
|
||||
|
||||
sed -i~ -bE "4s/HEAD/$TAG ($DATE)/; 5s/-+/$UNDERLINE/" CHANGELOG.md
|
||||
rm CHANGELOG.md*~
|
||||
|
||||
sed -i~ -bE "s/\"version\":.*$/\"version\": \"$VERSION\",/" library.json
|
||||
rm library.json*~
|
||||
|
||||
sed -i~ -bE "s/version=.*$/version=$VERSION/" library.properties
|
||||
rm library.properties*~
|
||||
|
||||
sed -i~ -bE "s/version: .*$/version: $VERSION.{build}/" appveyor.yml
|
||||
rm appveyor.yml*~
|
||||
|
||||
sed -i~ -bE \
|
||||
-e "s/ARDUINOJSON_VERSION .*$/ARDUINOJSON_VERSION \"$VERSION\"/" \
|
||||
-e "s/ARDUINOJSON_VERSION_MAJOR .*$/ARDUINOJSON_VERSION_MAJOR $MAJOR/" \
|
||||
@ -34,7 +38,7 @@ update_version_in_source () {
|
||||
}
|
||||
|
||||
commit_new_version () {
|
||||
git add src/ArduinoJson/version.hpp CHANGELOG.md library.json library.properties
|
||||
git add src/ArduinoJson/version.hpp README.md CHANGELOG.md library.json library.properties appveyor.yml
|
||||
git commit -m "Set version to $VERSION"
|
||||
}
|
||||
|
||||
|
14
scripts/travis/build.sh
Executable file
14
scripts/travis/build.sh
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
export CC="$_CC"
|
||||
export CXX="$_CXX"
|
||||
|
||||
if [ -n "$SANITIZE" ]; then
|
||||
export CXXFLAGS="-fsanitize=$SANITIZE"
|
||||
BUILD_TYPE="Debug"
|
||||
else
|
||||
BUILD_TYPE="Release"
|
||||
fi
|
||||
|
||||
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .
|
||||
cmake --build .
|
@ -1,30 +0,0 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
if [ $(uname) = 'Darwin' ]; then
|
||||
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Darwin-x86_64.tar.gz
|
||||
CMAKE=/tmp/CMake.app/Contents/bin/cmake
|
||||
CTEST=/tmp/CMake.app/Contents/bin/ctest
|
||||
else
|
||||
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Linux-x86_64.tar.gz
|
||||
CMAKE=/tmp/bin/cmake
|
||||
CTEST=/tmp/bin/ctest
|
||||
fi
|
||||
curl -sS $URL | tar xz -C /tmp --strip 1
|
||||
|
||||
if [ -n "$GCC" ]; then
|
||||
export CC="gcc-$GCC"
|
||||
export CXX="g++-$GCC"
|
||||
fi
|
||||
|
||||
if [ -n "$CLANG" ]; then
|
||||
export CC="clang-$CLANG"
|
||||
export CXX="clang++-$CLANG"
|
||||
fi
|
||||
|
||||
if [ -n "$SANITIZE" ]; then
|
||||
export CXXFLAGS="-fsanitize=$SANITIZE"
|
||||
fi
|
||||
|
||||
$CMAKE .
|
||||
$CMAKE --build .
|
||||
$CTEST --output-on-failure .
|
@ -1,8 +1,6 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1
|
||||
|
||||
/tmp/bin/cmake -DCOVERAGE=true .
|
||||
cmake -DCOVERAGE=true .
|
||||
make
|
||||
make test
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
ROOT_DIR=$(dirname $0)/../../
|
||||
INCLUDE_DIR=${ROOT_DIR}/src/
|
||||
FUZZING_DIR=${ROOT_DIR}/fuzzing/
|
||||
CXXFLAGS="-g -fprofile-instr-generate -fcoverage-mapping -fsanitize=address,fuzzer"
|
||||
CXXFLAGS="-g -fprofile-instr-generate -fcoverage-mapping -fsanitize=address,undefined,fuzzer -fno-sanitize-recover=all"
|
||||
|
||||
fuzz() {
|
||||
NAME="$1"
|
||||
|
@ -4,6 +4,18 @@ pip install --user platformio
|
||||
|
||||
rm -r test
|
||||
|
||||
case $BOARD in
|
||||
uno)
|
||||
platformio lib install 868 # SD library
|
||||
platformio lib install 872 # Ethernet library
|
||||
;;
|
||||
esp01)
|
||||
platformio lib uninstall 161 || true
|
||||
platformio lib uninstall 868 || true
|
||||
platformio lib uninstall 872 || true
|
||||
;;
|
||||
esac
|
||||
|
||||
for EXAMPLE in $PWD/examples/*/*.ino;
|
||||
do
|
||||
platformio ci $EXAMPLE -l '.' -b $BOARD
|
||||
|
4
scripts/travis/test.sh
Executable file
4
scripts/travis/test.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh -ex
|
||||
|
||||
"$(dirname "$0")/build.sh"
|
||||
ctest --output-on-failure .
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to generate a JSON document with ArduinoJson.
|
||||
@ -8,11 +8,11 @@
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
int main() {
|
||||
// The JSON document
|
||||
// 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/assistant to compute the capacity.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<200> doc;
|
||||
|
||||
// StaticJsonObject allocates memory on the stack, it can be
|
||||
@ -20,30 +20,35 @@ int main() {
|
||||
//
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// Make our document be an object
|
||||
JsonObject root = doc.to<JsonObject>();
|
||||
|
||||
// Add values in the object
|
||||
// StaticJsonObject allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonDocument which allocates in the heap.
|
||||
//
|
||||
// Most of the time, you can rely on the implicit casts.
|
||||
// In other case, you can do root.set<long>("time", 1351824120);
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// Add values in the document
|
||||
//
|
||||
doc["sensor"] = "gps";
|
||||
doc["time"] = 1351824120;
|
||||
|
||||
// Add an array.
|
||||
//
|
||||
JsonArray data = root.createNestedArray("data");
|
||||
JsonArray data = doc.createNestedArray("data");
|
||||
data.add(48.756080);
|
||||
data.add(2.302038);
|
||||
|
||||
serializeJson(root, std::cout);
|
||||
// This prints:
|
||||
// Generate the minified JSON and send it to STDOUT
|
||||
//
|
||||
serializeJson(doc, std::cout);
|
||||
// The above line prints:
|
||||
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
|
||||
// Start a new line
|
||||
std::cout << std::endl;
|
||||
|
||||
serializeJsonPretty(root, std::cout);
|
||||
// This prints:
|
||||
// Generate the prettified JSON and send it to STDOUT
|
||||
//
|
||||
serializeJsonPretty(doc, std::cout);
|
||||
// The above line prints:
|
||||
// {
|
||||
// "sensor": "gps",
|
||||
// "time": 1351824120,
|
||||
@ -52,6 +57,4 @@ int main() {
|
||||
// 2.302038
|
||||
// ]
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to deserialize a JSON document with ArduinoJson.
|
||||
@ -8,23 +8,26 @@
|
||||
#include "ArduinoJson.h"
|
||||
|
||||
int main() {
|
||||
// Root JSON object
|
||||
// Allocate the JSON document
|
||||
//
|
||||
// Inside the brackets, 300 is the size of the memory pool in bytes.
|
||||
// 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/assistant to compute the capacity.
|
||||
// Use arduinojson.org/v6/assistant to compute the capacity.
|
||||
StaticJsonDocument<300> doc;
|
||||
|
||||
// StaticJsonDocument<N> allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonObject which allocates in the heap.
|
||||
// replaced by DynamicJsonDocument which allocates in the heap.
|
||||
//
|
||||
// DynamicJsonObject doc(200);
|
||||
// DynamicJsonDocument doc(200);
|
||||
|
||||
// JSON input string.
|
||||
//
|
||||
// It's better to use a char[] as shown here.
|
||||
// If you use a const char* or a String, ArduinoJson will
|
||||
// have to make a copy of the input in the JsonBuffer.
|
||||
// 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]}";
|
||||
|
||||
@ -37,17 +40,14 @@ int main() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the root object in the document
|
||||
JsonObject root = doc.as<JsonObject>();
|
||||
|
||||
// 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 = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
const char* sensor = doc["sensor"];
|
||||
long time = doc["time"];
|
||||
double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
|
||||
// Print values.
|
||||
std::cout << sensor << std::endl;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
//
|
||||
// This example shows how to generate a JSON document with ArduinoJson.
|
||||
@ -49,17 +49,14 @@ int main() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the root object in the document
|
||||
JsonObject root = doc.as<JsonObject>();
|
||||
|
||||
// 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 = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
const char* sensor = doc["sensor"];
|
||||
long time = doc["time"];
|
||||
double latitude = doc["data"][0];
|
||||
double longitude = doc["data"][1];
|
||||
|
||||
// Print values.
|
||||
std::cout << sensor << std::endl;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,9 +1,17 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINOJSON_DEBUG
|
||||
#ifdef __clang__
|
||||
#pragma clang system_header
|
||||
#elif defined __GNUC__
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ArduinoJson/Namespace.hpp"
|
||||
|
||||
#include "ArduinoJson/Array/ArrayRef.hpp"
|
||||
@ -15,6 +23,7 @@
|
||||
|
||||
#include "ArduinoJson/Array/ArrayImpl.hpp"
|
||||
#include "ArduinoJson/Array/ElementProxy.hpp"
|
||||
#include "ArduinoJson/Array/Utilities.hpp"
|
||||
#include "ArduinoJson/Collection/CollectionImpl.hpp"
|
||||
#include "ArduinoJson/Object/MemberProxy.hpp"
|
||||
#include "ArduinoJson/Object/ObjectImpl.hpp"
|
||||
@ -27,6 +36,8 @@
|
||||
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp"
|
||||
|
||||
#include "ArduinoJson/compatibility.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray;
|
||||
@ -39,6 +50,8 @@ typedef ARDUINOJSON_NAMESPACE::String JsonString;
|
||||
typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst;
|
||||
typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant;
|
||||
using ARDUINOJSON_NAMESPACE::BasicJsonDocument;
|
||||
using ARDUINOJSON_NAMESPACE::copyArray;
|
||||
using ARDUINOJSON_NAMESPACE::DeserializationError;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeJson;
|
||||
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -11,12 +11,12 @@ namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TArray>
|
||||
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
|
||||
return impl()->add().template to<ArrayRef>();
|
||||
return impl()->addElement().template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TArray>
|
||||
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
|
||||
return impl()->add().template to<ObjectRef>();
|
||||
return impl()->addElement().template to<ObjectRef>();
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -23,7 +23,8 @@ template <typename TData>
|
||||
class ArrayRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(_data));
|
||||
const void* data = _data; // prevent warning cast-align
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
@ -77,6 +78,10 @@ class ArrayConstRef : public ArrayRefBase<const CollectionData>,
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data ? _data->get(index) : 0);
|
||||
}
|
||||
};
|
||||
@ -94,15 +99,15 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
|
||||
: base_type(data), _pool(pool) {}
|
||||
|
||||
operator VariantRef() {
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(_data));
|
||||
void* data = _data; // prevent warning cast-align
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||
}
|
||||
|
||||
operator ArrayConstRef() const {
|
||||
return ArrayConstRef(_data);
|
||||
}
|
||||
|
||||
using ArrayShortcuts::add;
|
||||
VariantRef add() const {
|
||||
VariantRef addElement() const {
|
||||
return VariantRef(_pool, arrayAdd(_data, _pool));
|
||||
}
|
||||
|
||||
@ -115,71 +120,18 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
|
||||
return iterator();
|
||||
}
|
||||
|
||||
// Imports a 1D array
|
||||
template <typename T, size_t N>
|
||||
FORCE_INLINE bool copyFrom(T (&array)[N]) const {
|
||||
return copyFrom(array, N);
|
||||
}
|
||||
|
||||
// Imports a 1D array
|
||||
template <typename T>
|
||||
bool copyFrom(T* array, size_t len) const {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ok &= add(array[i]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Imports a 2D array
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
bool copyFrom(T (&array)[N1][N2]) const {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < N1; i++) {
|
||||
ArrayRef nestedArray = createNestedArray();
|
||||
for (size_t j = 0; j < N2; j++) {
|
||||
ok &= nestedArray.add(array[i][j]);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Copy a ArrayRef
|
||||
FORCE_INLINE bool copyFrom(ArrayConstRef src) const {
|
||||
FORCE_INLINE bool set(ArrayConstRef src) const {
|
||||
if (!_data || !src._data) return false;
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
// Exports a 1D array
|
||||
template <typename T, size_t N>
|
||||
FORCE_INLINE size_t copyTo(T (&array)[N]) const {
|
||||
return copyTo(array, N);
|
||||
}
|
||||
|
||||
// Exports a 1D array
|
||||
template <typename T>
|
||||
size_t copyTo(T* array, size_t len) const {
|
||||
size_t i = 0;
|
||||
for (iterator it = begin(); it != end() && i < len; ++it) array[i++] = *it;
|
||||
return i;
|
||||
}
|
||||
|
||||
// Exports a 2D array
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
void copyTo(T (&array)[N1][N2]) const {
|
||||
if (!_data) return;
|
||||
size_t i = 0;
|
||||
for (iterator it = begin(); it != end() && i < N1; ++it) {
|
||||
it->as<ArrayRef>().copyTo(array[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE bool operator==(ArrayRef rhs) const {
|
||||
return arrayEquals(_data, rhs._data);
|
||||
}
|
||||
|
||||
// Gets the value at the specified index.
|
||||
FORCE_INLINE VariantRef get(size_t index) const {
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return VariantRef(_pool, _data ? _data->get(index) : 0);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -29,14 +29,14 @@ class ArrayShortcuts {
|
||||
// std::string, String, ObjectRef
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(const T &value) const {
|
||||
return impl()->add().set(value);
|
||||
return impl()->addElement().set(value);
|
||||
}
|
||||
//
|
||||
// bool add(TValue);
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(T *value) const {
|
||||
return impl()->add().set(value);
|
||||
return impl()->addElement().set(value);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -24,7 +24,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
: _array(array), _index(index) {}
|
||||
|
||||
FORCE_INLINE this_type& operator=(const this_type& src) {
|
||||
getElement().set(src.as<VariantConstRef>());
|
||||
getUpstreamElement().set(src.as<VariantConstRef>());
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(const T& src) {
|
||||
getElement().set(src);
|
||||
getUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
//
|
||||
@ -43,27 +43,31 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename T>
|
||||
FORCE_INLINE this_type& operator=(T* src) {
|
||||
getElement().set(src);
|
||||
getUpstreamElement().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamElement().clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return getElement().isNull();
|
||||
return getUpstreamElement().isNull();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename VariantAs<T>::type as() const {
|
||||
return getElement().template as<T>();
|
||||
return getUpstreamElement().template as<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE bool is() const {
|
||||
return getElement().template is<T>();
|
||||
return getUpstreamElement().template is<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename VariantTo<T>::type to() const {
|
||||
return getElement().template to<T>();
|
||||
return getUpstreamElement().template to<T>();
|
||||
}
|
||||
|
||||
// Replaces the value
|
||||
@ -73,53 +77,75 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
|
||||
// std::string, String, ArrayRef, ObjectRef
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue& value) const {
|
||||
return getElement().set(value);
|
||||
return getUpstreamElement().set(value);
|
||||
}
|
||||
//
|
||||
// bool set(TValue)
|
||||
// TValue = char*, const char*, const __FlashStringHelper*
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(TValue* value) const {
|
||||
return getElement().set(value);
|
||||
return getUpstreamElement().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor& visitor) const {
|
||||
return getElement().accept(visitor);
|
||||
return getUpstreamElement().accept(visitor);
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return getElement().size();
|
||||
return getUpstreamElement().size();
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef get(TNestedKey* key) const {
|
||||
return getElement().get(key);
|
||||
VariantRef getMember(TNestedKey* key) const {
|
||||
return getUpstreamElement().getMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef get(const TNestedKey& key) const {
|
||||
return getElement().get(key);
|
||||
VariantRef getMember(const TNestedKey& key) const {
|
||||
return getUpstreamElement().getMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrCreate(TNestedKey* key) const {
|
||||
return getElement().getOrCreate(key);
|
||||
VariantRef getOrAddMember(TNestedKey* key) const {
|
||||
return getUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
template <typename TNestedKey>
|
||||
VariantRef getOrCreate(const TNestedKey& key) const {
|
||||
return getElement().getOrCreate(key);
|
||||
VariantRef getOrAddMember(const TNestedKey& key) const {
|
||||
return getUpstreamElement().getOrAddMember(key);
|
||||
}
|
||||
|
||||
using ArrayShortcuts<ElementProxy>::add;
|
||||
VariantRef add() const {
|
||||
return getElement().add();
|
||||
VariantRef addElement() const {
|
||||
return getUpstreamElement().addElement();
|
||||
}
|
||||
|
||||
VariantRef getElement(size_t index) const {
|
||||
return getUpstreamElement().getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
getUpstreamElement().remove(index);
|
||||
}
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||
TChar* key) const {
|
||||
getUpstreamElement().remove(key);
|
||||
}
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString& key) const {
|
||||
getUpstreamElement().remove(key);
|
||||
}
|
||||
|
||||
private:
|
||||
FORCE_INLINE VariantRef getElement() const {
|
||||
return _array.get(_index);
|
||||
FORCE_INLINE VariantRef getUpstreamElement() const {
|
||||
return _array.getElement(_index);
|
||||
}
|
||||
|
||||
TArray _array;
|
||||
|
66
src/ArduinoJson/Array/Utilities.hpp
Normal file
66
src/ArduinoJson/Array/Utilities.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ArrayRef.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Copy a 1D array to a JsonArray
|
||||
template <typename T, size_t N>
|
||||
inline bool copyArray(T (&src)[N], ArrayRef dst) {
|
||||
return copyArray(src, N, dst);
|
||||
}
|
||||
|
||||
// Copy a 1D array to a JsonArray
|
||||
template <typename T>
|
||||
inline bool copyArray(T* src, size_t len, ArrayRef dst) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ok &= dst.add(src[i]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Copy a 2D array to a JsonArray
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
inline bool copyArray(T (&src)[N1][N2], ArrayRef dst) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < N1; i++) {
|
||||
ArrayRef nestedArray = dst.createNestedArray();
|
||||
for (size_t j = 0; j < N2; j++) {
|
||||
ok &= nestedArray.add(src[i][j]);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Copy a JsonArray to a 1D array
|
||||
template <typename T, size_t N>
|
||||
inline size_t copyArray(ArrayConstRef src, T (&dst)[N]) {
|
||||
return copyArray(src, dst, N);
|
||||
}
|
||||
|
||||
// Copy a JsonArray to a 1D array
|
||||
template <typename T>
|
||||
inline size_t copyArray(ArrayConstRef src, T* dst, size_t len) {
|
||||
size_t i = 0;
|
||||
for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < len;
|
||||
++it)
|
||||
dst[i++] = *it;
|
||||
return i;
|
||||
}
|
||||
|
||||
// Copy a JsonArray to a 2D array
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
inline void copyArray(ArrayConstRef src, T (&dst)[N1][N2]) {
|
||||
size_t i = 0;
|
||||
for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < N1;
|
||||
++it) {
|
||||
copyArray(it->as<ArrayConstRef>(), dst[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -26,7 +26,7 @@ inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
|
||||
}
|
||||
|
||||
inline VariantData* CollectionData::add(MemoryPool* pool) {
|
||||
return addSlot(pool)->data();
|
||||
return slotData(addSlot(pool));
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -88,28 +88,38 @@
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
// Enable support for Arduino String
|
||||
// Enable support for Arduino's String class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||
#endif
|
||||
|
||||
// Enable support for Arduino Stream
|
||||
// Enable support for Arduino's Stream class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
||||
#endif
|
||||
|
||||
// Enable support for Arduino's Print class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
|
||||
#endif
|
||||
|
||||
#else // ARDUINO
|
||||
|
||||
// Disable support for Arduino String
|
||||
// Enable support for Arduino's String class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
||||
#endif
|
||||
|
||||
// Disable support for Arduino Stream
|
||||
// Enable support for Arduino's Stream class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
|
||||
#endif
|
||||
|
||||
// Enable support for Arduino's Print class
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
|
||||
#endif
|
||||
|
||||
#endif // ARDUINO
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_PROGMEM
|
||||
@ -120,6 +130,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Convert unicode escape sequence (\u0123) to UTF-8
|
||||
#ifndef ARDUINOJSON_DECODE_UNICODE
|
||||
#define ARDUINOJSON_DECODE_UNICODE 0
|
||||
#endif
|
||||
|
||||
// Control the exponentiation threshold for big numbers
|
||||
// CAUTION: cannot be more that 1e9 !!!!
|
||||
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
|
||||
@ -134,7 +149,7 @@
|
||||
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
||||
#if defined(_MSC_VER) || \
|
||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
||||
(defined(__LITTLE_ENDIAN__))
|
||||
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
|
||||
#define ARDUINOJSON_LITTLE_ENDIAN 1
|
||||
#else
|
||||
#define ARDUINOJSON_LITTLE_ENDIAN 0
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
89
src/ArduinoJson/Document/BasicJsonDocument.hpp
Normal file
89
src/ArduinoJson/Document/BasicJsonDocument.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonDocument.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TAllocator>
|
||||
class AllocatorOwner {
|
||||
protected:
|
||||
AllocatorOwner() {}
|
||||
AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {}
|
||||
AllocatorOwner(TAllocator allocator) : _allocator(allocator) {}
|
||||
|
||||
void* allocate(size_t n) {
|
||||
return _allocator.allocate(n);
|
||||
}
|
||||
|
||||
void deallocate(void* p) {
|
||||
_allocator.deallocate(p);
|
||||
}
|
||||
|
||||
private:
|
||||
TAllocator _allocator;
|
||||
};
|
||||
|
||||
template <typename TAllocator>
|
||||
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
|
||||
public:
|
||||
explicit BasicJsonDocument(size_t capa, TAllocator allocator = TAllocator())
|
||||
: AllocatorOwner<TAllocator>(allocator), JsonDocument(allocPool(capa)) {}
|
||||
|
||||
BasicJsonDocument(const BasicJsonDocument& src)
|
||||
: AllocatorOwner<TAllocator>(src),
|
||||
JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
BasicJsonDocument(const T& src,
|
||||
typename enable_if<IsVisitable<T>::value>::type* = 0)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
// disambiguate
|
||||
BasicJsonDocument(VariantRef src)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
~BasicJsonDocument() {
|
||||
freePool();
|
||||
}
|
||||
|
||||
BasicJsonDocument& operator=(const BasicJsonDocument& src) {
|
||||
reallocPoolIfTooSmall(src.memoryUsage());
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
BasicJsonDocument& operator=(const T& src) {
|
||||
reallocPoolIfTooSmall(src.memoryUsage());
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool allocPool(size_t requiredSize) {
|
||||
size_t capa = addPadding(requiredSize);
|
||||
return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa);
|
||||
}
|
||||
|
||||
void reallocPoolIfTooSmall(size_t requiredSize) {
|
||||
if (requiredSize <= capacity()) return;
|
||||
freePool();
|
||||
replacePool(allocPool(addPadding(requiredSize)));
|
||||
}
|
||||
|
||||
void freePool() {
|
||||
this->deallocate(memoryPool().buffer());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,70 +1,25 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonDocument.hpp"
|
||||
#include "BasicJsonDocument.hpp"
|
||||
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
class DynamicJsonDocument : public JsonDocument {
|
||||
public:
|
||||
explicit DynamicJsonDocument(size_t capa)
|
||||
: JsonDocument(allocPool(capa)) {}
|
||||
|
||||
DynamicJsonDocument(const DynamicJsonDocument& src)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
struct DefaultAllocator {
|
||||
void* allocate(size_t n) {
|
||||
return malloc(n);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DynamicJsonDocument(const T& src,
|
||||
typename enable_if<IsVisitable<T>::value>::type* = 0)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
// disambiguate
|
||||
DynamicJsonDocument(VariantRef src)
|
||||
: JsonDocument(allocPool(src.memoryUsage())) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
~DynamicJsonDocument() {
|
||||
freePool();
|
||||
}
|
||||
|
||||
DynamicJsonDocument& operator=(const DynamicJsonDocument& src) {
|
||||
reallocPoolIfTooSmall(src.memoryUsage());
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DynamicJsonDocument& operator=(const T& src) {
|
||||
reallocPoolIfTooSmall(src.memoryUsage());
|
||||
set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
MemoryPool allocPool(size_t requiredSize) {
|
||||
size_t capa = addPadding(requiredSize);
|
||||
return MemoryPool(reinterpret_cast<char*>(malloc(capa)), capa);
|
||||
}
|
||||
|
||||
void reallocPoolIfTooSmall(size_t requiredSize) {
|
||||
if (requiredSize <= capacity()) return;
|
||||
freePool();
|
||||
replacePool(allocPool(addPadding(requiredSize)));
|
||||
}
|
||||
|
||||
void freePool() {
|
||||
free(memoryPool().buffer());
|
||||
void deallocate(void* p) {
|
||||
free(p);
|
||||
}
|
||||
};
|
||||
|
||||
typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument;
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -57,6 +57,10 @@ class JsonDocument : public Visitable {
|
||||
return _pool.capacity();
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
return _data.size();
|
||||
}
|
||||
|
||||
bool set(const JsonDocument& src) {
|
||||
return to<VariantRef>().set(src.as<VariantRef>());
|
||||
}
|
||||
@ -83,7 +87,7 @@ class JsonDocument : public Visitable {
|
||||
}
|
||||
|
||||
ArrayRef createNestedArray() {
|
||||
return add().to<ArrayRef>();
|
||||
return addElement().to<ArrayRef>();
|
||||
}
|
||||
|
||||
// createNestedArray(char*)
|
||||
@ -91,18 +95,18 @@ class JsonDocument : public Visitable {
|
||||
// createNestedArray(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
ArrayRef createNestedArray(TChar* key) {
|
||||
return getOrCreate(key).template to<ArrayRef>();
|
||||
return getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
// createNestedArray(const std::string&)
|
||||
// createNestedArray(const String&)
|
||||
template <typename TString>
|
||||
ArrayRef createNestedArray(const TString& key) {
|
||||
return getOrCreate(key).template to<ArrayRef>();
|
||||
return getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
ObjectRef createNestedObject() {
|
||||
return add().to<ObjectRef>();
|
||||
return addElement().to<ObjectRef>();
|
||||
}
|
||||
|
||||
// createNestedObject(char*)
|
||||
@ -110,14 +114,29 @@ class JsonDocument : public Visitable {
|
||||
// createNestedObject(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
ObjectRef createNestedObject(TChar* key) {
|
||||
return getOrCreate(key).template to<ObjectRef>();
|
||||
return getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
// createNestedObject(const std::string&)
|
||||
// createNestedObject(const String&)
|
||||
template <typename TString>
|
||||
ObjectRef createNestedObject(const TString& key) {
|
||||
return getOrCreate(key).template to<ObjectRef>();
|
||||
return getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
bool containsKey(TChar* key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
bool containsKey(const TString& key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// operator[](const std::string&)
|
||||
@ -146,7 +165,7 @@ class JsonDocument : public Visitable {
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
operator[](const TString& key) const {
|
||||
return getVariant()[key];
|
||||
return getMember(key);
|
||||
}
|
||||
|
||||
// operator[](char*) const
|
||||
@ -156,7 +175,7 @@ class JsonDocument : public Visitable {
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
|
||||
operator[](TChar* key) const {
|
||||
return getVariant()[key];
|
||||
return getMember(key);
|
||||
}
|
||||
|
||||
FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
|
||||
@ -164,51 +183,72 @@ class JsonDocument : public Visitable {
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantConstRef operator[](size_t index) const {
|
||||
return VariantConstRef(_data.get(index));
|
||||
return getElement(index);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef get(size_t index) {
|
||||
return VariantRef(&_pool, _data.get(index));
|
||||
FORCE_INLINE VariantRef getElement(size_t index) {
|
||||
return VariantRef(&_pool, _data.getElement(index));
|
||||
}
|
||||
|
||||
// get(char*) const
|
||||
// get(const char*) const
|
||||
// get(const __FlashStringHelper*) const
|
||||
FORCE_INLINE VariantConstRef getElement(size_t index) const {
|
||||
return VariantConstRef(_data.getElement(index));
|
||||
}
|
||||
|
||||
// JsonVariantConst getMember(char*) const
|
||||
// JsonVariantConst getMember(const char*) const
|
||||
// JsonVariantConst getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef get(TChar* key) {
|
||||
return VariantRef(&_pool, _data.get(adaptString(key)));
|
||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// get(const std::string&) const
|
||||
// get(const String&) const
|
||||
// JsonVariantConst getMember(const std::string&) const
|
||||
// JsonVariantConst getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename enable_if<IsString<TString>::value, VariantConstRef>::type
|
||||
getMember(const TString& key) const {
|
||||
return VariantConstRef(_data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariant getMember(char*)
|
||||
// JsonVariant getMember(const char*)
|
||||
// JsonVariant getMember(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getMember(TChar* key) {
|
||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// JsonVariant getMember(const std::string&)
|
||||
// JsonVariant getMember(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
|
||||
get(const TString& key) {
|
||||
return VariantRef(&_pool, _data.get(adaptString(key)));
|
||||
getMember(const TString& key) {
|
||||
return VariantRef(&_pool, _data.getMember(adaptString(key)));
|
||||
}
|
||||
|
||||
// getOrCreate(char*)
|
||||
// getOrCreate(const char*)
|
||||
// getOrCreate(const __FlashStringHelper*)
|
||||
// getOrAddMember(char*)
|
||||
// getOrAddMember(const char*)
|
||||
// getOrAddMember(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrCreate(TChar* key) {
|
||||
return VariantRef(&_pool, _data.getOrCreate(adaptString(key), &_pool));
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) {
|
||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||
}
|
||||
|
||||
// getOrCreate(const std::string&)
|
||||
// getOrCreate(const String&)
|
||||
// getOrAddMember(const std::string&)
|
||||
// getOrAddMember(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrCreate(const TString& key) {
|
||||
return VariantRef(&_pool, _data.getOrCreate(adaptString(key), &_pool));
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) {
|
||||
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef add() {
|
||||
return VariantRef(&_pool, _data.add(&_pool));
|
||||
FORCE_INLINE VariantRef addElement() {
|
||||
return VariantRef(&_pool, _data.addElement(&_pool));
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool add(const TValue& value) {
|
||||
return add().set(value);
|
||||
return addElement().set(value);
|
||||
}
|
||||
|
||||
// add(char*) const
|
||||
@ -216,7 +256,26 @@ class JsonDocument : public Visitable {
|
||||
// add(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool add(TChar* value) {
|
||||
return add().set(value);
|
||||
return addElement().set(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) {
|
||||
_data.remove(index);
|
||||
}
|
||||
// remove(char*)
|
||||
// remove(const char*)
|
||||
// remove(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
|
||||
TChar* key) {
|
||||
_data.remove(adaptString(key));
|
||||
}
|
||||
// remove(const std::string&)
|
||||
// remove(const String&)
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString& key) {
|
||||
_data.remove(adaptString(key));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -8,28 +8,28 @@
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <size_t CAPACITY>
|
||||
template <size_t desiredCapacity>
|
||||
class StaticJsonDocument : public JsonDocument {
|
||||
static const size_t ACTUAL_CAPACITY =
|
||||
AddPadding<Max<1, CAPACITY>::value>::value;
|
||||
static const size_t _capacity =
|
||||
AddPadding<Max<1, desiredCapacity>::value>::value;
|
||||
|
||||
public:
|
||||
StaticJsonDocument() : JsonDocument(_buffer, ACTUAL_CAPACITY) {}
|
||||
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {}
|
||||
|
||||
StaticJsonDocument(const StaticJsonDocument& src)
|
||||
: JsonDocument(_buffer, ACTUAL_CAPACITY) {
|
||||
: JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
StaticJsonDocument(const T& src,
|
||||
typename enable_if<IsVisitable<T>::value>::type* = 0)
|
||||
: JsonDocument(_buffer, ACTUAL_CAPACITY) {
|
||||
: JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
// disambiguate
|
||||
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, ACTUAL_CAPACITY) {
|
||||
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) {
|
||||
set(src);
|
||||
}
|
||||
|
||||
@ -45,7 +45,7 @@ class StaticJsonDocument : public JsonDocument {
|
||||
}
|
||||
|
||||
private:
|
||||
char _buffer[ACTUAL_CAPACITY];
|
||||
char _buffer[_capacity];
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,16 +1,16 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Deserialization/deserialize.hpp"
|
||||
#include "../Memory/MemoryPool.hpp"
|
||||
#include "../Numbers/isFloat.hpp"
|
||||
#include "../Numbers/isInteger.hpp"
|
||||
#include "../Numbers/parseNumber.hpp"
|
||||
#include "../Polyfills/type_traits.hpp"
|
||||
#include "../Variant/VariantData.hpp"
|
||||
#include "EscapeSequence.hpp"
|
||||
#include "Utf8.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
@ -18,7 +18,6 @@ template <typename TReader, typename TStringStorage>
|
||||
class JsonDeserializer {
|
||||
typedef typename remove_reference<TStringStorage>::type::StringBuilder
|
||||
StringBuilder;
|
||||
typedef const char *StringType;
|
||||
|
||||
public:
|
||||
JsonDeserializer(MemoryPool &pool, TReader reader,
|
||||
@ -123,10 +122,10 @@ class JsonDeserializer {
|
||||
if (!slot) return DeserializationError::NoMemory;
|
||||
|
||||
// Parse key
|
||||
StringType key;
|
||||
const char *key;
|
||||
err = parseKey(key);
|
||||
if (err) return err;
|
||||
slot->setOwnedKey(key);
|
||||
slot->setOwnedKey(make_not_null(key));
|
||||
|
||||
// Skip spaces
|
||||
err = skipSpacesAndComments();
|
||||
@ -161,7 +160,7 @@ class JsonDeserializer {
|
||||
}
|
||||
}
|
||||
|
||||
DeserializationError parseKey(StringType &key) {
|
||||
DeserializationError parseKey(const char *&key) {
|
||||
if (isQuote(current())) {
|
||||
return parseQuotedString(key);
|
||||
} else {
|
||||
@ -170,14 +169,14 @@ class JsonDeserializer {
|
||||
}
|
||||
|
||||
DeserializationError parseStringValue(VariantData &variant) {
|
||||
StringType value;
|
||||
const char *value;
|
||||
DeserializationError err = parseQuotedString(value);
|
||||
if (err) return err;
|
||||
variant.setOwnedString(value);
|
||||
variant.setOwnedString(make_not_null(value));
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
DeserializationError parseQuotedString(StringType &result) {
|
||||
DeserializationError parseQuotedString(const char *&result) {
|
||||
StringBuilder builder = _stringStorage.startString();
|
||||
const char stopChar = current();
|
||||
|
||||
@ -192,7 +191,18 @@ class JsonDeserializer {
|
||||
if (c == '\\') {
|
||||
c = current();
|
||||
if (c == '\0') return DeserializationError::IncompleteInput;
|
||||
if (c == 'u') return DeserializationError::NotSupported;
|
||||
if (c == 'u') {
|
||||
#if ARDUINOJSON_DECODE_UNICODE
|
||||
uint16_t codepoint;
|
||||
move();
|
||||
DeserializationError err = parseCodepoint(codepoint);
|
||||
if (err) return err;
|
||||
Utf8::encodeCodepoint(codepoint, builder);
|
||||
continue;
|
||||
#else
|
||||
return DeserializationError::NotSupported;
|
||||
#endif
|
||||
}
|
||||
// replace char
|
||||
c = EscapeSequence::unescapeChar(c);
|
||||
if (c == '\0') return DeserializationError::InvalidInput;
|
||||
@ -207,7 +217,7 @@ class JsonDeserializer {
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
DeserializationError parseNonQuotedString(StringType &result) {
|
||||
DeserializationError parseNonQuotedString(const char *&result) {
|
||||
StringBuilder builder = _stringStorage.startString();
|
||||
|
||||
char c = current();
|
||||
@ -240,18 +250,51 @@ class JsonDeserializer {
|
||||
}
|
||||
buffer[n] = 0;
|
||||
|
||||
if (isInteger(buffer)) {
|
||||
result.setInteger(parseInteger<Integer>(buffer));
|
||||
} else if (isFloat(buffer)) {
|
||||
result.setFloat(parseFloat<Float>(buffer));
|
||||
} else if (!strcmp(buffer, "true")) {
|
||||
c = buffer[0];
|
||||
if (c == 't') { // true
|
||||
result.setBoolean(true);
|
||||
} else if (!strcmp(buffer, "false")) {
|
||||
return n == 4 ? DeserializationError::Ok
|
||||
: DeserializationError::IncompleteInput;
|
||||
}
|
||||
if (c == 'f') { // false
|
||||
result.setBoolean(false);
|
||||
} else if (!strcmp(buffer, "null")) {
|
||||
// already null
|
||||
} else {
|
||||
return DeserializationError::InvalidInput;
|
||||
return n == 5 ? DeserializationError::Ok
|
||||
: DeserializationError::IncompleteInput;
|
||||
}
|
||||
if (c == 'n') { // null
|
||||
// the variant is already null
|
||||
return n == 4 ? DeserializationError::Ok
|
||||
: DeserializationError::IncompleteInput;
|
||||
}
|
||||
|
||||
ParsedNumber<Float, UInt> num = parseNumber<Float, UInt>(buffer);
|
||||
|
||||
switch (num.type()) {
|
||||
case VALUE_IS_NEGATIVE_INTEGER:
|
||||
result.setNegativeInteger(num.uintValue);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case VALUE_IS_POSITIVE_INTEGER:
|
||||
result.setPositiveInteger(num.uintValue);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case VALUE_IS_FLOAT:
|
||||
result.setFloat(num.floatValue);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
return DeserializationError::InvalidInput;
|
||||
}
|
||||
|
||||
DeserializationError parseCodepoint(uint16_t &codepoint) {
|
||||
codepoint = 0;
|
||||
for (uint8_t i = 0; i < 4; ++i) {
|
||||
char digit = current();
|
||||
if (!digit) return DeserializationError::IncompleteInput;
|
||||
uint8_t value = decodeHex(digit);
|
||||
if (value > 0x0F) return DeserializationError::InvalidInput;
|
||||
codepoint = uint16_t((codepoint << 4) | value);
|
||||
move();
|
||||
}
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
@ -269,6 +312,12 @@ class JsonDeserializer {
|
||||
return c == '\'' || c == '\"';
|
||||
}
|
||||
|
||||
static inline uint8_t decodeHex(char c) {
|
||||
if (c < 'A') return uint8_t(c - '0');
|
||||
c = char(c & ~0x20); // uppercase
|
||||
return uint8_t(c - 'A' + 10);
|
||||
}
|
||||
|
||||
DeserializationError skipSpacesAndComments() {
|
||||
for (;;) {
|
||||
switch (current()) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
26
src/ArduinoJson/Json/Utf8.hpp
Normal file
26
src/ArduinoJson/Json/Utf8.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
namespace Utf8 {
|
||||
template <typename TStringBuilder>
|
||||
inline void encodeCodepoint(uint16_t codepoint, TStringBuilder &str) {
|
||||
if (codepoint < 0x80) {
|
||||
str.append(char(codepoint));
|
||||
return;
|
||||
}
|
||||
|
||||
if (codepoint >= 0x00000800) {
|
||||
str.append(char(0xe0 /*0b11100000*/ | (codepoint >> 12)));
|
||||
str.append(char(((codepoint >> 6) & 0x3f /*0b00111111*/) | 0x80));
|
||||
} else {
|
||||
str.append(char(0xc0 /*0b11000000*/ | (codepoint >> 6)));
|
||||
}
|
||||
str.append(char((codepoint & 0x3f /*0b00111111*/) | 0x80));
|
||||
}
|
||||
} // namespace Utf8
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -91,7 +91,7 @@ class MemoryPool {
|
||||
return reinterpret_cast<T*>(allocRight(sizeof(T)));
|
||||
}
|
||||
|
||||
char* allocRight(size_t bytes) {
|
||||
void* allocRight(size_t bytes) {
|
||||
if (!canAlloc(bytes)) return 0;
|
||||
_right -= bytes;
|
||||
return _right;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -17,7 +17,6 @@ template <typename TReader, typename TStringStorage>
|
||||
class MsgPackDeserializer {
|
||||
typedef typename remove_reference<TStringStorage>::type::StringBuilder
|
||||
StringBuilder;
|
||||
typedef const char *StringType;
|
||||
|
||||
public:
|
||||
MsgPackDeserializer(MemoryPool &pool, TReader reader,
|
||||
@ -80,8 +79,7 @@ class MsgPackDeserializer {
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
return readInteger<uint64_t>(variant);
|
||||
#else
|
||||
readInteger<uint32_t>();
|
||||
return readInteger<uint32_t>(variant);
|
||||
return DeserializationError::NotSupported;
|
||||
#endif
|
||||
|
||||
case 0xd0:
|
||||
@ -97,8 +95,7 @@ class MsgPackDeserializer {
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
return readInteger<int64_t>(variant);
|
||||
#else
|
||||
if (!skip(4)) return DeserializationError::IncompleteInput;
|
||||
return readInteger<int32_t>(variant);
|
||||
return DeserializationError::NotSupported;
|
||||
#endif
|
||||
|
||||
case 0xca:
|
||||
@ -227,20 +224,20 @@ class MsgPackDeserializer {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError readString(StringType &str) {
|
||||
DeserializationError readString(const char *&str) {
|
||||
T size;
|
||||
if (!readInteger(size)) return DeserializationError::IncompleteInput;
|
||||
return readString(str, size);
|
||||
}
|
||||
|
||||
DeserializationError readString(VariantData &variant, size_t n) {
|
||||
StringType s;
|
||||
const char *s;
|
||||
DeserializationError err = readString(s, n);
|
||||
if (!err) variant.setOwnedString(s);
|
||||
if (!err) variant.setOwnedString(make_not_null(s));
|
||||
return err;
|
||||
}
|
||||
|
||||
DeserializationError readString(StringType &result, size_t n) {
|
||||
DeserializationError readString(const char *&result, size_t n) {
|
||||
StringBuilder builder = _stringStorage.startString();
|
||||
for (; n; --n) {
|
||||
uint8_t c;
|
||||
@ -287,10 +284,10 @@ class MsgPackDeserializer {
|
||||
VariantSlot *slot = object.addSlot(_pool);
|
||||
if (!slot) return DeserializationError::NoMemory;
|
||||
|
||||
StringType key;
|
||||
const char *key;
|
||||
DeserializationError err = parseKey(key);
|
||||
if (err) return err;
|
||||
slot->setOwnedKey(key);
|
||||
slot->setOwnedKey(make_not_null(key));
|
||||
|
||||
err = parse(*slot->data());
|
||||
if (err) return err;
|
||||
@ -299,7 +296,7 @@ class MsgPackDeserializer {
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
DeserializationError parseKey(StringType &key) {
|
||||
DeserializationError parseKey(const char *&key) {
|
||||
uint8_t code;
|
||||
if (!readByte(code)) return DeserializationError::IncompleteInput;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -24,6 +24,7 @@ class MsgPackSerializer {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
|
||||
typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) {
|
||||
float value32 = float(value64);
|
||||
if (value32 == value64) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -9,30 +9,33 @@
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 8>) {
|
||||
#if ARDUINOJSON_LITTLE_ENDIAN
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) {
|
||||
swap(p[0], p[7]);
|
||||
swap(p[1], p[6]);
|
||||
swap(p[2], p[5]);
|
||||
swap(p[3], p[4]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 4>) {
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) {
|
||||
swap(p[0], p[3]);
|
||||
swap(p[1], p[2]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 2>) {
|
||||
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) {
|
||||
swap(p[0], p[1]);
|
||||
}
|
||||
|
||||
inline void fixEndianess(uint8_t*, integral_constant<size_t, 1>) {}
|
||||
inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {}
|
||||
|
||||
template <typename T>
|
||||
inline void fixEndianess(T& value) {
|
||||
#if ARDUINOJSON_LITTLE_ENDIAN
|
||||
fixEndianess(reinterpret_cast<uint8_t*>(&value),
|
||||
inline void fixEndianess(T &value) {
|
||||
fixEndianess(reinterpret_cast<uint8_t *>(&value),
|
||||
integral_constant<size_t, sizeof(T)>());
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
inline void fixEndianess(T &) {}
|
||||
#endif
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -19,4 +19,5 @@
|
||||
#define ARDUINOJSON_NAMESPACE \
|
||||
ARDUINOJSON_CONCAT8(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
|
||||
ARDUINOJSON_VERSION_MINOR, ARDUINOJSON_VERSION_REVISION, \
|
||||
_, ARDUINOJSON_USE_LONG_LONG, _, ARDUINOJSON_USE_DOUBLE)
|
||||
_, ARDUINOJSON_USE_LONG_LONG, ARDUINOJSON_USE_DOUBLE, \
|
||||
ARDUINOJSON_DECODE_UNICODE)
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -7,6 +7,7 @@
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h>
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Polyfills/alias_cast.hpp"
|
||||
#include "../Polyfills/math.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
@ -16,10 +17,10 @@ struct FloatTraits {};
|
||||
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 8 /*64bits*/> {
|
||||
typedef int64_t mantissa_type;
|
||||
typedef uint64_t mantissa_type;
|
||||
static const short mantissa_bits = 52;
|
||||
static const mantissa_type mantissa_max =
|
||||
(static_cast<mantissa_type>(1) << mantissa_bits) - 1;
|
||||
(mantissa_type(1) << mantissa_bits) - 1;
|
||||
|
||||
typedef int16_t exponent_type;
|
||||
static const exponent_type exponent_max = 308;
|
||||
@ -94,25 +95,28 @@ struct FloatTraits<T, 8 /*64bits*/> {
|
||||
return forge(0x7ff00000, 0x00000000);
|
||||
}
|
||||
|
||||
static T highest() {
|
||||
return forge(0x7FEFFFFF, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
static T lowest() {
|
||||
return forge(0xFFEFFFFF, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
// constructs a double floating point values from its binary representation
|
||||
// we use this function to workaround platforms with single precision literals
|
||||
// (for example, when -fsingle-precision-constant is passed to GCC)
|
||||
static T forge(uint32_t msb, uint32_t lsb) {
|
||||
union {
|
||||
uint64_t integerBits;
|
||||
T floatBits;
|
||||
};
|
||||
integerBits = (uint64_t(msb) << 32) | lsb;
|
||||
return floatBits;
|
||||
return alias_cast<T>((uint64_t(msb) << 32) | lsb);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct FloatTraits<T, 4 /*32bits*/> {
|
||||
typedef int32_t mantissa_type;
|
||||
typedef uint32_t mantissa_type;
|
||||
static const short mantissa_bits = 23;
|
||||
static const mantissa_type mantissa_max =
|
||||
(static_cast<mantissa_type>(1) << mantissa_bits) - 1;
|
||||
(mantissa_type(1) << mantissa_bits) - 1;
|
||||
|
||||
typedef int8_t exponent_type;
|
||||
static const exponent_type exponent_max = 38;
|
||||
@ -150,12 +154,7 @@ struct FloatTraits<T, 4 /*32bits*/> {
|
||||
}
|
||||
|
||||
static T forge(uint32_t bits) {
|
||||
union {
|
||||
uint32_t integerBits;
|
||||
T floatBits;
|
||||
};
|
||||
integerBits = bits;
|
||||
return floatBits;
|
||||
return alias_cast<T>(bits);
|
||||
}
|
||||
|
||||
static T nan() {
|
||||
@ -165,5 +164,13 @@ struct FloatTraits<T, 4 /*32bits*/> {
|
||||
static T inf() {
|
||||
return forge(0x7f800000);
|
||||
}
|
||||
|
||||
static T highest() {
|
||||
return forge(0x7f7fffff);
|
||||
}
|
||||
|
||||
static T lowest() {
|
||||
return forge(0xFf7fffff);
|
||||
}
|
||||
};
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
105
src/ArduinoJson/Numbers/convertNumber.hpp
Normal file
105
src/ArduinoJson/Numbers/convertNumber.hpp
Normal file
@ -0,0 +1,105 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
|
||||
#include "../Polyfills/limits.hpp"
|
||||
#include "Float.hpp"
|
||||
#include "FloatTraits.hpp"
|
||||
#include "Integer.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
|
||||
bool>::type
|
||||
canStorePositiveInteger(TIn value) {
|
||||
return value <= TIn(numeric_limits<TOut>::highest());
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
|
||||
bool>::type
|
||||
canStorePositiveInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||
canStorePositiveInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TOut) <= sizeof(TIn),
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn value) {
|
||||
return value <= TIn(numeric_limits<TOut>::highest()) + 1;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
|
||||
sizeof(TIn) < sizeof(TOut),
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value,
|
||||
bool>::type
|
||||
canStoreNegativeInteger(TIn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
TOut convertPositiveInteger(TIn value) {
|
||||
return canStorePositiveInteger<TOut>(value) ? TOut(value) : 0;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
TOut convertNegativeInteger(TIn value) {
|
||||
return canStoreNegativeInteger<TOut>(value) ? TOut(~value + 1) : 0;
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||
TIn value) {
|
||||
return TOut(value);
|
||||
}
|
||||
|
||||
template <typename TOut, typename TIn>
|
||||
typename enable_if<!is_floating_point<TOut>::value, TOut>::type convertFloat(
|
||||
TIn value) {
|
||||
return value >= numeric_limits<TOut>::lowest() &&
|
||||
value <= numeric_limits<TOut>::highest()
|
||||
? TOut(value)
|
||||
: 0;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
@ -1,36 +0,0 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string.h> // for strcmp
|
||||
#include "../Polyfills/ctype.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline bool isFloat(const char* s) {
|
||||
if (!s) return false;
|
||||
|
||||
if (!strcmp(s, "NaN")) return true;
|
||||
if (issign(*s)) s++;
|
||||
if (!strcmp(s, "Infinity")) return true;
|
||||
if (*s == '\0') return false;
|
||||
|
||||
while (isdigit(*s)) s++;
|
||||
|
||||
if (*s == '.') {
|
||||
s++;
|
||||
while (isdigit(*s)) s++;
|
||||
}
|
||||
|
||||
if (*s == 'e' || *s == 'E') {
|
||||
s++;
|
||||
if (issign(*s)) s++;
|
||||
if (!isdigit(*s)) return false;
|
||||
while (isdigit(*s)) s++;
|
||||
}
|
||||
|
||||
return *s == '\0';
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,17 +0,0 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Polyfills/ctype.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
inline bool isInteger(const char* s) {
|
||||
if (!s || !*s) return false;
|
||||
if (issign(*s)) s++;
|
||||
while (isdigit(*s)) s++;
|
||||
return *s == '\0';
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,88 +1,18 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Numbers/FloatTraits.hpp"
|
||||
#include "../Polyfills/ctype.hpp"
|
||||
#include "../Polyfills/math.hpp"
|
||||
#include "convertNumber.hpp"
|
||||
#include "parseNumber.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T>
|
||||
inline T parseFloat(const char* s) {
|
||||
typedef FloatTraits<T> traits;
|
||||
typedef typename traits::mantissa_type mantissa_t;
|
||||
typedef typename traits::exponent_type exponent_t;
|
||||
|
||||
if (!s) return 0; // NULL
|
||||
|
||||
bool negative_result = false;
|
||||
switch (*s) {
|
||||
case '-':
|
||||
negative_result = true;
|
||||
s++;
|
||||
break;
|
||||
case '+':
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*s == 't') return 1; // true
|
||||
if (*s == 'n' || *s == 'N') return traits::nan();
|
||||
if (*s == 'i' || *s == 'I')
|
||||
return negative_result ? -traits::inf() : traits::inf();
|
||||
|
||||
mantissa_t mantissa = 0;
|
||||
exponent_t exponent_offset = 0;
|
||||
|
||||
while (isdigit(*s)) {
|
||||
if (mantissa < traits::mantissa_max / 10)
|
||||
mantissa = mantissa * 10 + (*s - '0');
|
||||
else
|
||||
exponent_offset++;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '.') {
|
||||
s++;
|
||||
while (isdigit(*s)) {
|
||||
if (mantissa < traits::mantissa_max / 10) {
|
||||
mantissa = mantissa * 10 + (*s - '0');
|
||||
exponent_offset--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
int exponent = 0;
|
||||
if (*s == 'e' || *s == 'E') {
|
||||
s++;
|
||||
bool negative_exponent = false;
|
||||
if (*s == '-') {
|
||||
negative_exponent = true;
|
||||
s++;
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
}
|
||||
|
||||
while (isdigit(*s)) {
|
||||
exponent = exponent * 10 + (*s - '0');
|
||||
if (exponent + exponent_offset > traits::exponent_max) {
|
||||
if (negative_exponent)
|
||||
return negative_result ? -0.0f : 0.0f;
|
||||
else
|
||||
return negative_result ? -traits::inf() : traits::inf();
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (negative_exponent) exponent = -exponent;
|
||||
}
|
||||
exponent += exponent_offset;
|
||||
|
||||
T result = traits::make_float(static_cast<T>(mantissa), exponent);
|
||||
|
||||
return negative_result ? -result : result;
|
||||
// try to reuse the same parameters as JsonDeserializer
|
||||
typedef typename choose_largest<Float, T>::type TFloat;
|
||||
return parseNumber<TFloat, UInt>(s).template as<T>();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -1,37 +1,19 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Polyfills/ctype.hpp"
|
||||
#include "../Polyfills/type_traits.hpp"
|
||||
#include "convertNumber.hpp"
|
||||
#include "parseNumber.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
template <typename T>
|
||||
T parseInteger(const char *s) {
|
||||
if (!s) return 0; // NULL
|
||||
|
||||
if (*s == 't') return 1; // "true"
|
||||
|
||||
T result = 0;
|
||||
bool negative_result = false;
|
||||
|
||||
switch (*s) {
|
||||
case '-':
|
||||
negative_result = true;
|
||||
s++;
|
||||
break;
|
||||
case '+':
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
|
||||
while (isdigit(*s)) {
|
||||
result = T(result * 10 + T(*s - '0'));
|
||||
s++;
|
||||
}
|
||||
|
||||
return negative_result ? T(~result + 1) : result;
|
||||
// try to reuse the same parameters as JsonDeserializer
|
||||
typedef typename choose_largest<UInt, typename make_unsigned<T>::type>::type
|
||||
TUInt;
|
||||
return parseNumber<Float, TUInt>(s).template as<T>();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
150
src/ArduinoJson/Numbers/parseNumber.hpp
Normal file
150
src/ArduinoJson/Numbers/parseNumber.hpp
Normal file
@ -0,0 +1,150 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Polyfills/assert.hpp"
|
||||
#include "../Polyfills/ctype.hpp"
|
||||
#include "../Polyfills/math.hpp"
|
||||
#include "../Polyfills/type_traits.hpp"
|
||||
#include "../Variant/VariantContent.hpp"
|
||||
#include "FloatTraits.hpp"
|
||||
#include "convertNumber.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename TFloat, typename TUInt>
|
||||
struct ParsedNumber {
|
||||
ParsedNumber() : uintValue(0), floatValue(0), _type(VALUE_IS_NULL) {}
|
||||
|
||||
ParsedNumber(TUInt value, bool is_negative)
|
||||
: uintValue(value),
|
||||
floatValue(TFloat(value)),
|
||||
_type(uint8_t(is_negative ? VALUE_IS_NEGATIVE_INTEGER
|
||||
: VALUE_IS_POSITIVE_INTEGER)) {}
|
||||
ParsedNumber(TFloat value) : floatValue(value), _type(VALUE_IS_FLOAT) {}
|
||||
|
||||
template <typename T>
|
||||
T as() const {
|
||||
switch (_type) {
|
||||
case VALUE_IS_NEGATIVE_INTEGER:
|
||||
return convertNegativeInteger<T>(uintValue);
|
||||
case VALUE_IS_POSITIVE_INTEGER:
|
||||
return convertPositiveInteger<T>(uintValue);
|
||||
case VALUE_IS_FLOAT:
|
||||
return convertFloat<T>(floatValue);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t type() const {
|
||||
return _type;
|
||||
}
|
||||
|
||||
TUInt uintValue;
|
||||
TFloat floatValue;
|
||||
uint8_t _type;
|
||||
};
|
||||
|
||||
template <typename A, typename B>
|
||||
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {};
|
||||
|
||||
template <typename TFloat, typename TUInt>
|
||||
inline ParsedNumber<TFloat, TUInt> parseNumber(const char *s) {
|
||||
typedef FloatTraits<TFloat> traits;
|
||||
typedef typename choose_largest<typename traits::mantissa_type, TUInt>::type
|
||||
mantissa_t;
|
||||
typedef typename traits::exponent_type exponent_t;
|
||||
typedef ParsedNumber<TFloat, TUInt> return_type;
|
||||
|
||||
ARDUINOJSON_ASSERT(s != 0);
|
||||
|
||||
bool is_negative = false;
|
||||
switch (*s) {
|
||||
case '-':
|
||||
is_negative = true;
|
||||
s++;
|
||||
break;
|
||||
case '+':
|
||||
s++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*s == 'n' || *s == 'N') return traits::nan();
|
||||
if (*s == 'i' || *s == 'I')
|
||||
return is_negative ? -traits::inf() : traits::inf();
|
||||
if (!isdigit(*s) && *s != '.') return return_type();
|
||||
|
||||
mantissa_t mantissa = 0;
|
||||
exponent_t exponent_offset = 0;
|
||||
const mantissa_t maxUint = TUInt(-1);
|
||||
|
||||
while (isdigit(*s)) {
|
||||
uint8_t digit = uint8_t(*s - '0');
|
||||
if (mantissa > maxUint / 10) break;
|
||||
mantissa *= 10;
|
||||
if (mantissa > maxUint - digit) break;
|
||||
mantissa += digit;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '\0') return return_type(TUInt(mantissa), is_negative);
|
||||
|
||||
// avoid mantissa overflow
|
||||
while (mantissa > traits::mantissa_max) {
|
||||
mantissa /= 10;
|
||||
exponent_offset++;
|
||||
}
|
||||
|
||||
// remaing digits can't fit in the mantissa
|
||||
while (isdigit(*s)) {
|
||||
exponent_offset++;
|
||||
s++;
|
||||
}
|
||||
|
||||
if (*s == '.') {
|
||||
s++;
|
||||
while (isdigit(*s)) {
|
||||
if (mantissa < traits::mantissa_max / 10) {
|
||||
mantissa = mantissa * 10 + uint8_t(*s - '0');
|
||||
exponent_offset--;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
int exponent = 0;
|
||||
if (*s == 'e' || *s == 'E') {
|
||||
s++;
|
||||
bool negative_exponent = false;
|
||||
if (*s == '-') {
|
||||
negative_exponent = true;
|
||||
s++;
|
||||
} else if (*s == '+') {
|
||||
s++;
|
||||
}
|
||||
|
||||
while (isdigit(*s)) {
|
||||
exponent = exponent * 10 + (*s - '0');
|
||||
if (exponent + exponent_offset > traits::exponent_max) {
|
||||
if (negative_exponent)
|
||||
return is_negative ? -0.0f : 0.0f;
|
||||
else
|
||||
return is_negative ? -traits::inf() : traits::inf();
|
||||
}
|
||||
s++;
|
||||
}
|
||||
if (negative_exponent) exponent = -exponent;
|
||||
}
|
||||
exponent += exponent_offset;
|
||||
|
||||
// we should be at the end of the string, otherwise it's an error
|
||||
if (*s != '\0') return return_type();
|
||||
|
||||
TFloat result = traits::make_float(static_cast<TFloat>(mantissa), exponent);
|
||||
|
||||
return is_negative ? -result : result;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -25,53 +25,80 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
: _object(variant), _key(key) {}
|
||||
|
||||
FORCE_INLINE operator VariantConstRef() const {
|
||||
return getMember();
|
||||
return getUpstreamMember();
|
||||
}
|
||||
|
||||
FORCE_INLINE this_type &operator=(const this_type &src) {
|
||||
getOrCreateMember().set(src);
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type
|
||||
operator=(const TValue &src) {
|
||||
getOrCreateMember().set(src);
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// operator=(char*) const
|
||||
// operator=(const char*) const
|
||||
// operator=(const __FlashStringHelper*) const
|
||||
// operator=(char*)
|
||||
// operator=(const char*)
|
||||
// operator=(const __FlashStringHelper*)
|
||||
template <typename TChar>
|
||||
FORCE_INLINE this_type &operator=(TChar *src) {
|
||||
getOrCreateMember().set(src);
|
||||
getOrAddUpstreamMember().set(src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE void clear() const {
|
||||
getUpstreamMember().clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return getMember().isNull();
|
||||
return getUpstreamMember().isNull();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantAs<TValue>::type as() const {
|
||||
return getMember().template as<TValue>();
|
||||
return getUpstreamMember().template as<TValue>();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool is() const {
|
||||
return getMember().template is<TValue>();
|
||||
return getUpstreamMember().template is<TValue>();
|
||||
}
|
||||
|
||||
FORCE_INLINE size_t size() const {
|
||||
return getUpstreamMember().size();
|
||||
}
|
||||
|
||||
FORCE_INLINE void remove(size_t index) const {
|
||||
getUpstreamMember().remove(index);
|
||||
}
|
||||
// remove(char*) const
|
||||
// remove(const char*) const
|
||||
// remove(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
|
||||
TChar *key) const {
|
||||
getUpstreamMember().remove(key);
|
||||
}
|
||||
// remove(const std::string&) const
|
||||
// remove(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
|
||||
const TString &key) const {
|
||||
getUpstreamMember().remove(key);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename VariantTo<TValue>::type to() {
|
||||
return getOrCreateMember().template to<TValue>();
|
||||
return getOrAddUpstreamMember().template to<TValue>();
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, bool>::type set(
|
||||
const TValue &value) {
|
||||
return getOrCreateMember().set(value);
|
||||
return getOrAddUpstreamMember().set(value);
|
||||
}
|
||||
|
||||
// set(char*) const
|
||||
@ -79,56 +106,60 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
|
||||
// set(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool set(const TChar *value) {
|
||||
return getOrCreateMember().set(value);
|
||||
return getOrAddUpstreamMember().set(value);
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
void accept(Visitor &visitor) const {
|
||||
return getMember().accept(visitor);
|
||||
return getUpstreamMember().accept(visitor);
|
||||
}
|
||||
|
||||
using ArrayShortcuts<MemberProxy>::add;
|
||||
FORCE_INLINE VariantRef add() const {
|
||||
return getOrCreateMember().add();
|
||||
FORCE_INLINE VariantRef addElement() const {
|
||||
return getOrAddUpstreamMember().addElement();
|
||||
}
|
||||
|
||||
// get(char*) const
|
||||
// get(const char*) const
|
||||
// get(const __FlashStringHelper*) const
|
||||
// getElement(size_t) const
|
||||
FORCE_INLINE VariantRef getElement(size_t index) const {
|
||||
return getUpstreamMember().getElement(index);
|
||||
}
|
||||
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef get(TChar *key) const {
|
||||
return getMember().get(key);
|
||||
FORCE_INLINE VariantRef getMember(TChar *key) const {
|
||||
return getUpstreamMember().getMember(key);
|
||||
}
|
||||
|
||||
// get(const std::string&) const
|
||||
// get(const String&) const
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef get(const TString &key) const {
|
||||
return getMember().get(key);
|
||||
FORCE_INLINE VariantRef getMember(const TString &key) const {
|
||||
return getUpstreamMember().getMember(key);
|
||||
}
|
||||
|
||||
// getOrCreate(char*) const
|
||||
// getOrCreate(const char*) const
|
||||
// getOrCreate(const __FlashStringHelper*) const
|
||||
// getOrAddMember(char*) const
|
||||
// getOrAddMember(const char*) const
|
||||
// getOrAddMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrCreate(TChar *key) const {
|
||||
return getOrCreateMember().getOrCreate(key);
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar *key) const {
|
||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||
}
|
||||
|
||||
// getOrCreate(const std::string&) const
|
||||
// getOrCreate(const String&) const
|
||||
// getOrAddMember(const std::string&) const
|
||||
// getOrAddMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrCreate(const TString &key) const {
|
||||
return getOrCreateMember().getOrCreate(key);
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString &key) const {
|
||||
return getOrAddUpstreamMember().getOrAddMember(key);
|
||||
}
|
||||
|
||||
private:
|
||||
FORCE_INLINE VariantRef getMember() const {
|
||||
return _object.get(_key);
|
||||
FORCE_INLINE VariantRef getUpstreamMember() const {
|
||||
return _object.getMember(_key);
|
||||
}
|
||||
|
||||
FORCE_INLINE VariantRef getOrCreateMember() const {
|
||||
return _object.getOrCreate(_key);
|
||||
FORCE_INLINE VariantRef getOrAddUpstreamMember() const {
|
||||
return _object.getOrAddMember(_key);
|
||||
}
|
||||
|
||||
TObject _object;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -16,11 +16,6 @@ void objectAccept(const CollectionData *obj, Visitor &visitor) {
|
||||
visitor.visitNull();
|
||||
}
|
||||
|
||||
template <typename TAdaptedString>
|
||||
inline bool objectContainsKey(const CollectionData *obj, TAdaptedString key) {
|
||||
return obj && obj->containsKey(key);
|
||||
}
|
||||
|
||||
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
|
||||
if (lhs == rhs) return true;
|
||||
if (!lhs || !rhs) return false;
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -13,26 +13,40 @@ template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
|
||||
const TString& key) const {
|
||||
return impl()->getOrCreate(key).template to<ArrayRef>();
|
||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const {
|
||||
return impl()->getOrCreate(key).template to<ArrayRef>();
|
||||
return impl()->getOrAddMember(key).template to<ArrayRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||
const TString& key) const {
|
||||
return impl()->getOrCreate(key).template to<ObjectRef>();
|
||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
|
||||
TChar* key) const {
|
||||
return impl()->getOrCreate(key).template to<ObjectRef>();
|
||||
return impl()->getOrAddMember(key).template to<ObjectRef>();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TString>
|
||||
inline typename enable_if<IsString<TString>::value, bool>::type
|
||||
ObjectShortcuts<TObject>::containsKey(const TString& key) const {
|
||||
return !impl()->getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
template <typename TObject>
|
||||
template <typename TChar>
|
||||
inline typename enable_if<IsString<TChar*>::value, bool>::type
|
||||
ObjectShortcuts<TObject>::containsKey(TChar* key) const {
|
||||
return !impl()->getMember(key).isUndefined();
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -18,7 +18,8 @@ template <typename TData>
|
||||
class ObjectRefBase {
|
||||
public:
|
||||
operator VariantConstRef() const {
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(_data));
|
||||
const void* data = _data; // prevent warning cast-align
|
||||
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
@ -26,21 +27,6 @@ class ObjectRefBase {
|
||||
objectAccept(_data, visitor);
|
||||
}
|
||||
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE bool containsKey(const TString& key) const {
|
||||
return objectContainsKey(_data, adaptString(key));
|
||||
}
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool containsKey(TChar* key) const {
|
||||
return objectContainsKey(_data, adaptString(key));
|
||||
}
|
||||
|
||||
FORCE_INLINE bool isNull() const {
|
||||
return _data == 0;
|
||||
}
|
||||
@ -82,18 +68,33 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
|
||||
return iterator();
|
||||
}
|
||||
|
||||
// get(const std::string&) const
|
||||
// get(const String&) const
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantConstRef get(const TString& key) const {
|
||||
FORCE_INLINE bool containsKey(const TString& key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE bool containsKey(TChar* key) const {
|
||||
return !getMember(key).isUndefined();
|
||||
}
|
||||
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantConstRef getMember(const TString& key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// get(char*) const
|
||||
// get(const char*) const
|
||||
// get(const __FlashStringHelper*) const
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantConstRef get(TChar* key) const {
|
||||
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
@ -140,7 +141,8 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
|
||||
: base_type(data), _pool(buf) {}
|
||||
|
||||
operator VariantRef() const {
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(_data));
|
||||
void* data = _data; // prevent warning cast-align
|
||||
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
|
||||
}
|
||||
|
||||
operator ObjectConstRef() const {
|
||||
@ -161,38 +163,38 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
|
||||
_data->clear();
|
||||
}
|
||||
|
||||
FORCE_INLINE bool copyFrom(ObjectConstRef src) {
|
||||
FORCE_INLINE bool set(ObjectConstRef src) {
|
||||
if (!_data || !src._data) return false;
|
||||
return _data->copyFrom(*src._data, _pool);
|
||||
}
|
||||
|
||||
// get(const std::string&) const
|
||||
// get(const String&) const
|
||||
// getMember(const std::string&) const
|
||||
// getMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef get(const TString& key) const {
|
||||
FORCE_INLINE VariantRef getMember(const TString& key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// get(char*) const
|
||||
// get(const char*) const
|
||||
// get(const __FlashStringHelper*) const
|
||||
// getMember(char*) const
|
||||
// getMember(const char*) const
|
||||
// getMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef get(TChar* key) const {
|
||||
FORCE_INLINE VariantRef getMember(TChar* key) const {
|
||||
return get_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// getOrCreate(const std::string&) const
|
||||
// getOrCreate(const String&) const
|
||||
// getOrAddMember(const std::string&) const
|
||||
// getOrAddMember(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE VariantRef getOrCreate(const TString& key) const {
|
||||
FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
|
||||
return getOrCreate_impl(adaptString(key));
|
||||
}
|
||||
|
||||
// getOrCreate(char*) const
|
||||
// getOrCreate(const char*) const
|
||||
// getOrCreate(const __FlashStringHelper*) const
|
||||
// getOrAddMember(char*) const
|
||||
// getOrAddMember(const char*) const
|
||||
// getOrAddMember(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE VariantRef getOrCreate(TChar* key) const {
|
||||
FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
|
||||
return getOrCreate_impl(adaptString(key));
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -15,6 +15,19 @@ class MemberProxy;
|
||||
template <typename TObject>
|
||||
class ObjectShortcuts {
|
||||
public:
|
||||
// containsKey(const std::string&) const
|
||||
// containsKey(const String&) const
|
||||
template <typename TString>
|
||||
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type
|
||||
containsKey(const TString &key) const;
|
||||
|
||||
// containsKey(char*) const
|
||||
// containsKey(const char*) const
|
||||
// containsKey(const __FlashStringHelper*) const
|
||||
template <typename TChar>
|
||||
FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type
|
||||
containsKey(TChar *key) const;
|
||||
|
||||
// operator[](const std::string&) const
|
||||
// operator[](const String&) const
|
||||
template <typename TString>
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
28
src/ArduinoJson/Polyfills/alias_cast.hpp
Normal file
28
src/ArduinoJson/Polyfills/alias_cast.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h> // for size_t
|
||||
#include "../Configuration.hpp"
|
||||
#include "../Polyfills/math.hpp"
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
template <typename T, typename F>
|
||||
struct alias_cast_t {
|
||||
union {
|
||||
F raw;
|
||||
T data;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T, typename F>
|
||||
T alias_cast(F raw_data) {
|
||||
alias_cast_t<T, F> ac;
|
||||
ac.raw = raw_data;
|
||||
return ac.data;
|
||||
}
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
@ -33,3 +33,13 @@
|
||||
#else
|
||||
#define NOEXCEPT throw()
|
||||
#endif
|
||||
|
||||
#if defined(__has_attribute)
|
||||
#if __has_attribute(no_sanitize)
|
||||
#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
|
||||
#else
|
||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||
#endif
|
||||
#else
|
||||
#define ARDUINOJSON_NO_SANITIZE(check)
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
33
src/ArduinoJson/Polyfills/gsl/not_null.hpp
Normal file
33
src/ArduinoJson/Polyfills/gsl/not_null.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../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
|
45
src/ArduinoJson/Polyfills/limits.hpp
Normal file
45
src/ArduinoJson/Polyfills/limits.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2019
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Polyfills/type_traits.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4310)
|
||||
#endif
|
||||
|
||||
namespace ARDUINOJSON_NAMESPACE {
|
||||
|
||||
// Differs from standard because we can't use the symbols "min" and "max"
|
||||
template <typename T, typename Enable = void>
|
||||
struct numeric_limits;
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
|
||||
static T lowest() {
|
||||
return 0;
|
||||
}
|
||||
static T highest() {
|
||||
return T(-1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct numeric_limits<
|
||||
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> {
|
||||
static T lowest() {
|
||||
return T(T(1) << (sizeof(T) * 8 - 1));
|
||||
}
|
||||
static T highest() {
|
||||
return T(~lowest());
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ARDUINOJSON_NAMESPACE
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user