Compare commits

...

79 Commits

Author SHA1 Message Date
ad4b13c8f0 Set version to 5.13.5 2019-03-01 16:57:28 +01:00
f20f8e3171 Added an clear message for StaticJsonDocument, DynamicJsonDocument... 2019-02-28 14:38:13 +01:00
5c297ba4a2 Fixed warning "maybe uninitialized" (issue #909) 2019-02-28 13:45:56 +01:00
f483b06735 Fixed strict-aliasing warning in FloatTraits.hpp 2019-02-28 12:10:42 +01:00
a0011ba7f8 Travis: build in Release mode 2019-02-28 11:13:29 +01:00
ae2bfee0b1 Fixed warning "unused variable" with GCC 4.4 (issue #912) 2019-02-28 10:22:27 +01:00
b171872b58 Add an empty cpp file to detect warnings muted by catch.hpp 2019-02-28 09:32:56 +01:00
0d01e84336 Updated copyright year to 2019 2019-02-15 13:34:37 +01:00
0685a36f0e Added ArduBadge badge 2019-01-24 20:55:55 +01:00
ef12c74771 Set version to 5.13.4 2018-12-04 11:36:16 +01:00
0bc03e8071 Removed spurious files in the Particle library 2018-12-04 11:19:22 +01:00
04286f3228 Moved size measurements to github.com/bblanchon/ArduinoJson-size 2018-12-04 10:50:45 +01:00
0d4a93018b Set version to 5.13.3 2018-10-06 17:50:41 +02:00
3ca40db9f8 Added a coupon code for the book 2018-10-06 17:42:01 +02:00
ce607196d1 Travis: update osx images 2018-10-06 17:24:54 +02:00
0b3af166ae Fixed JsonVariant::is<String>() (closes #763) 2018-10-06 17:21:16 +02:00
fa1a40ac6e Fixed JsonVariant::is<int>() that returned true for empty strings 2018-07-05 09:53:11 +02:00
954428e341 Improved float serialization when -fsingle-precision-constant is used 2018-07-05 09:48:57 +02:00
7b229e4c38 Added fuzzing to travis 2018-06-06 11:20:49 +02:00
9ac9b533b6 Added clang 3.9, 4.0, 5.0 and 6.0 to travis 2018-06-05 20:55:53 +02:00
011aac43d2 Set version to 5.13.2 2018-06-01 09:21:42 +02:00
eb20ae6a3f Added macros ARDUINOJSON_VERSION, ARDUINOJSON_VERSION_MAJOR... 2018-06-01 09:19:34 +02:00
7c0af91844 Fixed null values that could be pass to strcmp() (closes #745) 2018-06-01 09:08:38 +02:00
3523296e3d Fixed JsonBuffer::parse() nesting limit (fixes #693) 2018-03-12 18:29:33 +01:00
689ae5c08d Set version to 5.13.1 2018-02-19 08:56:17 +01:00
d9b1e7e810 Allowed non-quoted key to contain underscores (fixes #665) 2018-02-16 11:04:07 +01:00
b4eece01f8 Fixed JsonVariant::operator|(int) to accept double (fixes #675) 2018-02-09 09:05:29 +01:00
cf5396aaed Set version to 5.13.0 2018-01-19 15:35:19 +01:00
e390587e91 Kept only two namespaces ArduinoJson and ArduinoJson::Internals 2018-01-19 08:32:15 +01:00
bae179ed67 RawJson() accepts any kind of string and obeys to duplication rules 2018-01-18 09:43:37 +01:00
7e4fcb0868 Add repository and license in library.properties (closes #662) 2018-01-15 10:24:51 +01:00
fbfdca1de9 Added campaign information in links 2018-01-15 10:22:04 +01:00
0612eef69b Marked strdup() as deprecated (issue #658) 2018-01-14 14:02:10 +01:00
ae0b7a3ebd Changed the return type of strdup() to const char* (issue #658) 2018-01-14 14:01:08 +01:00
e92612b511 Changed the rules of string duplication (fixes #658) 2018-01-14 13:46:28 +01:00
5c33fd4b94 Set copyright year to 2018 2018-01-05 09:20:01 +01:00
c3f51e2980 Updated links to arduinojson.org 2018-01-05 09:17:24 +01:00
de47c0af9e Updated links to the book 2017-12-27 14:15:49 +01:00
e53e4e3dd9 Fixed typos 2017-12-15 17:52:47 +01:00
36fe6535c4 Reworked the readme 2017-12-15 17:52:13 +01:00
b55e57a7cf Set version to 5.12.0 2017-12-11 17:50:18 +01:00
7626db624e Changed all link to point to HTTPS version 2017-12-11 17:26:50 +01:00
6d8329b255 Added an example that shows how to save and load a configuration file 2017-12-11 17:20:27 +01:00
461e30148c Reworked all examples 2017-12-11 15:19:28 +01:00
57d98e48f7 Added detection of Keil ARM Compiler (issue #629) 2017-12-05 21:24:28 +01:00
cf2babc598 Added detection of MPLAB XC compiler (issue #629) 2017-12-05 21:18:21 +01:00
d10277df31 Added a clear error message when compiled as C (issue #629) 2017-12-03 13:49:51 +01:00
d3a1203782 Added JsonVariant::operator| to return a default value 2017-11-29 09:49:40 +01:00
126f7ab819 Rewrote example JsonHttpClient.ino (fixes #600) 2017-11-13 16:17:44 +01:00
221c2861fc Changed all links to point to arduinojson.org 2017-11-07 20:42:50 +01:00
66667382e1 Added Alexander Wilms to the list of donators 2017-11-01 09:19:40 +01:00
a7e928d126 Set version to 5.11.2 2017-10-17 10:21:52 +02:00
591fe7e92b Fixed incorrect rounding for float values (fixes #588) 2017-10-17 10:19:21 +02:00
d6e61cbcda Added banner with the new logo 2017-10-16 10:21:44 +02:00
5825366fe4 Added Patrick Elliott to the list of donators 2017-10-07 16:33:53 +02:00
6df204cf40 Split CONTRIBUTING and SUPPORT 2017-10-03 13:01:47 +02:00
3f7e1db549 Added guidelines for contributing 2017-10-03 12:26:49 +02:00
a6091136b0 Fix GCC 7 warning 2017-09-27 11:13:45 +02:00
353bbd0e8c Fix GCC 4.8.5 warning 2017-09-27 09:45:48 +02:00
a428e125fa Travis: Added GCC 7 2017-09-27 09:29:08 +02:00
2e262b2689 Travis: Removed GCC 4.5 2017-09-27 09:29:08 +02:00
a2d055e408 Added Günther Jehle to the list of donators 2017-09-26 09:43:32 +02:00
57defe00ee Fixed DynamicJsonBuffer::clear() not resetting allocation size (fixes #561) 2017-08-30 21:51:10 +02:00
ac5a2676e7 Upgraded to Catch 1.9.7 2017-08-27 15:12:20 +02:00
ed98ea4e43 Implemented JsonVariant comparisons with template friends 2017-08-06 16:26:38 +02:00
729bf0afd2 Made JsonBuffer destructor protected 2017-07-18 22:00:06 +02:00
2ea7ea153c Set version to 5.11.1 2017-07-14 11:17:11 +02:00
2772e66064 Fixed warning "this statement may fall through" (issue #539) 2017-07-14 11:14:56 +02:00
d41f7a8165 Fixed too many decimals places in float serialization (issue #543) 2017-07-14 10:51:46 +02:00
abfd3997eb Fixed "constant exceeds range of float [-Woverflow]" (issue #544) 2017-07-09 15:24:58 +02:00
788c9be016 Removed dependency on PGM_P as Particle 0.6.2 doesn't define it (issue #546) 2017-07-07 23:04:42 +02:00
c3d7a79a83 Travis: Removed Arduino DUE on platformio (fatal error: Ethernet.h: No such file or directory) 2017-07-06 20:56:05 +02:00
1782348275 Added Charles Walker to the list of donators 2017-07-06 20:55:05 +02:00
edfe5c6622 Set version to 5.11.0 2017-06-25 15:11:57 +02:00
2b9492317b Added Charles Haynes to the list of donators 2017-06-22 21:56:41 +02:00
5da41edf6a Removed implementation of JsonBufferAllocated::delete. 2017-06-19 10:05:38 +02:00
476e5aaa86 Added DynamicJsonBuffer::clear() 2017-06-17 16:48:40 +02:00
789fa507b5 Added StaticJsonBuffer::clear() 2017-06-17 15:00:46 +02:00
508f936317 Made JsonBuffer non-copyable (PR #524 by @luisrayas3) 2017-06-17 14:17:01 +02:00
197 changed files with 4025 additions and 2884 deletions

View File

@ -1,6 +1,6 @@
<!--
Before opening an issue, please read the FAQ:
https://bblanchon.github.io/ArduinoJson/faq/
https://arduinojson.org/faq/
Please provide all the relevant information:
* good title

View File

@ -8,12 +8,6 @@ matrix:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.4']
env: SCRIPT=cmake GCC=4.4
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.5']
env: SCRIPT=cmake GCC=4.5
- compiler: gcc
addons:
apt:
@ -43,13 +37,19 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5']
env: SCRIPT=cmake GCC=5 SANITIZE=undefined
env: SCRIPT=cmake GCC=5
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6']
env: SCRIPT=cmake GCC=6
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-7']
env: SCRIPT=cmake GCC=7
- compiler: clang
env: SCRIPT=cmake
- compiler: clang
@ -76,22 +76,58 @@ matrix:
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:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-3.9']
packages: ['clang-3.9']
env: SCRIPT=cmake CLANG=3.9
- compiler: clang
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:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-5.0']
packages: ['clang-5.0']
env: SCRIPT=cmake CLANG=5.0
- compiler: clang
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
- os: osx
osx_image: xcode6.4
osx_image: xcode7.3
compiler: clang
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.3
osx_image: xcode8.3
compiler: clang
env: SCRIPT=cmake
- os: osx
osx_image: xcode9.4
compiler: clang
env: SCRIPT=cmake
- os: osx
osx_image: xcode10
compiler: clang
env: SCRIPT=cmake SANITIZE=address
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.8.2 BOARD=arduino:avr:uno
- env: SCRIPT=platformio BOARD=uno
- env: SCRIPT=platformio BOARD=due
- env: SCRIPT=platformio BOARD=esp01
#- env: SCRIPT=platformio BOARD=teensy31C
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-6.0']
packages: ['clang-6.0','llvm-6.0']
env: SCRIPT=fuzz CLANG=6.0
cache:
directories:
- "~/.platformio"

View File

@ -1,8 +1,5 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include "src/ArduinoJson.h"

View File

@ -1,6 +1,108 @@
ArduinoJson: change log
=======================
v5.13.5
-------
* Fixed warning "unused variable" with GCC 4.4 (issue #912)
* Fixed warning "maybe uninitialized" (issue #909)
* Added an clear message for `StaticJsonDocument`, `DynamicJsonDocument`...
v5.13.4
-------
* Removed spurious files in the Particle library
v5.13.3
-------
* Improved float serialization when `-fsingle-precision-constant` is used
* Fixed `JsonVariant::is<int>()` that returned true for empty strings
* Fixed `JsonVariant::is<String>()` (closes #763)
v5.13.2
-------
* Fixed `JsonBuffer::parse()` not respecting nesting limit correctly (issue #693)
* Fixed inconsistencies in nesting level counting (PR #695 from Zhenyu Wu)
* Fixed null values that could be pass to `strcmp()` (PR #745 from Mike Karlesky)
* Added macros `ARDUINOJSON_VERSION`, `ARDUINOJSON_VERSION_MAJOR`...
v5.13.1
-------
* Fixed `JsonVariant::operator|(int)` that returned the default value if the variant contained a double (issue #675)
* Allowed non-quoted key to contain underscores (issue #665)
v5.13.0
-------
* Changed the rules of string duplication (issue #658)
* `RawJson()` accepts any kind of string and obeys to the same rules for duplication
* Changed the return type of `strdup()` to `const char*` to prevent double duplication
* Marked `strdup()` as deprecated
> ### New rules for string duplication
>
> | type | duplication |
> |:---------------------------|:------------|
> | const char* | no |
> | char* | ~~no~~ yes |
> | String | yes |
> | std::string | yes |
> | const __FlashStringHelper* | yes |
>
> These new rules make `JsonBuffer::strdup()` useless.
v5.12.0
-------
* Added `JsonVariant::operator|` to return a default value (see below)
* Added a clear error message when compiled as C instead of C++ (issue #629)
* Added detection of MPLAB XC compiler (issue #629)
* Added detection of Keil ARM Compiler (issue #629)
* Added an example that shows how to save and load a configuration file
* Reworked all other examples
> ### How to use the new feature?
>
> If you have a block like this:
>
> ```c++
> const char* ssid = root["ssid"];
> if (!ssid)
> ssid = "default ssid";
> ```
>
> You can simplify like that:
>
> ```c++
> const char* ssid = root["ssid"] | "default ssid";
> ```
v5.11.2
-------
* Fixed `DynamicJsonBuffer::clear()` not resetting allocation size (issue #561)
* Fixed incorrect rounding for float values (issue #588)
v5.11.1
-------
* Removed dependency on `PGM_P` as Particle 0.6.2 doesn't define it (issue #546)
* Fixed warning "dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]"
* Fixed warning "floating constant exceeds range of 'float' [-Woverflow]" (issue #544)
* Fixed warning "this statement may fall through" [-Wimplicit-fallthrough=] (issue #539)
* Removed `ARDUINOJSON_DOUBLE_IS_64BITS` as it became useless.
* Fixed too many decimals places in float serialization (issue #543)
v5.11.0
-------
* Made `JsonBuffer` non-copyable (PR #524 by @luisrayas3)
* Added `StaticJsonBuffer::clear()`
* Added `DynamicJsonBuffer::clear()`
v5.10.1
-------
@ -19,27 +121,26 @@ v5.10.0
* Fixed error `IsBaseOf is not a member of ArduinoJson::TypeTraits` (issue #495)
* Fixed error `forming reference to reference` (issue #495)
### BREAKING CHANGES :warning:
| Old syntax | New syntax |
|---------------------------------|---------------------|
| `double_with_n_digits(3.14, 2)` | `3.14` |
| `float_with_n_digits(3.14, 2)` | `3.14f` |
| `obj.set("key", 3.14, 2)` | `obj["key"] = 3.14` |
| `arr.add(3.14, 2)` | `arr.add(3.14)` |
| Input | Old output | New output |
|-----------|------------|------------|
| `3.14159` | `3.14` | `3.14159` |
| `42.0` | `42.00` | `42` |
| `0.0` | `0.00` | `0` |
| Expression | Old result | New result |
|--------------------------------|------------|------------|
| `JsonVariant(42).is<int>()` | `true` | `true` |
| `JsonVariant(42).is<float>()` | `false` | `true` |
| `JsonVariant(42).is<double>()` | `false` | `true` |
> ### BREAKING CHANGES :warning:
>
> | Old syntax | New syntax |
> |:--------------------------------|:--------------------|
> | `double_with_n_digits(3.14, 2)` | `3.14` |
> | `float_with_n_digits(3.14, 2)` | `3.14f` |
> | `obj.set("key", 3.14, 2)` | `obj["key"] = 3.14` |
> | `arr.add(3.14, 2)` | `arr.add(3.14)` |
>
> | Input | Old output | New output |
> |:----------|:-----------|:-----------|
> | `3.14159` | `3.14` | `3.14159` |
> | `42.0` | `42.00` | `42` |
> | `0.0` | `0.00` | `0` |
>
> | Expression | Old result | New result |
> |:-------------------------------|:-----------|:-----------|
> | `JsonVariant(42).is<int>()` | `true` | `true` |
> | `JsonVariant(42).is<float>()` | `false` | `true` |
> | `JsonVariant(42).is<double>()` | `false` | `true` |
v5.9.0
------
@ -93,24 +194,23 @@ v5.8.0
* Added support for `Stream` (issue #300)
* Reduced memory consumption by not duplicating spaces and comments
### BREAKING CHANGES :warning:
`JsonBuffer::parseObject()` and `JsonBuffer::parseArray()` have been pulled down to the derived classes `DynamicJsonBuffer` and `StaticJsonBufferBase`.
This means that if you have code like:
```c++
void myFunction(JsonBuffer& jsonBuffer);
```
you need to replace it with one of the following:
```c++
void myFunction(DynamicJsonBuffer& jsonBuffer);
void myFunction(StaticJsonBufferBase& jsonBuffer);
template<typename TJsonBuffer> void myFunction(TJsonBuffer& jsonBuffer);
```
> ### BREAKING CHANGES :warning:
>
> `JsonBuffer::parseObject()` and `JsonBuffer::parseArray()` have been pulled down to the derived classes `DynamicJsonBuffer` and `StaticJsonBufferBase`.
>
> This means that if you have code like:
>
> ```c++
> void myFunction(JsonBuffer& jsonBuffer);
> ```
>
> you need to replace it with one of the following:
>
> ```c++
> void myFunction(DynamicJsonBuffer& jsonBuffer);
> void myFunction(StaticJsonBufferBase& jsonBuffer);
> template<typename TJsonBuffer> void myFunction(TJsonBuffer& jsonBuffer);
> ```
v5.7.3
------
@ -143,27 +243,26 @@ v5.7.0
* Added example `StringExample.ino` to show where `String` can be used
* Increased default nesting limit to 50 when compiled for a computer (issue #349)
### BREAKING CHANGES :warning:
The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
Old code:
```c++
#define ARDUINOJSON_USE_ARDUINO_STRING 0
JsonVariant value1 = myObject.get("myKey");
JsonVariant value2 = myArray.get(0);
```
New code:
```c++
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#define ARDUINOJSON_ENABLE_STD_STRING 1
JsonVariant value1 = myObject.get<JsonVariant>("myKey");
JsonVariant value2 = myArray.get<JsonVariant>(0);
```
> ### BREAKING CHANGES :warning:
>
> The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
>
> Old code:
>
> ```c++
> #define ARDUINOJSON_USE_ARDUINO_STRING 0
> JsonVariant value1 = myObject.get("myKey");
> JsonVariant value2 = myArray.get(0);
> ```
>
> New code:
>
> ```c++
> #define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
> #define ARDUINOJSON_ENABLE_STD_STRING 1
> JsonVariant value1 = myObject.get<JsonVariant>("myKey");
> JsonVariant value2 = myArray.get<JsonVariant>(0);
> ```
v5.6.7
------
@ -255,8 +354,9 @@ v5.1.0
* Added support of `long long` (issue #171)
* Moved all build settings to `ArduinoJson/Configuration.hpp`
**BREAKING CHANGE**:
If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
> ### BREAKING CHANGE :warning:
>
> If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
v5.0.8
------
@ -270,10 +370,10 @@ v5.0.7
* Made library easier to use from a CMake project: simply `add_subdirectory(ArduinoJson/src)`
* Changed `String` to be a `typedef` of `std::string` (issues #142 and #161)
### BREAKING CHANGES :warning:
- `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
- `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
> ### BREAKING CHANGES :warning:
>
> - `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
> - `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
v5.0.6
------
@ -327,11 +427,11 @@ v5.0.0
* Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66)
* Switched to new the library layout (requires Arduino 1.0.6 or above)
### BREAKING CHANGES :warning:
- `JsonObject::add()` was renamed to `set()`
- `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
- Number of digits of floating point value are now set with `double_with_n_digits()`
> ### BREAKING CHANGES :warning:
>
> - `JsonObject::add()` was renamed to `set()`
> - `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
> - Number of digits of floating point value are now set with `double_with_n_digits()`
**Personal note about the `String` class**:
Support of the `String` class has been added to the library because many people use it in their programs.
@ -384,106 +484,7 @@ v4.0
* Unified parser and generator API (issue #23)
* Updated library layout, now requires Arduino 1.0.6 or newer
**BREAKING CHANGE**: API changed significantly, see [Migrating code to the new API](https://github.com/bblanchon/ArduinoJson/wiki/Migrating-code-to-the-new-API).
> ### BREAKING CHANGES :warning:
>
> API changed significantly since v3, see [Migrating code to the new API](https://arduinojson.org/doc/migration/).
v3.4
----
* Fixed escaped char parsing (issue #16)
v3.3
----
* Added indented output for the JSON generator (issue #11), see example bellow.
* Added `IndentedPrint`, a decorator for `Print` to allow indented output
Example:
JsonOject<2> json;
json["key"] = "value";
json.prettyPrintTo(Serial);
v3.2
----
* Fixed a bug when adding nested object in `JsonArray` (bug introduced in v3.1).
v3.1
----
* Calling `Generator::JsonObject::add()` twice with the same `key` now replaces the `value`
* Added `Generator::JsonObject::operator[]`, see bellow the new API
* Added `Generator::JsonObject::remove()` (issue #9)
Old generator API:
JsonObject<3> root;
root.add("sensor", "gps");
root.add("time", 1351824120);
root.add("data", array);
New generator API:
JsonObject<3> root;
root["sensor"] = "gps";
root["time"] = 1351824120;
root["data"] = array;
v3.0
----
* New parser API, see bellow
* Renamed `JsonHashTable` into `JsonObject`
* Added iterators for `JsonArray` and `JsonObject` (issue #4)
Old parser API:
JsonHashTable root = parser.parseHashTable(json);
char* sensor = root.getString("sensor");
long time = root.getLong("time");
double latitude = root.getArray("data").getDouble(0);
double longitude = root.getArray("data").getDouble(1);
New parser API:
JsonObject root = parser.parse(json);
char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
v2.1
----
* Fixed case `#include "jsmn.cpp"` which caused an error in Linux (issue #6)
* Fixed a buffer overrun in JSON Parser (issue #5)
v2.0
----
* Added JSON encoding (issue #2)
* Renamed the library `ArduinoJsonParser` becomes `ArduinoJson`
**Breaking change**: you need to add the following line at the top of your program.
using namespace ArduinoJson::Parser;
v1.2
----
* Fixed error in JSON parser example (issue #1)
v1.1
----
* Example: changed `char* json` into `char[] json` so that the bytes are not write protected
* Fixed parsing bug when the JSON contains multi-dimensional arrays
v1.0
----
Initial release

View File

@ -1,9 +1,6 @@
# Copyright Benoit Blanchon 2014-2017
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2019
# MIT License
#
# Arduino JSON library
# https://bblanchon.github.io/ArduinoJson/
# If you like this project, please add a star!
cmake_minimum_required(VERSION 3.0)
project(ArduinoJson)

11
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,11 @@
# Contribution to ArduinoJson
First, thank you for taking the time to contribute to this project.
You can submit changes via GitHub Pull Requests.
Please:
1. Unit test every change in behavior
2. Use clang-format in "file" mode to format the code
3. Consider using the Continuous Integration (Travis and AppVeyor)

View File

@ -1,7 +1,7 @@
The MIT License (MIT)
---------------------
Copyright © 2014-2017 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:

129
README.md
View File

@ -1,47 +1,64 @@
ArduinoJson - C++ JSON library for IoT
====================
![ArduinoJson](banner.svg)
[![Build status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/master?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/master) [![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=master)](https://travis-ci.org/bblanchon/ArduinoJson) [![Coverage Status](https://img.shields.io/coveralls/bblanchon/ArduinoJson.svg)](https://coveralls.io/r/bblanchon/ArduinoJson?branch=master) [![Star this project](http://githubbadges.com/star.svg?user=bblanchon&repo=ArduinoJson&style=flat&color=fff&background=007ec6)](https://github.com/bblanchon/ArduinoJson)
---
*An elegant and efficient JSON library for embedded systems.*
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=5.13.5)](https://www.ardu-badge.com/ArduinoJson/5.13.5)
[![Build Status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/master?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/master)
[![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=master)](https://travis-ci.org/bblanchon/ArduinoJson)
[![Coverage Status](https://img.shields.io/coveralls/bblanchon/ArduinoJson.svg)](https://coveralls.io/r/bblanchon/ArduinoJson?branch=master)
[![Star this project](http://githubbadges.com/star.svg?user=bblanchon&repo=ArduinoJson&style=flat&color=fff&background=007ec6)](https://github.com/bblanchon/ArduinoJson)
It's designed to have the most intuitive API, the smallest footprint and is able to work without any allocation on the heap (no malloc).
ArduinoJson is a C++ JSON library for Arduino and IoT (Internet Of Things).
It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project.
For instance, it supports Aduino's `String` and `Stream`, but also `std::string`, `std::istream` and `std::ostream`.
Features
--------
## Features
* JSON decoding (comments are supported)
* JSON encoding (with optional indentation)
* Elegant API, very easy to use
* Elegant API, easy to use
* Fixed memory allocation (zero malloc)
* No data duplication (zero copy)
* Portable (written in C++98)
* Portable (written in C++98, can be used in any C++ project)
* Self-contained (no external dependency)
* Small footprint
* Header-only library
* MIT License
* Input and output streams
* [100% code coverage](https://coveralls.io/github/bblanchon/ArduinoJson)
* [Header-only library](https://en.wikipedia.org/wiki/Header-only)
* [MIT License](https://en.wikipedia.org/wiki/MIT_License)
* [Comprehensive documentation](https://arduinojson.org?utm_source=github&utm_medium=readme)
Works on
--------
## Compatibility
* Arduino boards: Uno, Due, Mini, Micro, Yun...
* ESP8266, ESP32
* Teensy
* RedBearLab boards (BLE Nano...)
* Intel Edison and Galileo
* WeMos boards: D1...
* Computers: Windows, Linux, OSX...
* PlatformIO
* Particle
* Energia
ArduinoJson works on the following hardware:
Quick start
-----------
* <img src="https://www.arduino.cc/favicon.ico" height="16" width="16"> Arduino boards: [Uno](https://www.arduino.cc/en/Main/ArduinoBoardUno), [Due](https://www.arduino.cc/en/Main/ArduinoBoardDue), [Mini](https://www.arduino.cc/en/Main/ArduinoBoardMini), [Micro](https://www.arduino.cc/en/Main/ArduinoBoardMicro), [Yun](https://www.arduino.cc/en/Main/ArduinoBoardYun)...
* <img src="http://espressif.com/sites/all/themes/espressif/favicon.ico" height="16" width="16"> Espressif chips: [ESP8266](https://en.wikipedia.org/wiki/ESP8266), [ESP32](https://en.wikipedia.org/wiki/ESP32)
* <img src="https://www.wemos.cc/themes/martin-materialize-parallax/assets/favicon.ico" height="16" width="16"> WeMos boards: [D1](https://wiki.wemos.cc/products:d1:d1), [D1 mini](https://wiki.wemos.cc/products:d1:d1_mini), ...
* <img src="http://redbearlab.com/favicon.ico" height="16" width="16"> RedBearLab boards: [BLE Nano](http://redbearlab.com/blenano/), [BLE Mini](http://redbearlab.com/blemini/), [WiFi Micro](https://redbear.cc/product/wifi/wifi-micro.html), [LOLIN32](https://wiki.wemos.cc/products:lolin32:lolin32)...
* <img src="https://www.pjrc.com/favicon.ico" height="16" width="16"> [Teensy](https://www.pjrc.com/teensy/) boards
* <img src="https://software.intel.com/sites/all/themes/zero/favicon.ico" height="16" width="16"> Intel boards: Edison, Galileo...
* <img src="https://www-assets.particle.io/images/favicon.png" height="16" width="16"> Particle boards: [Photon](https://www.particle.io/products/hardware/photon-wifi-dev-kit), [Electron](https://www.particle.io/products/hardware/electron-cellular-dev-kit)...
* <img src="http://www.ti.com/favicon.ico" height="16" width="16"> Texas Instruments boards: [MSP430](http://www.ti.com/microcontrollers/msp430-ultra-low-power-mcus/overview/overview.html)...
#### Decoding / Parsing
ArduinoJson compiles with zero warning on the following compilers, IDEs, and platforms:
* <img src="https://www.arduino.cc/favicon.ico" height="16" width="16"> [Arduino IDE](https://www.arduino.cc/en/Main/Software)
* <img src="http://cdn.platformio.org/favicon.ico" height="16" width="16"> [PlatformIO](http://platformio.org/)
* <img src="http://energia.nu/img/favicon.ico" height="16" width="16"> [Energia](http://energia.nu/)
* <img src="http://www.visualmicro.com/pics/arduino-visual-studio-ld.png" height="16" width="16"> [Visual Micro](http://www.visualmicro.com/)
* <img src="http://www.atmel.com/Images/favicon.ico" height="16" width="16"> [Atmel Studio](http://www.atmel.com/microsite/atmel-studio/)
* <img src="https://www.iar.com/favicon.ico" height="16" width="16"> [IAR Embedded Workbench](https://www.iar.com/iar-embedded-workbench/)
* <img src="http://www.st.com/etc/clientlibs/st-site/media/app/images/favicon.png" height="16" width="16"> [Atollic TrueSTUDIO](https://atollic.com/truestudio/)
* <img src="http://www.keil.com/favicon.ico" height="16" width="16"> [Keil uVision](http://www.keil.com/)
* <img src="http://www.microchip.com/favicon.ico" height="16" width="16"> [MPLAB X IDE](http://www.microchip.com/mplab/mplab-x-ide)
* <img src="https://gcc.gnu.org/favicon.ico" height="16" width="16"> [GCC](https://gcc.gnu.org/)
* <img src="https://clang.llvm.org/favicon.ico" height="16" width="16"> [Clang](https://clang.llvm.org/)
* <img src="https://www.visualstudio.com/favicon.ico" height="16" width="16"> [Visual Studio](https://www.visualstudio.com/)
## Quickstart
### Deserialization
Here is a program that parses a JSON document with ArduinoJson.
```c++
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
@ -56,11 +73,11 @@ double latitude = root["data"][0];
double longitude = root["data"][1];
```
[See JsonParserExample.ino](examples/JsonParserExample/JsonParserExample.ino)
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_source=github&utm_medium=readme)
Use [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) to compute the buffer size.
### Serialization
#### Encoding / Generating
Here is a program that generates a JSON document with ArduinoJson:
```c++
StaticJsonBuffer<200> jsonBuffer;
@ -78,46 +95,20 @@ root.printTo(Serial);
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
```
[See JsonGeneratorExample.ino](examples/JsonGeneratorExample/JsonGeneratorExample.ino)
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/encoding/?utm_source=github&utm_medium=readme)
Use [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) to compute the buffer size.
## Documentation
The documentation is available on [arduinojson.org](https://arduinojson.org/?utm_source=github&utm_medium=readme), here are some shortcuts:
Documentation
-------------
The documentation is available online in the [ArduinoJson Website](https://bblanchon.github.io/ArduinoJson/).
The [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) helps you get started with the library.
Donators
--------
Special thanks to the following persons and companies who made generous donations to the library author:
* Robert Murphy <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Surge Communications <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Alex Scott <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
* Firepick Services LLC <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* A B Doodkorte <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Scott Smith <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Johann Stieger <img alt='Austria' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e6-1f1f9.svg' width='18' height='18'>
* Gustavo Donizeti Gini <img alt='Brazil' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e7-1f1f7.svg' width='18' height='18'>
* Charles-Henri Hallard <img alt='France' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1eb-1f1f7.svg' width='18' height='18'>
* Martijn van den Burg <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Nick Koumaris <img alt='Greece' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1f7.svg' width='18' height='18'>
* Jon Williams <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Kestutis Liaugminas <img alt='Lithuania' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f1-1f1f9.svg' width='18' height='18'>
* Darlington Adibe <img alt='Nigeria' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1ec.svg' width='18' height='18'>
* Yoeri Kroon <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Andrew Melvin <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
* Doanh Luong <img alt ='Vietnam' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fb-1f1f3.svg' width='18' height='18'>
* Christoph Schmidt <img alt='Germany' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e9-1f1ea.svg' width='18' height='18'>
* OpenEVSE LLC <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Prokhoryatov Alexey <img alt='Russia' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f7-1f1fa.svg' width='18' height='18'>
* Google Inc. <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* The [Examples](https://arduinojson.org/example/?utm_source=github&utm_medium=readme) show how to use the library in various situations.
* The [API Reference](https://arduinojson.org/api/?utm_source=github&utm_medium=readme) contains the description of each class and function.
* The [FAQ](https://arduinojson.org/faq/?utm_source=github&utm_medium=readme) has the answer to virtually every question.
* The [ArduinoJson Assistant](https://arduinojson.org/assistant/?utm_source=github&utm_medium=readme) writes programs for you!
---
Found this library useful? Please star this project or [help me back with a donation!](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate%40benoitblanchon%2efr&lc=GB&item_name=Benoit%20Blanchon&item_number=Arduino%20JSON&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :smile:
Do you like this library? Please [star this project on GitHub](https://github.com/bblanchon/ArduinoJson/stargazers)!
What? You don't like it but you *love* it?
We don't take donations anymore, but [we sell a book](https://arduinojson.org/book/?utm_source=github&utm_medium=readme), so you can help and learn at the same time!

27
SUPPORT.md Normal file
View File

@ -0,0 +1,27 @@
# ArduinoJson Support
First off, thank you very much for using ArduinoJson.
We'll be very happy to help you, but first please read the following.
## Before asking for help
1. Read the [FAQ](https://arduinojson.org/faq/?utm_source=github&utm_medium=support)
2. Search in the [API Reference](https://arduinojson.org/api/?utm_source=github&utm_medium=support)
If you did not find the answer, please create a [new issue on GitHub](https://github.com/bblanchon/ArduinoJson/issues/new).
It is OK to add a comment to a currently opened issue, but please avoid adding comments to a closed issue.
## Before hitting the Submit button
Please provide all the relevant information:
* Good title
* Short description of the problem
* Target platform
* Compiler model and version
* [MVCE](https://stackoverflow.com/help/mcve)
* Compiler output
Good questions get fast answers!

View File

@ -1,4 +1,4 @@
version: 5.10.1.{build}
version: 5.13.5.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017

367
banner.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -0,0 +1,144 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to store your project configuration in a file.
// It uses the SD library but can be easily modified for any other file-system.
//
// The file contains a JSON document with the following content:
// {
// "hostname": "examples.com",
// "port": 2731
// }
#include <ArduinoJson.h>
#include <SD.h>
#include <SPI.h>
// Configuration that we'll store on disk
struct Config {
char hostname[64];
int port;
};
const char *filename = "/config.txt"; // <- SD library uses 8.3 filenames
Config config; // <- global configuration object
// Loads the configuration from a file
void loadConfiguration(const char *filename, Config &config) {
// Open file for reading
File file = SD.open(filename);
// Allocate the memory pool on the stack.
// Don't forget to change the capacity to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<512> jsonBuffer;
// Parse the root object
JsonObject &root = jsonBuffer.parseObject(file);
if (!root.success())
Serial.println(F("Failed to read file, using default configuration"));
// Copy values from the JsonObject to the Config
config.port = root["port"] | 2731;
strlcpy(config.hostname, // <- destination
root["hostname"] | "example.com", // <- source
sizeof(config.hostname)); // <- destination's capacity
// Close the file (File's destructor doesn't close the file)
file.close();
}
// Saves the configuration to a file
void saveConfiguration(const char *filename, const Config &config) {
// Delete existing file, otherwise the configuration is appended to the file
SD.remove(filename);
// Open file for writing
File file = SD.open(filename, FILE_WRITE);
if (!file) {
Serial.println(F("Failed to create file"));
return;
}
// Allocate the memory pool on the stack
// Don't forget to change the capacity to match your JSON document.
// Use https://arduinojson.org/assistant/ to compute the capacity.
StaticJsonBuffer<256> jsonBuffer;
// Parse the root object
JsonObject &root = jsonBuffer.createObject();
// Set the values
root["hostname"] = config.hostname;
root["port"] = config.port;
// Serialize JSON to file
if (root.printTo(file) == 0) {
Serial.println(F("Failed to write to file"));
}
// Close the file (File's destructor doesn't close the file)
file.close();
}
// Prints the content of a file to the Serial
void printFile(const char *filename) {
// Open file for reading
File file = SD.open(filename);
if (!file) {
Serial.println(F("Failed to read file"));
return;
}
// Extract each characters by one by one
while (file.available()) {
Serial.print((char)file.read());
}
Serial.println();
// Close the file (File's destructor doesn't close the file)
file.close();
}
void setup() {
// Initialize serial port
Serial.begin(9600);
while (!Serial) continue;
// Initialize SD library
while (!SD.begin()) {
Serial.println(F("Failed to initialize SD library"));
delay(1000);
}
// Should load default config if run for the first time
Serial.println(F("Loading configuration..."));
loadConfiguration(filename, config);
// Create configuration file
Serial.println(F("Saving configuration..."));
saveConfiguration(filename, config);
// Dump config file
Serial.println(F("Print config file..."));
printFile(filename);
}
void loop() {
// not used in this example
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization or deserialization problem.
//
// The book "Mastering ArduinoJson" contains a case study of a project that has
// a complex configuration with nested members.
// Contrary to this example, the project in the book uses the SPIFFS filesystem.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,23 +1,21 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
// This example shows how to generate a JSON document with ArduinoJson.
#include <ArduinoJson.h>
void setup() {
// Initialize Serial port
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
while (!Serial) continue;
// Memory pool for JSON object tree.
//
// Inside the brackets, 200 is the size of the pool in bytes.
// If the JSON object is more complex, you need to increase that value.
// See https://bblanchon.github.io/ArduinoJson/assistant/
// Don't forget to change this value to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer allocates memory on the stack, it can be
@ -68,3 +66,16 @@ void setup() {
void loop() {
// not used in this example
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
// It begins with a simple example, like the one above, and then adds more
// features like serializing directly to a file or an HTTP request.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,184 +1,112 @@
// Sample Arduino Json Web Client
// Downloads and parse http://jsonplaceholder.typicode.com/users/1
//
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
// This example shows how to parse a JSON document in an HTTP response.
// It uses the Ethernet library, but can be easily adapted for Wifi.
//
// It performs a GET resquest on arduinojson.org/example.json
// Here is the expected response:
// {
// "sensor": "gps",
// "time": 1351824120,
// "data": [
// 48.756080,
// 2.302038
// ]
// }
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
EthernetClient client;
const char* server = "jsonplaceholder.typicode.com"; // server's address
const char* resource = "/users/1"; // http resource
const unsigned long BAUD_RATE = 9600; // serial connection speed
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
// The type of data that we want to extract from the page
struct UserData {
char name[32];
char company[32];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
initSerial();
initEthernet();
}
// Initialize Serial port
Serial.begin(9600);
while (!Serial) continue;
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if (connect(server)) {
if (sendRequest(server, resource) && skipResponseHeaders()) {
UserData userData;
if (readReponseContent(&userData)) {
printUserData(&userData);
}
}
}
disconnect();
wait();
}
// Initialize Serial port
void initSerial() {
Serial.begin(BAUD_RATE);
while (!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
}
// Initialize Ethernet library
void initEthernet() {
// Initialize Ethernet library
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
if (!Ethernet.begin(mac)) {
Serial.println("Failed to configure Ethernet");
Serial.println(F("Failed to configure Ethernet"));
return;
}
Serial.println("Ethernet ready");
delay(1000);
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
Serial.println(F("Connecting..."));
bool ok = client.connect(hostName, 80);
// Connect to HTTP server
EthernetClient client;
client.setTimeout(10000);
if (!client.connect("arduinojson.org", 80)) {
Serial.println(F("Connection failed"));
return;
}
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
Serial.println(F("Connected!"));
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
// Send HTTP request
client.println(F("GET /example.json HTTP/1.0"));
client.println(F("Host: arduinojson.org"));
client.println(F("Connection: close"));
if (client.println() == 0) {
Serial.println(F("Failed to send request"));
return;
}
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.0");
client.print("Host: ");
client.println(host);
client.println("Connection: close");
client.println();
// Check HTTP status
char status[32] = {0};
client.readBytesUntil('\r', status, sizeof(status));
if (strcmp(status, "HTTP/1.1 200 OK") != 0) {
Serial.print(F("Unexpected response: "));
Serial.println(status);
return;
}
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
// Skip HTTP headers
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
if (!client.find(endOfHeaders)) {
Serial.println(F("Invalid response"));
return;
}
return ok;
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
// {
// "id": 1,
// "name": "Leanne Graham",
// "username": "Bret",
// "email": "Sincere@april.biz",
// "address": {
// "street": "Kulas Light",
// "suite": "Apt. 556",
// "city": "Gwenborough",
// "zipcode": "92998-3874",
// "geo": {
// "lat": "-37.3159",
// "lng": "81.1496"
// }
// },
// "phone": "1-770-736-8031 x56442",
// "website": "hildegard.org",
// "company": {
// "name": "Romaguera-Crona",
// "catchPhrase": "Multi-layered client-server neural-net",
// "bs": "harness real-time e-markets"
// }
// }
bool readReponseContent(struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// See https://bblanchon.github.io/ArduinoJson/assistant/
const size_t BUFFER_SIZE =
JSON_OBJECT_SIZE(8) // the root object has 8 elements
+ JSON_OBJECT_SIZE(5) // the "address" object has 5 elements
+ JSON_OBJECT_SIZE(2) // the "geo" object has 2 elements
+ JSON_OBJECT_SIZE(3) // the "company" object has 3 elements
+ MAX_CONTENT_SIZE; // additional space for strings
// Allocate a temporary memory pool
DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);
// Allocate JsonBuffer
// Use arduinojson.org/assistant to compute the capacity.
const size_t capacity = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2) + 60;
DynamicJsonBuffer jsonBuffer(capacity);
// Parse JSON object
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
Serial.println(F("Parsing failed!"));
return;
}
// Here were copy the strings we're interested in
strcpy(userData->name, root["name"]);
strcpy(userData->company, root["company"]["name"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
// Extract values
Serial.println(F("Response:"));
Serial.println(root["sensor"].as<char*>());
Serial.println(root["time"].as<char*>());
Serial.println(root["data"][0].as<char*>());
Serial.println(root["data"][1].as<char*>());
return true;
}
// Print the data extracted from the JSON
void printUserData(const struct UserData* userData) {
Serial.print("Name = ");
Serial.println(userData->name);
Serial.print("Company = ");
Serial.println(userData->company);
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
// Disconnect
client.stop();
}
// Pause for a 1 minute
void wait() {
Serial.println("Wait 60 seconds");
delay(60000);
void loop() {
// not used in this example
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on deserialization
// showing how to parse the response from Yahoo Weather. In the last chapter,
// it shows how to parse the huge documents from OpenWeatherMap
// and Weather Underground.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,23 +1,21 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
// This example shows how to deserialize a JSON document with ArduinoJson.
#include <ArduinoJson.h>
void setup() {
// Initialize serial port
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
while (!Serial) continue;
// Memory pool for JSON object tree.
//
// Inside the brackets, 200 is the size of the pool in bytes,
// If the JSON object is more complex, you need to increase that value.
// See https://bblanchon.github.io/ArduinoJson/assistant/
// Inside the brackets, 200 is the size of the pool in bytes.
// Don't forget to change this value to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer allocates memory on the stack, it can be
@ -65,3 +63,16 @@ void setup() {
void loop() {
// not used in this example
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// deserialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on deserialization.
// It begins with a simple example, like the one above, and then adds more
// features like deserializing directly from a file or an HTTP request.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,76 +1,109 @@
// Sample Arduino Json Web Server
// Created by Benoit Blanchon.
// Heavily inspired by "Web Server" from David A. Mellis and Tom Igoe
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to implement an HTTP server that sends JSON document
// in the responses.
// It uses the Ethernet library but can be easily adapted for Wifi.
//
// It sends the value of the analog and digital pins.
// The JSON document looks like the following:
// {
// "analog": [ 0, 1, 2, 3, 4, 5 ],
// "digital": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
// }
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 0, 177);
EthernetServer server(80);
bool readRequest(EthernetClient& client) {
bool currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
return true;
} else if (c == '\n') {
currentLineIsBlank = true;
} else if (c != '\r') {
currentLineIsBlank = false;
}
}
void setup() {
// Initialize serial port
Serial.begin(9600);
while (!Serial) continue;
// Initialize Ethernet libary
if (!Ethernet.begin(mac)) {
Serial.println(F("Failed to initialize Ethernet library"));
return;
}
return false;
// Start to listen
server.begin();
Serial.println(F("Server is ready."));
Serial.print(F("Please connect to http://"));
Serial.println(Ethernet.localIP());
}
JsonObject& prepareResponse(JsonBuffer& jsonBuffer) {
void loop() {
// Wait for an incomming connection
EthernetClient client = server.available();
// Do we have a client?
if (!client) return;
Serial.println(F("New client"));
// Read the request (we ignore the content in this example)
while (client.available()) client.read();
// Allocate JsonBuffer
// Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<500> jsonBuffer;
// Create the root object
JsonObject& root = jsonBuffer.createObject();
// Create the "analog" array
JsonArray& analogValues = root.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
// Read the analog input
int value = analogRead(pin);
// Add the value at the end of the array
analogValues.add(value);
}
// Create the "digital" array
JsonArray& digitalValues = root.createNestedArray("digital");
for (int pin = 0; pin < 14; pin++) {
// Read the digital input
int value = digitalRead(pin);
// Add the value at the end of the array
digitalValues.add(value);
}
return root;
}
Serial.print(F("Sending: "));
root.printTo(Serial);
Serial.println();
void writeResponse(EthernetClient& client, JsonObject& json) {
client.println("HTTP/1.1 200 OK");
// Write response headers
client.println("HTTP/1.0 200 OK");
client.println("Content-Type: application/json");
client.println("Connection: close");
client.println();
json.prettyPrintTo(client);
// Write JSON document
root.prettyPrintTo(client);
// Disconnect
client.stop();
}
void setup() {
Ethernet.begin(mac, ip);
server.begin();
}
void loop() {
EthernetClient client = server.available();
if (client) {
bool success = readRequest(client);
if (success) {
// Use https://bblanchon.github.io/ArduinoJson/assistant/ to
// compute the right size for the buffer
StaticJsonBuffer<500> jsonBuffer;
JsonObject& json = prepareResponse(jsonBuffer);
writeResponse(client, json);
}
delay(1);
client.stop();
}
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
// It begins with a simple example, then adds more features like serializing
// directly to a file or an HTTP client.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,57 +1,101 @@
// Send a JSON object on UDP at regular interval
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// You can easily test this program with netcat:
// $ nc -ulp 8888
// This example shows how to send a JSON document to a UDP socket.
// At regular interval, it sends a UDP packet that contains the status of
// analog and digital pins.
// The JSON document looks like the following:
// {
// "analog": [ 0, 1, 2, 3, 4, 5 ],
// "digital": [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ]
// }
//
// by Benoit Blanchon, MIT License 2015-2017
// If you want to test this program, you need to be able to receive the UDP
// packets.
// For example, you can run netcat on your computer
// $ ncat -ulp 8888
// See https://nmap.org/ncat/
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress localIp(192, 168, 0, 177);
IPAddress remoteIp(192, 168, 0, 109);
unsigned int remotePort = 8888;
unsigned localPort = 8888;
IPAddress remoteIp(192, 168, 0, 108); // <- EDIT!!!!
unsigned short remotePort = 8888;
unsigned short localPort = 8888;
EthernetUDP udp;
JsonObject& buildJson(JsonBuffer& jsonBuffer) {
JsonObject& root = jsonBuffer.createObject();
JsonArray& analogValues = root.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(pin);
analogValues.add(value);
}
JsonArray& digitalValues = root.createNestedArray("digital");
for (int pin = 0; pin < 14; pin++) {
int value = digitalRead(pin);
digitalValues.add(value);
}
return root;
}
void sendJson(JsonObject& json) {
udp.beginPacket(remoteIp, remotePort);
json.printTo(udp);
udp.println();
udp.endPacket();
}
void setup() {
Ethernet.begin(mac, localIp);
// Initialize serial port
Serial.begin(9600);
while (!Serial) continue;
// Initialize Ethernet libary
if (!Ethernet.begin(mac)) {
Serial.println(F("Failed to initialize Ethernet library"));
return;
}
// Enable UDP
udp.begin(localPort);
}
void loop() {
delay(1000);
// Allocate JsonBuffer
// Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<500> jsonBuffer;
// Use https://bblanchon.github.io/ArduinoJson/assistant/ to
// compute the right size for the buffer
StaticJsonBuffer<300> jsonBuffer;
JsonObject& json = buildJson(jsonBuffer);
sendJson(json);
// Create the root object
JsonObject& root = jsonBuffer.createObject();
// Create the "analog" array
JsonArray& analogValues = root.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
// Read the analog input
int value = analogRead(pin);
// Add the value at the end of the array
analogValues.add(value);
}
// Create the "digital" array
JsonArray& digitalValues = root.createNestedArray("digital");
for (int pin = 0; pin < 14; pin++) {
// Read the digital input
int value = digitalRead(pin);
// Add the value at the end of the array
digitalValues.add(value);
}
// Log
Serial.print(F("Sending to "));
Serial.print(remoteIp);
Serial.print(F(" on port "));
Serial.println(remotePort);
root.printTo(Serial);
// Send UDP packet
udp.beginPacket(remoteIp, remotePort);
root.printTo(udp);
udp.println();
udp.endPacket();
// Wait
delay(10000);
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
// It begins with a simple example, then adds more features like serializing
// directly to a file or any stream.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,21 +1,19 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
// This example shows the different ways you can use Flash strings with
// ArduinoJson.
//
// Use Flash strings sparingly, because ArduinoJson duplicates them in the
// JsonBuffer. Prefer plain old char*, as they are more efficient in term of
// code size, speed, and memory usage.
#include <ArduinoJson.h>
// About
// -----
// This example shows the different ways you can use PROGMEM with ArduinoJson.
// Please don't see this as an invitation to use PROGMEM.
// On the contrary, you should always use char[] when possible, it's much more
// efficient in term of code size, speed and memory usage.
void setup() {
#ifdef PROGMEM
#ifdef PROGMEM // <- check that Flash strings are supported
DynamicJsonBuffer jsonBuffer;
// You can use a Flash String as your JSON input.
@ -39,6 +37,9 @@ void setup() {
// JsonBuffer.
root["sensor"] = F("gps");
// It works with RawJson too:
root["sensor"] = RawJson(F("\"gps\""));
// You can compare the content of a JsonVariant to a Flash String
if (root["sensor"] == F("gps")) {
// ...
@ -54,3 +55,16 @@ void setup() {
void loop() {
// not used in this example
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any memory
// problem.
//
// The book "Mastering ArduinoJson" contains a quick C++ course that explains
// how your microcontroller stores strings in memory. It also tells why you
// should not abuse Flash strings with ArduinoJson.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,19 +1,15 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
// This example shows the different ways you can use String with ArduinoJson.
//
// Use String objects sparingly, because ArduinoJson duplicates them in the
// JsonBuffer. Prefer plain old char[], as they are more efficient in term of
// code size, speed, and memory usage.
#include <ArduinoJson.h>
// About
// -----
// This example shows the different ways you can use String with ArduinoJson.
// Please don't see this as an invitation to use String.
// On the contrary, you should always use char[] when possible, it's much more
// efficient in term of code size, speed and memory usage.
void setup() {
DynamicJsonBuffer jsonBuffer;
@ -44,6 +40,9 @@ void setup() {
// WARNING: the content of the String will be duplicated in the JsonBuffer.
root["sensor"] = sensor;
// It works with RawJson too:
root["sensor"] = RawJson(sensor);
// You can also concatenate strings
// WARNING: the content of the String will be duplicated in the JsonBuffer.
root[String("sen") + "sor"] = String("gp") + "s";
@ -61,3 +60,15 @@ void setup() {
void loop() {
// not used in this example
}
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any problem.
//
// The book "Mastering ArduinoJson" contains a quick C++ course that explains
// how your microcontroller stores strings in memory. On several occasions, it
// shows how you can avoid String in your program.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,9 +0,0 @@
#!/bin/bash
# This script mimics an invocation from https://github.com/google/oss-fuzz
cd $(dirname $0)
export CXX='clang++'
export CXXFLAGS='-fsanitize-coverage=trace-pc-guard -fsanitize=address'
export LIB_FUZZING_ENGINE=-lFuzzer
make OUT=.
./json_fuzzer my_corpus seed_corpus -max_len=1024 -timeout=10

View File

@ -2,11 +2,12 @@
"name": "ArduinoJson",
"keywords": "json, rest, http, web",
"description": "An elegant and efficient JSON library for embedded systems",
"homepage": "https://arduinojson.org/?utm_source=meta&utm_medium=library.json",
"repository": {
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "5.10.1",
"version": "5.13.5",
"authors": {
"name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr"

View File

@ -1,9 +1,11 @@
name=ArduinoJson
version=5.10.1
version=5.13.5
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=An efficient and elegant JSON library for Arduino.
paragraph=Like this project? Please star it on GitHub!
paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ fixed allocation, ✔ zero-copy, ✔ streams, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation.
category=Data Processing
url=https://bblanchon.github.io/ArduinoJson/
url=https://arduinojson.org/?utm_source=meta&utm_medium=library.properties
architectures=*
repository=https://github.com/bblanchon/ArduinoJson.git
license=MIT

View File

@ -1,42 +0,0 @@
#!/bin/bash
set -eu
OUTPUT="$(pwd)/sizes.csv"
echo "Tag;Date;Parser;Generator" > $OUTPUT
cd $(dirname $(dirname $0))
git tag | while read TAG
do
git checkout -q tags/$TAG
DATE=$(git log -1 --date=short --pretty=format:%cd)
PARSER_SIZE=$(arduino --verify examples/JsonParserExample/JsonParserExample.ino 2>/dev/null | grep -e 'Sketch uses' | sed 's/.*uses \([0-9]*\).\([0-9]\+\).*/\1\2/')
if [ -e 'examples/JsonGeneratorExample/JsonGeneratorExample.ino' ]; then
GENERATOR_SIZE=$(arduino --verify examples/JsonGeneratorExample/JsonGeneratorExample.ino 2>/dev/null | grep -e 'Sketch uses' | sed 's/.*uses \([0-9]*\).\([0-9]\+\).*/\1\2/')
else
GENERATOR_SIZE=""
fi
echo $TAG
if [ ! -z "$PARSER_SIZE" ]
then
echo "JsonParserExample = $PARSER_SIZE bytes"
else
echo "JsonParserExample compilation failed."
fi
if [ ! -z "$GENERATOR_SIZE" ]
then
echo "JsonGeneratorExample = $GENERATOR_SIZE bytes"
else
echo "JsonGeneratorExample compilation failed."
fi
echo "$TAG;$DATE;$PARSER_SIZE;$GENERATOR_SIZE" >> $OUTPUT
done

View File

@ -0,0 +1,18 @@
#!/usr/bin/env bash
set -eu
SOURCE_DIR="$(dirname "$0")/.."
WORK_DIR=$(mktemp -d)
trap 'rm -rf "$WORK_DIR"' EXIT
cp "$SOURCE_DIR/README.md" "$WORK_DIR/README.md"
cp "$SOURCE_DIR/CHANGELOG.md" "$WORK_DIR/CHANGELOG.md"
cp "$SOURCE_DIR/library.properties" "$WORK_DIR/library.properties"
cp "$SOURCE_DIR/LICENSE.md" "$WORK_DIR/LICENSE.txt"
cp -r "$SOURCE_DIR/src" "$WORK_DIR/"
cp -r "$SOURCE_DIR/examples" "$WORK_DIR/"
cd "$WORK_DIR"
particle library upload
particle library publish

View File

@ -1,6 +1,6 @@
#!/bin/sh -ex
if [ $(uname) = 'Darwin' ]; then
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
@ -23,8 +23,11 @@ fi
if [ -n "$SANITIZE" ]; then
export CXXFLAGS="-fsanitize=$SANITIZE"
BUILD_TYPE="Debug"
else
BUILD_TYPE="Release"
fi
$CMAKE .
$CMAKE -DCMAKE_BUILD_TYPE=$BUILD_TYPE .
$CMAKE --build .
$CTEST --output-on-failure .

20
scripts/travis/fuzz.sh Executable file
View File

@ -0,0 +1,20 @@
#!/bin/bash -eux
ROOT_DIR=$(dirname $0)/../../
INCLUDE_DIR=$ROOT_DIR/src/
FUZZING_DIR=$ROOT_DIR/fuzzing/
JSON_CORPUS_DIR=$FUZZING_DIR/my_corpus
JSON_SEED_CORPUS_DIR=$FUZZING_DIR/seed_corpus
CXX="clang++-$CLANG"
CXXFLAGS="-g -fprofile-instr-generate -fcoverage-mapping -fsanitize=address,fuzzer"
$CXX $CXXFLAGS -o json_fuzzer -I$INCLUDE_DIR $FUZZING_DIR/fuzzer.cpp
export ASAN_OPTIONS="detect_leaks=0"
export LLVM_PROFILE_FILE="json_fuzzer.profraw"
./json_fuzzer "$JSON_CORPUS_DIR" "$JSON_SEED_CORPUS_DIR" -max_total_time=60
llvm-profdata-$CLANG merge -sparse json_fuzzer.profraw -o json_fuzzer.profdata
llvm-cov-$CLANG report ./json_fuzzer -instr-profile=json_fuzzer.profdata

View File

@ -1,12 +1,17 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#ifdef __cplusplus
#include "ArduinoJson.hpp"
using namespace ArduinoJson;
#else
#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp
#endif

View File

@ -1,16 +1,14 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "ArduinoJson/version.hpp"
#include "ArduinoJson/DynamicJsonBuffer.hpp"
#include "ArduinoJson/JsonArray.hpp"
#include "ArduinoJson/JsonObject.hpp"
#include "ArduinoJson/JsonVariantComparisons.hpp"
#include "ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson/Deserialization/JsonParserImpl.hpp"
@ -19,3 +17,5 @@
#include "ArduinoJson/JsonObjectImpl.hpp"
#include "ArduinoJson/JsonVariantImpl.hpp"
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"
#include "ArduinoJson/compatibility.hpp"

View File

@ -1,15 +1,13 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
// Small or big machine?
#ifndef ARDUINOJSON_EMBEDDED_MODE
#if defined(ARDUINO) || defined(__IAR_SYSTEMS_ICC__)
#if defined(ARDUINO) || defined(__IAR_SYSTEMS_ICC__) || defined(__XC) || \
defined(__ARMCC_VERSION)
#define ARDUINOJSON_EMBEDDED_MODE 1
#else
#define ARDUINOJSON_EMBEDDED_MODE 0
@ -148,16 +146,6 @@
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
#endif
// how many bits in a double
#ifndef ARDUINOJSON_DOUBLE_IS_64BITS
#if /*GCC*/ (defined(__SIZEOF_DOUBLE__) && __SIZEOF_DOUBLE__ < 8) || \
/*IAR*/ (defined(__DOUBLE__) && __DOUBLE__ < 64)
#define ARDUINOJSON_DOUBLE_IS_64BITS 0
#else
#define ARDUINOJSON_DOUBLE_IS_64BITS 1 // by default support 64-bit
#endif
#endif
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
#endif

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -36,5 +33,5 @@ class Encoding {
return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0];
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -19,7 +16,7 @@ class JsonBufferAllocated {
return jsonBuffer->alloc(n);
}
void operator delete(void *, JsonBuffer *)throw() {}
void operator delete(void *, JsonBuffer *)throw();
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -17,5 +14,5 @@ typedef double JsonFloat;
#else
typedef float JsonFloat;
#endif
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -22,5 +19,5 @@ typedef unsigned _int64 JsonUInt;
typedef long JsonInteger;
typedef unsigned long JsonUInt;
#endif
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -41,5 +38,5 @@ template <>
struct JsonVariantAs<const JsonObject> {
typedef const JsonObject& type;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,69 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../JsonVariantBase.hpp"
#include "../StringTraits/StringTraits.hpp"
#include "../TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TComparand, typename Enable = void>
struct JsonVariantComparer {};
template <typename TString>
struct JsonVariantComparer<
TString,
typename TypeTraits::EnableIf<TypeTraits::IsString<TString>::value>::type> {
template <typename TVariant>
static bool equals(const JsonVariantBase<TVariant> &variant,
const TString &comparand) {
const char *value = variant.template as<const char *>();
return Internals::StringTraits<TString>::equals(comparand, value);
}
};
template <typename TComparand>
struct JsonVariantComparer<
TComparand, typename TypeTraits::EnableIf<
!TypeTraits::IsVariant<TComparand>::value &&
!TypeTraits::IsString<TComparand>::value>::type> {
template <typename TVariant>
static bool equals(const JsonVariantBase<TVariant> &variant,
const TComparand &comparand) {
return variant.template as<TComparand>() == comparand;
}
};
template <typename TVariant2>
struct JsonVariantComparer<TVariant2,
typename TypeTraits::EnableIf<
TypeTraits::IsVariant<TVariant2>::value>::type> {
template <typename TVariant1>
static bool equals(const JsonVariantBase<TVariant1> &left,
const TVariant2 &right) {
if (left.template is<bool>() && right.template is<bool>())
return left.template as<bool>() == right.template as<bool>();
if (left.template is<JsonInteger>() && right.template is<JsonInteger>())
return left.template as<JsonInteger>() ==
right.template as<JsonInteger>();
if (left.template is<JsonFloat>() && right.template is<JsonFloat>())
return left.template as<JsonFloat>() == right.template as<JsonFloat>();
if (left.template is<JsonArray>() && right.template is<JsonArray>())
return left.template as<JsonArray>() == right.template as<JsonArray>();
if (left.template is<JsonObject>() && right.template is<JsonObject>())
return left.template as<JsonObject>() == right.template as<JsonObject>();
if (left.template is<char *>() && right.template is<char *>())
return strcmp(left.template as<char *>(), right.template as<char *>()) ==
0;
return false;
}
};
}
}

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -26,5 +23,5 @@ union JsonVariantContent {
JsonArray* asArray; // asArray cannot be null
JsonObject* asObject; // asObject cannot be null
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -22,5 +19,5 @@ struct JsonVariantDefault<const T> : JsonVariantDefault<T> {};
template <typename T>
struct JsonVariantDefault<T&> : JsonVariantDefault<T> {};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -26,5 +23,5 @@ enum JsonVariantType {
JSON_OBJECT, // JsonVariant stores a pointer to a JsonObject
JSON_FLOAT // JsonVariant stores a JsonFloat
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -93,5 +90,5 @@ class List {
private:
node_type *_firstNode;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -49,5 +46,5 @@ class ListConstIterator {
private:
const ListNode<T> *_node;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -59,5 +56,5 @@ class ListIterator {
private:
ListNode<T> *_node;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -18,10 +15,10 @@ namespace Internals {
// Used by List<T> and its iterators.
template <typename T>
struct ListNode : public Internals::JsonBufferAllocated {
ListNode() : next(NULL) {}
ListNode() throw() : next(NULL) {}
ListNode<T> *next;
T content;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -0,0 +1,23 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
namespace ArduinoJson {
namespace Internals {
// A type that cannot be copied
class NonCopyable {
protected:
NonCopyable() {}
private:
// copy constructor is private
NonCopyable(const NonCopyable&);
// copy operator is private
NonCopyable& operator=(const NonCopyable&);
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -22,16 +19,6 @@ class ReferenceType {
bool operator!=(const ReferenceType& other) const {
return this != &other;
}
protected:
ReferenceType() {}
private:
// copy constructor is private
ReferenceType(const ReferenceType&);
// copy operator is private
ReferenceType& operator=(const ReferenceType&);
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -0,0 +1,52 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../JsonBuffer.hpp"
#include "../JsonVariant.hpp"
#include "../StringTraits/StringTraits.hpp"
#include "../TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename Source, typename Enable = void>
struct ValueSaver {
template <typename Destination>
static bool save(JsonBuffer*, Destination& destination, Source source) {
destination = source;
return true;
}
};
template <typename Source>
struct ValueSaver<
Source, typename EnableIf<StringTraits<Source>::should_duplicate>::type> {
template <typename Destination>
static bool save(JsonBuffer* buffer, Destination& dest, Source source) {
if (!StringTraits<Source>::is_null(source)) {
typename StringTraits<Source>::duplicate_t dup =
StringTraits<Source>::duplicate(source, buffer);
if (!dup) return false;
dest = dup;
} else {
dest = reinterpret_cast<const char*>(0);
}
return true;
}
};
// const char*, const signed char*, const unsigned char*
template <typename Char>
struct ValueSaver<
Char*, typename EnableIf<!StringTraits<Char*>::should_duplicate>::type> {
template <typename Destination>
static bool save(JsonBuffer*, Destination& dest, Char* source) {
dest = reinterpret_cast<const char*>(source);
return true;
}
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,51 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include "../JsonVariant.hpp"
#include "../StringTraits/StringTraits.hpp"
#include "../TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TSourceRef, typename Enable = void>
struct ValueSetter {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
destination = source;
return true;
}
};
template <typename TSourceRef>
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<StringTraits<
TSourceRef>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer* buffer, TDestination& destination,
TSourceRef source) {
const char* copy = buffer->strdup(source);
if (!copy) return false;
destination = copy;
return true;
}
};
template <typename TSourceRef>
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<!StringTraits<
TSourceRef>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
// unsigned char* -> char*
destination = reinterpret_cast<const char*>(source);
return true;
}
};
}
}

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -60,5 +57,5 @@ void skipSpacesAndComments(TInput& input) {
}
}
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -47,19 +44,18 @@ class JsonParser {
const char *parseString();
bool parseAnythingTo(JsonVariant *destination);
FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
inline bool parseArrayTo(JsonVariant *destination);
inline bool parseObjectTo(JsonVariant *destination);
inline bool parseStringTo(JsonVariant *destination);
static inline bool isInRange(char c, char min, char max) {
static inline bool isBetween(char c, char min, char max) {
return min <= c && c <= max;
}
static inline bool isLetterOrNumber(char c) {
return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') ||
isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.';
static inline bool canBeInNonQuotedString(char c) {
return isBetween(c, '0', '9') || isBetween(c, '_', 'z') ||
isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.';
}
static inline bool isQuote(char c) {
@ -74,7 +70,7 @@ class JsonParser {
template <typename TJsonBuffer, typename TString, typename Enable = void>
struct JsonParserBuilder {
typedef typename Internals::StringTraits<TString>::Reader InputReader;
typedef typename StringTraits<TString>::Reader InputReader;
typedef JsonParser<InputReader, TJsonBuffer &> TParser;
static TParser makeParser(TJsonBuffer *buffer, TString &json,
@ -84,10 +80,9 @@ struct JsonParserBuilder {
};
template <typename TJsonBuffer, typename TChar>
struct JsonParserBuilder<
TJsonBuffer, TChar *,
typename TypeTraits::EnableIf<!TypeTraits::IsConst<TChar>::value>::type> {
typedef typename Internals::StringTraits<TChar *>::Reader TReader;
struct JsonParserBuilder<TJsonBuffer, TChar *,
typename EnableIf<!IsConst<TChar>::value>::type> {
typedef typename StringTraits<TChar *>::Reader TReader;
typedef StringWriter<TChar> TWriter;
typedef JsonParser<TReader, TWriter> TParser;
@ -103,5 +98,5 @@ inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser(
return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json,
nestingLimit);
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -20,18 +17,9 @@ inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat(
}
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<
TReader, TWriter>::parseAnythingTo(JsonVariant *destination) {
if (_nestingLimit == 0) return false;
_nestingLimit--;
bool success = parseAnythingToUnsafe(destination);
_nestingLimit++;
return success;
}
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<
TReader, TWriter>::parseAnythingToUnsafe(JsonVariant *destination) {
inline bool
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
JsonVariant *destination) {
skipSpacesAndComments(_reader);
switch (_reader.current()) {
@ -49,6 +37,9 @@ inline bool ArduinoJson::Internals::JsonParser<
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonArray &
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
if (_nestingLimit == 0) return JsonArray::invalid();
_nestingLimit--;
// Create an empty array
JsonArray &array = _buffer->createArray();
@ -70,6 +61,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
SUCCESS_EMPTY_ARRAY:
SUCCES_NON_EMPTY_ARRAY:
_nestingLimit++;
return array;
ERROR_INVALID_VALUE:
@ -92,6 +84,9 @@ inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonObject &
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
if (_nestingLimit == 0) return JsonObject::invalid();
_nestingLimit--;
// Create an empty object
JsonObject &object = _buffer->createObject();
@ -118,6 +113,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
SUCCESS_EMPTY_OBJECT:
SUCCESS_NON_EMPTY_OBJECT:
_nestingLimit++;
return object;
ERROR_INVALID_KEY:
@ -142,8 +138,7 @@ inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo(
template <typename TReader, typename TWriter>
inline const char *
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
typename TypeTraits::RemoveReference<TWriter>::type::String str =
_writer.startString();
typename RemoveReference<TWriter>::type::String str = _writer.startString();
skipSpacesAndComments(_reader);
char c = _reader.current();
@ -169,7 +164,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
}
} else { // no quotes
for (;;) {
if (!isLetterOrNumber(c)) break;
if (!canBeInNonQuotedString(c)) break;
_reader.move();
str.append(c);
c = _reader.current();

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -40,5 +37,5 @@ class StringWriter {
private:
TChar* _ptr;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -22,6 +19,7 @@
#endif
namespace ArduinoJson {
namespace Internals {
class DefaultAllocator {
public:
void* allocate(size_t size) {
@ -46,30 +44,41 @@ class DynamicJsonBufferBase
};
public:
enum { EmptyBlockSize = sizeof(EmptyBlock) };
DynamicJsonBufferBase(size_t initialSize = 256)
: _head(NULL), _nextBlockCapacity(initialSize) {}
~DynamicJsonBufferBase() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
Block* nextBlock = currentBlock->next;
_allocator.deallocate(currentBlock);
currentBlock = nextBlock;
}
clear();
}
// Gets the number of bytes occupied in the buffer
size_t size() const {
size_t total = 0;
for (const Block* b = _head; b; b = b->next) total += b->size;
return total;
}
// Allocates the specified amount of bytes in the buffer
virtual void* alloc(size_t bytes) {
alignNextAlloc();
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
}
// Resets the buffer.
// USE WITH CAUTION: this invalidates all previously allocated data
void clear() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
_nextBlockCapacity = currentBlock->capacity;
Block* nextBlock = currentBlock->next;
_allocator.deallocate(currentBlock);
currentBlock = nextBlock;
}
_head = 0;
}
class String {
public:
String(DynamicJsonBufferBase* parent)
@ -129,7 +138,7 @@ class DynamicJsonBufferBase
}
bool addNewBlock(size_t capacity) {
size_t bytes = sizeof(EmptyBlock) + capacity;
size_t bytes = EmptyBlockSize + capacity;
Block* block = static_cast<Block*>(_allocator.allocate(bytes));
if (block == NULL) return false;
block->capacity = capacity;
@ -143,6 +152,7 @@ class DynamicJsonBufferBase
Block* _head;
size_t _nextBlockCapacity;
};
} // namespace Internals
#if defined(__clang__)
#pragma clang diagnostic pop
@ -155,5 +165,6 @@ class DynamicJsonBufferBase
// Implements a JsonBuffer with dynamic memory allocation.
// You are strongly encouraged to consider using StaticJsonBuffer which is much
// more suitable for embedded systems.
typedef DynamicJsonBufferBase<DefaultAllocator> DynamicJsonBuffer;
}
typedef Internals::DynamicJsonBufferBase<Internals::DefaultAllocator>
DynamicJsonBuffer;
} // namespace ArduinoJson

View File

@ -1,16 +1,13 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "Data/JsonBufferAllocated.hpp"
#include "Data/List.hpp"
#include "Data/ReferenceType.hpp"
#include "Data/ValueSetter.hpp"
#include "Data/ValueSaver.hpp"
#include "JsonVariant.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "StringTraits/StringTraits.hpp"
@ -29,7 +26,9 @@ namespace ArduinoJson {
// Forward declarations
class JsonObject;
class JsonBuffer;
namespace Internals {
class JsonArraySubscript;
}
// An array of JsonVariant.
//
@ -39,38 +38,37 @@ class JsonArraySubscript;
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
class JsonArray : public Internals::JsonPrintable<JsonArray>,
public Internals::ReferenceType,
public Internals::NonCopyable,
public Internals::List<JsonVariant>,
public Internals::JsonBufferAllocated {
public:
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not call this constructor directly.
// Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
explicit JsonArray(JsonBuffer *buffer)
explicit JsonArray(JsonBuffer *buffer) throw()
: Internals::List<JsonVariant>(buffer) {}
// Gets the value at the specified index
const JsonArraySubscript operator[](size_t index) const;
const Internals::JsonArraySubscript operator[](size_t index) const;
// Gets or sets the value at specified index
JsonArraySubscript operator[](size_t index);
Internals::JsonArraySubscript operator[](size_t index);
// Adds the specified value at the end of the array.
//
// bool add(TValue);
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename T>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type add(
const T &value) {
bool add(const T &value) {
return add_impl<const T &>(value);
}
//
// bool add(TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename T>
bool add(const T *value) {
return add_impl<const T *>(value);
bool add(T *value) {
return add_impl<T *>(value);
}
//
// bool add(TValue value, uint8_t decimals);
@ -83,28 +81,25 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
// Sets the value at specified index.
//
// bool add(size_t index, TValue);
// bool add(size_t index, const TValue&);
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename T>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type set(
size_t index, const T &value) {
bool set(size_t index, const T &value) {
return set_impl<const T &>(index, value);
}
//
// bool add(size_t index, TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename T>
bool set(size_t index, const T *value) {
return set_impl<const T *>(index, value);
bool set(size_t index, T *value) {
return set_impl<T *>(index, value);
}
//
// bool set(size_t index, TValue value, uint8_t decimals);
// TValue = float, double
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
typename Internals::EnableIf<Internals::IsFloatingPoint<T>::value, bool>::type
set(size_t index, T value, uint8_t decimals) {
return set_impl<const JsonVariant &>(index, JsonVariant(value, decimals));
}
@ -210,14 +205,14 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
bool set_impl(size_t index, TValueRef value) {
iterator it = begin() += index;
if (it == end()) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
return Internals::ValueSaver<TValueRef>::save(_buffer, *it, value);
}
template <typename TValueRef>
bool add_impl(TValueRef value) {
iterator it = Internals::List<JsonVariant>::add();
if (it == end()) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
return Internals::ValueSaver<TValueRef>::save(_buffer, *it, value);
}
};
@ -228,5 +223,5 @@ struct JsonVariantDefault<JsonArray> {
return JsonArray::invalid();
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -26,4 +23,4 @@ inline JsonObject &JsonArray::createNestedObject() {
add(object);
return object;
}
}
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -16,6 +13,7 @@
#endif
namespace ArduinoJson {
namespace Internals {
class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
public:
FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index)
@ -28,10 +26,9 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
// Replaces the value
//
// operator=(TValue)
// operator=(const TValue&)
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename T>
FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
_array.set(_index, src);
@ -39,9 +36,9 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
}
//
// operator=(TValue)
// TValue = const char*, const char[N], const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename T>
FORCE_INLINE JsonArraySubscript& operator=(const T* src) {
FORCE_INLINE JsonArraySubscript& operator=(T* src) {
_array.set(_index, src);
return *this;
}
@ -51,7 +48,7 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
}
template <typename T>
FORCE_INLINE typename Internals::JsonVariantAs<T>::type as() const {
FORCE_INLINE typename JsonVariantAs<T>::type as() const {
return _array.get<T>(_index);
}
@ -62,19 +59,18 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
// Replaces the value
//
// bool set(TValue)
// bool set(const TValue&)
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue>
FORCE_INLINE bool set(const TValue& value) {
return _array.set(_index, value);
}
//
// bool set(TValue)
// TValue = const char*, const char[N], const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename TValue>
FORCE_INLINE bool set(const TValue* value) {
FORCE_INLINE bool set(TValue* value) {
return _array.set(_index, value);
}
//
@ -91,32 +87,34 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
const size_t _index;
};
template <typename TImpl>
inline JsonArraySubscript JsonVariantSubscripts<TImpl>::operator[](
size_t index) {
return impl()->template as<JsonArray>()[index];
}
template <typename TImpl>
inline const JsonArraySubscript JsonVariantSubscripts<TImpl>::operator[](
size_t index) const {
return impl()->template as<JsonArray>()[index];
}
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(std::ostream& os,
const JsonArraySubscript& source) {
return source.printTo(os);
}
#endif
} // namespace Internals
inline JsonArraySubscript JsonArray::operator[](size_t index) {
return JsonArraySubscript(*this, index);
inline Internals::JsonArraySubscript JsonArray::operator[](size_t index) {
return Internals::JsonArraySubscript(*this, index);
}
inline const JsonArraySubscript JsonArray::operator[](size_t index) const {
return JsonArraySubscript(*const_cast<JsonArray*>(this), index);
}
template <typename TImplem>
inline JsonArraySubscript JsonVariantBase<TImplem>::operator[](size_t index) {
return as<JsonArray>()[index];
}
template <typename TImplem>
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
inline const Internals::JsonArraySubscript JsonArray::operator[](
size_t index) const {
return as<JsonArray>()[index];
return Internals::JsonArraySubscript(*const_cast<JsonArray*>(this), index);
}
} // namespace ArduinoJson
#ifdef _MSC_VER

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -11,20 +8,11 @@
#include <stdint.h> // for uint8_t
#include <string.h>
#include "Data/NonCopyable.hpp"
#include "JsonVariant.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsArray.hpp"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
class JsonArray;
class JsonObject;
@ -34,13 +22,8 @@ class JsonObject;
// Handle the memory management (done in derived classes) and calls the parser.
// This abstract class is implemented by StaticJsonBuffer which implements a
// fixed memory allocation.
class JsonBuffer {
class JsonBuffer : Internals::NonCopyable {
public:
// CAUTION: NO VIRTUAL DESTRUCTOR!
// If we add a virtual constructor the Arduino compiler will add malloc() and
// free() to the binary, adding 706 useless bytes.
// virtual ~JsonBuffer() {}
// Allocates an empty JsonArray.
//
// Returns a reference to the new JsonArray or JsonArray::invalid() if the
@ -55,20 +38,21 @@ class JsonBuffer {
// Duplicates a string
//
// char* strdup(TValue);
// const char* strdup(TValue);
// TValue = const std::string&, const String&,
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
char *>::type
strdup(const TString &src) {
DEPRECATED("char* are duplicated, you don't need strdup() anymore")
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
const char *>::type strdup(const TString &src) {
return Internals::StringTraits<TString>::duplicate(src, this);
}
//
// char* strdup(TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
// const char* strdup(TValue);
// TValue = char*, const char*, const FlashStringHelper*
template <typename TString>
char *strdup(const TString *src) {
return Internals::StringTraits<const TString *>::duplicate(src, this);
DEPRECATED("char* are duplicated, you don't need strdup() anymore")
const char *strdup(TString *src) {
return Internals::StringTraits<TString *>::duplicate(src, this);
}
// Allocates n bytes in the JsonBuffer.
@ -76,6 +60,11 @@ class JsonBuffer {
virtual void *alloc(size_t size) = 0;
protected:
// CAUTION: NO VIRTUAL DESTRUCTOR!
// If we add a virtual constructor the Arduino compiler will add malloc()
// and free() to the binary, adding 706 useless bytes.
~JsonBuffer() {}
// Preserve aligment if necessary
static FORCE_INLINE size_t round_size_up(size_t bytes) {
#if ARDUINOJSON_ENABLE_ALIGNMENT
@ -86,12 +75,4 @@ class JsonBuffer {
#endif
}
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif
} // namespace ArduinoJson

View File

@ -1,25 +1,13 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "Deserialization/JsonParser.hpp"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
namespace Internals {
template <typename TDerived>
class JsonBufferBase : public JsonBuffer {
public:
@ -38,8 +26,8 @@ class JsonBufferBase : public JsonBuffer {
// JsonArray& parseArray(TString);
// TString = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonArray &>::type
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
JsonArray &>::type
parseArray(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseArray();
@ -75,8 +63,8 @@ class JsonBufferBase : public JsonBuffer {
// JsonObject& parseObject(TString);
// TString = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonObject &>::type
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
JsonObject &>::type
parseObject(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseObject();
@ -104,8 +92,8 @@ class JsonBufferBase : public JsonBuffer {
// JsonVariant parse(TString);
// TString = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonVariant>::type
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
JsonVariant>::type
parse(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
@ -127,17 +115,13 @@ class JsonBufferBase : public JsonBuffer {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
protected:
~JsonBufferBase() {}
private:
TDerived *that() {
return static_cast<TDerived *>(this);
}
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -1,16 +1,13 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "Data/JsonBufferAllocated.hpp"
#include "Data/List.hpp"
#include "Data/ReferenceType.hpp"
#include "Data/ValueSetter.hpp"
#include "Data/ValueSaver.hpp"
#include "JsonPair.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "StringTraits/StringTraits.hpp"
@ -29,6 +26,10 @@ namespace ArduinoJson {
// Forward declarations
class JsonArray;
class JsonBuffer;
namespace Internals {
template <typename>
class JsonObjectSubscript;
}
// A dictionary of JsonVariant indexed by string (char*)
//
@ -38,30 +39,31 @@ class JsonBuffer;
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
class JsonObject : public Internals::JsonPrintable<JsonObject>,
public Internals::ReferenceType,
public Internals::NonCopyable,
public Internals::List<JsonPair>,
public Internals::JsonBufferAllocated {
public:
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not use this constructor directly.
// Instead, use JsonBuffer::createObject() or JsonBuffer.parseObject().
explicit JsonObject(JsonBuffer* buffer) : Internals::List<JsonPair>(buffer) {}
explicit JsonObject(JsonBuffer* buffer) throw()
: Internals::List<JsonPair>(buffer) {}
// Gets or sets the value associated with the specified key.
//
// JsonObjectSubscript operator[](TKey)
// TKey = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonObjectSubscript<const TString&> >::type
operator[](const TString& key) {
return JsonObjectSubscript<const TString&>(*this, key);
Internals::JsonObjectSubscript<const TString&> operator[](
const TString& key) {
return Internals::JsonObjectSubscript<const TString&>(*this, key);
}
//
// JsonObjectSubscript operator[](TKey)
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, char[], const char[N], const FlashStringHelper*
template <typename TString>
JsonObjectSubscript<const TString*> operator[](const TString* key) {
return JsonObjectSubscript<const TString*>(*this, key);
Internals::JsonObjectSubscript<TString*> operator[](TString* key) {
return Internals::JsonObjectSubscript<TString*>(*this, key);
}
// Gets the value associated with the specified key.
@ -69,21 +71,19 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<
!TypeTraits::IsArray<TString>::value,
const JsonObjectSubscript<const TString&> >::type
operator[](const TString& key) const {
return JsonObjectSubscript<const TString&>(*const_cast<JsonObject*>(this),
key);
const Internals::JsonObjectSubscript<const TString&> operator[](
const TString& key) const {
return Internals::JsonObjectSubscript<const TString&>(
*const_cast<JsonObject*>(this), key);
}
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
const JsonObjectSubscript<const TString*> operator[](
const TString* key) const {
return JsonObjectSubscript<const TString*>(*const_cast<JsonObject*>(this),
key);
const Internals::JsonObjectSubscript<TString*> operator[](
TString* key) const {
return Internals::JsonObjectSubscript<TString*>(
*const_cast<JsonObject*>(this), key);
}
// Sets the specified key with the specified value.
@ -91,43 +91,35 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// bool set(TKey, TValue);
// TKey = const std::string&, const String&
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value &&
!TypeTraits::IsArray<TValue>::value,
bool>::type
set(const TString& key, const TValue& value) {
bool set(const TString& key, const TValue& value) {
return set_impl<const TString&, const TValue&>(key, value);
}
//
// bool set(TKey, TValue);
// TKey = const std::string&, const String&
// TValue = const char*, const char[N], const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
bool>::type
set(const TString& key, const TValue* value) {
return set_impl<const TString&, const TValue*>(key, value);
bool set(const TString& key, TValue* value) {
return set_impl<const TString&, TValue*>(key, value);
}
//
// bool set(TKey, TValue);
// TKey = const char*, const char[N], const FlashStringHelper*
// bool set(TKey, const TValue&);
// TKey = char*, const char*, const FlashStringHelper*
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value, bool>::type
set(const TString* key, const TValue& value) {
return set_impl<const TString*, const TValue&>(key, value);
bool set(TString* key, const TValue& value) {
return set_impl<TString*, const TValue&>(key, value);
}
//
// bool set(TKey, TValue);
// TKey = const char*, const char[N], const FlashStringHelper*
// TValue = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename TValue, typename TString>
bool set(const TString* key, const TValue* value) {
return set_impl<const TString*, const TValue*>(key, value);
bool set(TString* key, TValue* value) {
return set_impl<TString*, TValue*>(key, value);
}
//
// bool set(TKey, TValue, uint8_t decimals);
@ -135,50 +127,43 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// TValue = float, double
template <typename TValue, typename TString>
DEPRECATED("Second argument is not supported anymore")
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value &&
!TypeTraits::IsArray<TString>::value,
bool>::type
typename Internals::EnableIf<Internals::IsFloatingPoint<TValue>::value,
bool>::type
set(const TString& key, TValue value, uint8_t) {
return set_impl<const TString&, const JsonVariant&>(key,
JsonVariant(value));
}
//
// bool set(TKey, TValue, uint8_t decimals);
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, const FlashStringHelper*
// TValue = float, double
template <typename TValue, typename TString>
DEPRECATED("Second argument is not supported anymore")
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value,
bool>::type
set(const TString* key, TValue value, uint8_t) {
return set_impl<const TString*, const JsonVariant&>(key,
JsonVariant(value));
typename Internals::EnableIf<Internals::IsFloatingPoint<TValue>::value,
bool>::type
set(TString* key, TValue value, uint8_t) {
return set_impl<TString*, const JsonVariant&>(key, JsonVariant(value));
}
// Gets the value associated with the specified key.
//
// TValue get<TValue>(TKey);
// TValue get<TValue>(TKey) const;
// TKey = const std::string&, const String&
// TValue = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<
!TypeTraits::IsArray<TString>::value,
typename Internals::JsonVariantAs<TValue>::type>::type
get(const TString& key) const {
typename Internals::JsonVariantAs<TValue>::type get(
const TString& key) const {
return get_impl<const TString&, TValue>(key);
}
//
// TValue get<TValue>(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
// TValue get<TValue>(TKey) const;
// TKey = char*, const char*, const FlashStringHelper*
// TValue = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
typename Internals::JsonVariantAs<TValue>::type get(
const TString* key) const {
return get_impl<const TString*, TValue>(key);
typename Internals::JsonVariantAs<TValue>::type get(TString* key) const {
return get_impl<TString*, TValue>(key);
}
// Checks the type of the value associated with the specified key.
@ -187,23 +172,19 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// bool is<TValue>(TKey) const;
// TKey = const std::string&, const String&
// TValue = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
bool>::type
is(const TString& key) const {
bool is(const TString& key) const {
return is_impl<const TString&, TValue>(key);
}
//
// bool is<TValue>(TKey) const;
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, const FlashStringHelper*
// TValue = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue, typename TString>
bool is(const TString* key) const {
return is_impl<const TString*, TValue>(key);
bool is(TString* key) const {
return is_impl<TString*, TValue>(key);
}
// Creates and adds a JsonArray.
@ -211,16 +192,14 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// JsonArray& createNestedArray(TKey);
// TKey = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonArray&>::type
createNestedArray(const TString& key) {
JsonArray& createNestedArray(const TString& key) {
return createNestedArray_impl<const TString&>(key);
}
// JsonArray& createNestedArray(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
JsonArray& createNestedArray(const TString* key) {
return createNestedArray_impl<const TString*>(key);
JsonArray& createNestedArray(TString* key) {
return createNestedArray_impl<TString*>(key);
}
// Creates and adds a JsonObject.
@ -228,17 +207,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// JsonObject& createNestedObject(TKey);
// TKey = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonObject&>::type
createNestedObject(const TString& key) {
JsonObject& createNestedObject(const TString& key) {
return createNestedObject_impl<const TString&>(key);
}
//
// JsonObject& createNestedObject(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
JsonObject& createNestedObject(const TString* key) {
return createNestedObject_impl<const TString*>(key);
JsonObject& createNestedObject(TString* key) {
return createNestedObject_impl<TString*>(key);
}
// Tells weither the specified key is present and associated with a value.
@ -246,17 +223,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// bool containsKey(TKey);
// TKey = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
bool>::type
containsKey(const TString& key) const {
bool containsKey(const TString& key) const {
return findKey<const TString&>(key) != end();
}
//
// bool containsKey(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
bool containsKey(const TString* key) const {
return findKey<const TString*>(key) != end();
bool containsKey(TString* key) const {
return findKey<TString*>(key) != end();
}
// Removes the specified key and the associated value.
@ -264,17 +239,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// void remove(TKey);
// TKey = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
void>::type
remove(const TString& key) {
void remove(const TString& key) {
remove(findKey<const TString&>(key));
}
//
// void remove(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = char*, const char*, char[], const char[], const FlashStringHelper*
template <typename TString>
void remove(const TString* key) {
remove(findKey<const TString*>(key));
void remove(TString* key) {
remove(findKey<TString*>(key));
}
//
// void remove(iterator)
@ -313,16 +286,22 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
template <typename TStringRef, typename TValueRef>
bool set_impl(TStringRef key, TValueRef value) {
// ignore null key
if (Internals::StringTraits<TStringRef>::is_null(key)) return false;
// search a matching key
iterator it = findKey<TStringRef>(key);
if (it == end()) {
// add the key
it = Internals::List<JsonPair>::add();
if (it == end()) return false;
bool key_ok =
Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key);
Internals::ValueSaver<TStringRef>::save(_buffer, it->key, key);
if (!key_ok) return false;
}
return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value);
// save the value
return Internals::ValueSaver<TValueRef>::save(_buffer, it->value, value);
}
template <typename TStringRef, typename TValue>
@ -345,5 +324,5 @@ struct JsonVariantDefault<JsonObject> {
return JsonObject::invalid();
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -28,4 +25,4 @@ inline JsonObject &JsonObject::createNestedObject_impl(TStringRef key) {
set(key, object);
return object;
}
}
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -17,6 +14,7 @@
#endif
namespace ArduinoJson {
namespace Internals {
template <typename TStringRef>
class JsonObjectSubscript
@ -34,23 +32,20 @@ class JsonObjectSubscript
// Set the specified value
//
// operator=(TValue);
// operator=(const TValue&);
// TValue = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue>
FORCE_INLINE
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value,
this_type&>::type
operator=(const TValue& src) {
FORCE_INLINE typename EnableIf<!IsArray<TValue>::value, this_type&>::type
operator=(const TValue& src) {
_object.set(_key, src);
return *this;
}
//
// operator=(TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
// TValue = char*, const char*, const FlashStringHelper*
template <typename TValue>
FORCE_INLINE this_type& operator=(const TValue* src) {
FORCE_INLINE this_type& operator=(TValue* src) {
_object.set(_key, src);
return *this;
}
@ -60,7 +55,7 @@ class JsonObjectSubscript
}
template <typename TValue>
FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type as() const {
FORCE_INLINE typename JsonVariantAs<TValue>::type as() const {
return _object.get<TValue>(_key);
}
@ -71,20 +66,17 @@ class JsonObjectSubscript
// Sets the specified value.
//
// bool set(TValue);
// bool set(const TValue&);
// TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
// std::string, String, JsonArray, JsonObject
template <typename TValue>
FORCE_INLINE
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value,
bool>::type
set(const TValue& value) {
FORCE_INLINE typename EnableIf<!IsArray<TValue>::value, bool>::type set(
const TValue& value) {
return _object.set(_key, value);
}
//
// bool set(TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
// TValue = char*, const char, const FlashStringHelper*
template <typename TValue>
FORCE_INLINE bool set(const TValue* value) {
return _object.set(_key, value);
@ -110,6 +102,7 @@ inline std::ostream& operator<<(std::ostream& os,
return source.printTo(os);
}
#endif
} // namespace Internals
} // namespace ArduinoJson
#ifdef _MSC_VER

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -16,4 +13,4 @@ struct JsonPair {
const char* key;
JsonVariant value;
};
}
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -39,7 +36,7 @@ class JsonObject;
// - a char, short, int or a long (signed or unsigned)
// - a string (const char*)
// - a reference to a JsonArray or JsonObject
class JsonVariant : public JsonVariantBase<JsonVariant> {
class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
template <typename Print>
friend class Internals::JsonSerializer;
@ -59,8 +56,8 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// JsonVariant(double value);
// JsonVariant(float value);
template <typename T>
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
JsonVariant(T value, typename Internals::EnableIf<
Internals::IsFloatingPoint<T>::value>::type * = 0) {
using namespace Internals;
_type = JSON_FLOAT;
_content.asFloat = static_cast<JsonFloat>(value);
@ -68,8 +65,8 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
template <typename T>
DEPRECATED("Second argument is not supported anymore")
JsonVariant(T value, uint8_t,
typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
typename Internals::EnableIf<
Internals::IsFloatingPoint<T>::value>::type * = 0) {
using namespace Internals;
_type = JSON_FLOAT;
_content.asFloat = static_cast<JsonFloat>(value);
@ -82,9 +79,11 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// JsonVariant(signed long)
// JsonVariant(signed char)
template <typename T>
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsSignedIntegral<T>::value ||
TypeTraits::IsSame<T, char>::value>::type * = 0) {
JsonVariant(
T value,
typename Internals::EnableIf<Internals::IsSignedIntegral<T>::value ||
Internals::IsSame<T, char>::value>::type * =
0) {
using namespace Internals;
if (value >= 0) {
_type = JSON_POSITIVE_INTEGER;
@ -99,8 +98,8 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// JsonVariant(unsigned long)
template <typename T>
JsonVariant(T value,
typename TypeTraits::EnableIf<
TypeTraits::IsUnsignedIntegral<T>::value>::type * = 0) {
typename Internals::EnableIf<
Internals::IsUnsignedIntegral<T>::value>::type * = 0) {
using namespace Internals;
_type = JSON_POSITIVE_INTEGER;
_content.asInteger = static_cast<JsonUInt>(value);
@ -113,14 +112,14 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
template <typename TChar>
JsonVariant(
const TChar *value,
typename TypeTraits::EnableIf<TypeTraits::IsChar<TChar>::value>::type * =
typename Internals::EnableIf<Internals::IsChar<TChar>::value>::type * =
0) {
_type = Internals::JSON_STRING;
_content.asString = reinterpret_cast<const char *>(value);
}
// Create a JsonVariant containing an unparsed string
JsonVariant(RawJson value) {
JsonVariant(Internals::RawJsonString<const char *> value) {
_type = Internals::JSON_UNPARSED;
_content.asString = value;
}
@ -147,14 +146,13 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// unsigned int as<unsigned int>() const;
// unsigned long as<unsigned long>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, T>::type
const typename Internals::EnableIf<Internals::IsIntegral<T>::value, T>::type
as() const {
return variantAsInteger<T>();
}
// bool as<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
T>::type
const typename Internals::EnableIf<Internals::IsSame<T, bool>::value, T>::type
as() const {
return variantAsInteger<int>() != 0;
}
@ -162,8 +160,8 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// double as<double>() const;
// float as<float>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
T>::type
const typename Internals::EnableIf<Internals::IsFloatingPoint<T>::value,
T>::type
as() const {
return variantAsFloat<T>();
}
@ -171,9 +169,9 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// const char* as<const char*>() const;
// const char* as<char*>() const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
TypeTraits::IsSame<T, char *>::value,
const char *>::type
typename Internals::EnableIf<Internals::IsSame<T, const char *>::value ||
Internals::IsSame<T, char *>::value,
const char *>::type
as() const {
return variantAsString();
}
@ -181,7 +179,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// std::string as<std::string>() const;
// String as<String>() const;
template <typename T>
typename TypeTraits::EnableIf<Internals::StringTraits<T>::has_append, T>::type
typename Internals::EnableIf<Internals::StringTraits<T>::has_append, T>::type
as() const {
const char *cstr = variantAsString();
if (cstr) return T(cstr);
@ -193,9 +191,9 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// JsonArray& as<JsonArray> const;
// JsonArray& as<JsonArray&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
JsonArray>::value,
typename Internals::EnableIf<
Internals::IsSame<typename Internals::RemoveReference<T>::type,
JsonArray>::value,
JsonArray &>::type
as() const {
return variantAsArray();
@ -203,9 +201,9 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
//
// const JsonArray& as<const JsonArray&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
const JsonArray>::value,
typename Internals::EnableIf<
Internals::IsSame<typename Internals::RemoveReference<T>::type,
const JsonArray>::value,
const JsonArray &>::type
as() const {
return variantAsArray();
@ -214,9 +212,9 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// JsonObject& as<JsonObject> const;
// JsonObject& as<JsonObject&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
JsonObject>::value,
typename Internals::EnableIf<
Internals::IsSame<typename Internals::RemoveReference<T>::type,
JsonObject>::value,
JsonObject &>::type
as() const {
return variantAsObject();
@ -225,9 +223,9 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// JsonObject& as<const JsonObject> const;
// JsonObject& as<const JsonObject&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
const JsonObject>::value,
typename Internals::EnableIf<
Internals::IsSame<typename Internals::RemoveReference<T>::type,
const JsonObject>::value,
const JsonObject &>::type
as() const {
return variantAsObject();
@ -235,8 +233,8 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
//
// JsonVariant as<JsonVariant> const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, JsonVariant>::value,
T>::type
typename Internals::EnableIf<Internals::IsSame<T, JsonVariant>::value,
T>::type
as() const {
return *this;
}
@ -254,33 +252,34 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// bool is<unsigned int>() const;
// bool is<unsigned long>() const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, bool>::type
is() const {
typename Internals::EnableIf<Internals::IsIntegral<T>::value, bool>::type is()
const {
return variantIsInteger();
}
//
// bool is<double>() const;
// bool is<float>() const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
typename Internals::EnableIf<Internals::IsFloatingPoint<T>::value, bool>::type
is() const {
return variantIsFloat();
}
//
// bool is<bool>() const
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value, bool>::type
typename Internals::EnableIf<Internals::IsSame<T, bool>::value, bool>::type
is() const {
return variantIsBoolean();
}
//
// bool is<const char*>() const;
// bool is<char*>() const;
// bool is<std::string>() const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
TypeTraits::IsSame<T, char *>::value,
bool>::type
typename Internals::EnableIf<Internals::IsSame<T, const char *>::value ||
Internals::IsSame<T, char *>::value ||
Internals::StringTraits<T>::has_append,
bool>::type
is() const {
return variantIsString();
}
@ -289,11 +288,10 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// bool is<JsonArray&> const;
// bool is<const JsonArray&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<
typename TypeTraits::RemoveConst<
typename TypeTraits::RemoveReference<T>::type>::type,
JsonArray>::value,
typename Internals::EnableIf<
Internals::IsSame<typename Internals::RemoveConst<
typename Internals::RemoveReference<T>::type>::type,
JsonArray>::value,
bool>::type
is() const {
return variantIsArray();
@ -303,11 +301,10 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// bool is<JsonObject&> const;
// bool is<const JsonObject&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<
typename TypeTraits::RemoveConst<
typename TypeTraits::RemoveReference<T>::type>::type,
JsonObject>::value,
typename Internals::EnableIf<
Internals::IsSame<typename Internals::RemoveConst<
typename Internals::RemoveReference<T>::type>::type,
JsonObject>::value,
bool>::type
is() const {
return variantIsObject();
@ -357,4 +354,4 @@ DEPRECATED("Decimal places are ignored, use the double value instead")
inline JsonVariant double_with_n_digits(double value, uint8_t) {
return JsonVariant(value);
}
}
} // namespace ArduinoJson

View File

@ -1,139 +1,24 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "Data/JsonVariantAs.hpp"
#include "Polyfills/attributes.hpp"
#include "JsonVariantCasts.hpp"
#include "JsonVariantComparisons.hpp"
#include "JsonVariantOr.hpp"
#include "JsonVariantSubscripts.hpp"
#include "Serialization/JsonPrintable.hpp"
namespace ArduinoJson {
// Forward declarations.
class JsonArraySubscript;
template <typename TKey>
class JsonObjectSubscript;
namespace Internals {
template <typename TImpl>
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
public:
#if ARDUINOJSON_ENABLE_DEPRECATED
DEPRECATED("use as<JsonArray>() instead")
FORCE_INLINE JsonArray &asArray() const {
return as<JsonArray>();
}
DEPRECATED("use as<JsonObject>() instead")
FORCE_INLINE JsonObject &asObject() const {
return as<JsonObject>();
}
DEPRECATED("use as<char*>() instead")
FORCE_INLINE const char *asString() const {
return as<const char *>();
}
#endif
// Gets the variant as an array.
// Returns a reference to the JsonArray or JsonArray::invalid() if the
// variant
// is not an array.
FORCE_INLINE operator JsonArray &() const {
return as<JsonArray &>();
}
// Gets the variant as an object.
// Returns a reference to the JsonObject or JsonObject::invalid() if the
// variant is not an object.
FORCE_INLINE operator JsonObject &() const {
return as<JsonObject &>();
}
template <typename T>
FORCE_INLINE operator T() const {
return as<T>();
}
template <typename T>
FORCE_INLINE const typename Internals::JsonVariantAs<T>::type as() const {
return impl()->template as<T>();
}
template <typename T>
FORCE_INLINE bool is() const {
return impl()->template is<T>();
}
// Mimics an array or an object.
// Returns the size of the array or object if the variant has that type.
// Returns 0 if the variant is neither an array nor an object
size_t size() const {
return as<JsonArray>().size() + as<JsonObject>().size();
}
// Mimics an array.
// Returns the element at specified index if the variant is an array.
// Returns JsonVariant::invalid() if the variant is not an array.
FORCE_INLINE const JsonArraySubscript operator[](size_t index) const;
FORCE_INLINE JsonArraySubscript operator[](size_t index);
// Mimics an object.
// Returns the value associated with the specified key if the variant is
// an object.
// Return JsonVariant::invalid() if the variant is not an object.
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<TString>::has_equals,
const JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) const {
return as<JsonObject>()[key];
}
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<TString>::has_equals,
JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) {
return as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<const TString *>::has_equals,
JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) {
return as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<TString *>::has_equals,
const JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) const {
return as<JsonObject>()[key];
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
};
namespace TypeTraits {
template <typename T>
struct IsVariant : IsBaseOf<JsonVariantBase<T>, T> {};
}
}
class JsonVariantBase : public JsonPrintable<TImpl>,
public JsonVariantCasts<TImpl>,
public JsonVariantComparisons<TImpl>,
public JsonVariantOr<TImpl>,
public JsonVariantSubscripts<TImpl>,
public JsonVariantTag {};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -0,0 +1,59 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "Data/JsonVariantAs.hpp"
#include "Polyfills/attributes.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TImpl>
class JsonVariantCasts {
public:
#if ARDUINOJSON_ENABLE_DEPRECATED
DEPRECATED("use as<JsonArray>() instead")
FORCE_INLINE JsonArray &asArray() const {
return impl()->template as<JsonArray>();
}
DEPRECATED("use as<JsonObject>() instead")
FORCE_INLINE JsonObject &asObject() const {
return impl()->template as<JsonObject>();
}
DEPRECATED("use as<char*>() instead")
FORCE_INLINE const char *asString() const {
return impl()->template as<const char *>();
}
#endif
// Gets the variant as an array.
// Returns a reference to the JsonArray or JsonArray::invalid() if the
// variant
// is not an array.
FORCE_INLINE operator JsonArray &() const {
return impl()->template as<JsonArray &>();
}
// Gets the variant as an object.
// Returns a reference to the JsonObject or JsonObject::invalid() if the
// variant is not an object.
FORCE_INLINE operator JsonObject &() const {
return impl()->template as<JsonObject &>();
}
template <typename T>
FORCE_INLINE operator T() const {
return impl()->template as<T>();
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,88 +1,139 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "Data/JsonVariantComparer.hpp"
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsVariant.hpp"
namespace ArduinoJson {
template <typename TVariant, typename TComparand>
inline bool operator==(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return Internals::JsonVariantComparer<TComparand>::equals(variant, comparand);
}
namespace Internals {
template <typename TVariant, typename TComparand>
inline typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator==(TComparand comparand, const JsonVariantBase<TVariant> &variant) {
return Internals::JsonVariantComparer<TComparand>::equals(variant, comparand);
}
template <typename TImpl>
class JsonVariantComparisons {
public:
template <typename TComparand>
friend bool operator==(const JsonVariantComparisons &variant,
TComparand comparand) {
return variant.equals(comparand);
}
template <typename TVariant, typename TComparand>
inline bool operator!=(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return !Internals::JsonVariantComparer<TComparand>::equals(variant,
comparand);
}
template <typename TComparand>
friend typename EnableIf<!IsVariant<TComparand>::value, bool>::type
operator==(TComparand comparand, const JsonVariantComparisons &variant) {
return variant.equals(comparand);
}
template <typename TVariant, typename TComparand>
inline typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator!=(TComparand comparand, const JsonVariantBase<TVariant> &variant) {
return !Internals::JsonVariantComparer<TComparand>::equals(variant,
comparand);
}
template <typename TComparand>
friend bool operator!=(const JsonVariantComparisons &variant,
TComparand comparand) {
return !variant.equals(comparand);
}
template <typename TVariant, typename TComparand>
inline bool operator<=(const JsonVariantBase<TVariant> &left,
TComparand right) {
return left.template as<TComparand>() <= right;
}
template <typename TComparand>
friend typename EnableIf<!IsVariant<TComparand>::value, bool>::type
operator!=(TComparand comparand, const JsonVariantComparisons &variant) {
return !variant.equals(comparand);
}
template <typename TVariant, typename TComparand>
inline bool operator<=(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand <= variant.template as<TComparand>();
}
template <typename TComparand>
friend bool operator<=(const JsonVariantComparisons &left, TComparand right) {
return left.as<TComparand>() <= right;
}
template <typename TVariant, typename TComparand>
inline bool operator>=(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return variant.template as<TComparand>() >= comparand;
}
template <typename TComparand>
friend bool operator<=(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand <= variant.as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator>=(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand >= variant.template as<TComparand>();
}
template <typename TComparand>
friend bool operator>=(const JsonVariantComparisons &variant,
TComparand comparand) {
return variant.as<TComparand>() >= comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator<(const JsonVariantBase<TVariant> &varian,
TComparand comparand) {
return varian.template as<TComparand>() < comparand;
}
template <typename TComparand>
friend bool operator>=(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand >= variant.as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator<(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand < variant.template as<TComparand>();
}
template <typename TComparand>
friend bool operator<(const JsonVariantComparisons &varian,
TComparand comparand) {
return varian.as<TComparand>() < comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator>(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return variant.template as<TComparand>() > comparand;
}
template <typename TComparand>
friend bool operator<(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand < variant.as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator>(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand > variant.template as<TComparand>();
}
}
template <typename TComparand>
friend bool operator>(const JsonVariantComparisons &variant,
TComparand comparand) {
return variant.as<TComparand>() > comparand;
}
template <typename TComparand>
friend bool operator>(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand > variant.as<TComparand>();
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
template <typename T>
const typename JsonVariantAs<T>::type as() const {
return impl()->template as<T>();
}
template <typename T>
bool is() const {
return impl()->template is<T>();
}
template <typename TString>
typename EnableIf<StringTraits<TString>::has_equals, bool>::type equals(
const TString &comparand) const {
const char *value = as<const char *>();
return StringTraits<TString>::equals(comparand, value);
}
template <typename TComparand>
typename EnableIf<!IsVariant<TComparand>::value &&
!StringTraits<TComparand>::has_equals,
bool>::type
equals(const TComparand &comparand) const {
return as<TComparand>() == comparand;
}
template <typename TVariant2>
bool equals(const JsonVariantComparisons<TVariant2> &right) const {
using namespace Internals;
if (is<bool>() && right.template is<bool>())
return as<bool>() == right.template as<bool>();
if (is<JsonInteger>() && right.template is<JsonInteger>())
return as<JsonInteger>() == right.template as<JsonInteger>();
if (is<JsonFloat>() && right.template is<JsonFloat>())
return as<JsonFloat>() == right.template as<JsonFloat>();
if (is<JsonArray>() && right.template is<JsonArray>())
return as<JsonArray>() == right.template as<JsonArray>();
if (is<JsonObject>() && right.template is<JsonObject>())
return as<JsonObject>() == right.template as<JsonObject>();
if (is<char *>() && right.template is<char *>())
return StringTraits<const char *>::equals(as<char *>(),
right.template as<char *>());
return false;
}
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -26,6 +23,7 @@ inline JsonVariant::JsonVariant(const JsonArray &array) {
_content.asArray = const_cast<JsonArray *>(&array);
} else {
_type = Internals::JSON_UNDEFINED;
_content.asArray = 0; // <- prevent warning 'maybe-uninitialized'
}
}
@ -35,6 +33,7 @@ inline JsonVariant::JsonVariant(const JsonObject &object) {
_content.asObject = const_cast<JsonObject *>(&object);
} else {
_type = Internals::JSON_UNDEFINED;
_content.asObject = 0; // <- prevent warning 'maybe-uninitialized'
}
}
@ -61,7 +60,7 @@ inline T JsonVariant::variantAsInteger() const {
return T(~_content.asInteger + 1);
case JSON_STRING:
case JSON_UNPARSED:
return Polyfills::parseInteger<T>(_content.asString);
return parseInteger<T>(_content.asString);
default:
return T(_content.asFloat);
}
@ -89,7 +88,7 @@ inline T JsonVariant::variantAsFloat() const {
return -static_cast<T>(_content.asInteger);
case JSON_STRING:
case JSON_UNPARSED:
return Polyfills::parseFloat<T>(_content.asString);
return parseFloat<T>(_content.asString);
default:
return static_cast<T>(_content.asFloat);
}
@ -109,7 +108,7 @@ inline bool JsonVariant::variantIsInteger() const {
using namespace Internals;
return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER ||
(_type == JSON_UNPARSED && Polyfills::isInteger(_content.asString));
(_type == JSON_UNPARSED && isInteger(_content.asString));
}
inline bool JsonVariant::variantIsFloat() const {
@ -117,7 +116,7 @@ inline bool JsonVariant::variantIsFloat() const {
return _type == JSON_FLOAT || _type == JSON_POSITIVE_INTEGER ||
_type == JSON_NEGATIVE_INTEGER ||
(_type == JSON_UNPARSED && Polyfills::isFloat(_content.asString));
(_type == JSON_UNPARSED && isFloat(_content.asString));
}
#if ARDUINOJSON_ENABLE_STD_STREAM

View File

@ -0,0 +1,52 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "Data/JsonVariantAs.hpp"
#include "Polyfills/attributes.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsIntegral.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TImpl>
class JsonVariantOr {
public:
// Returns the default value if the JsonVariant is undefined of incompatible
template <typename T>
typename EnableIf<!IsIntegral<T>::value, T>::type operator|(
const T &defaultValue) const {
if (impl()->template is<T>())
return impl()->template as<T>();
else
return defaultValue;
}
// Returns the default value if the JsonVariant is undefined of incompatible
// Special case for string: null is treated as undefined
const char *operator|(const char *defaultValue) const {
const char *value = impl()->template as<const char *>();
return value ? value : defaultValue;
}
// Returns the default value if the JsonVariant is undefined of incompatible
// Special case for integers: we also accept double
template <typename Integer>
typename EnableIf<IsIntegral<Integer>::value, Integer>::type operator|(
const Integer &defaultValue) const {
if (impl()->template is<double>())
return impl()->template as<Integer>();
else
return defaultValue;
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -0,0 +1,86 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "Data/JsonVariantAs.hpp"
#include "Polyfills/attributes.hpp"
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
namespace Internals {
// Forward declarations.
class JsonArraySubscript;
template <typename TKey>
class JsonObjectSubscript;
template <typename TImpl>
class JsonVariantSubscripts {
public:
// Mimics an array or an object.
// Returns the size of the array or object if the variant has that type.
// Returns 0 if the variant is neither an array nor an object
size_t size() const {
return impl()->template as<JsonArray>().size() +
impl()->template as<JsonObject>().size();
}
// Mimics an array.
// Returns the element at specified index if the variant is an array.
// Returns JsonVariant::invalid() if the variant is not an array.
FORCE_INLINE const JsonArraySubscript operator[](size_t index) const;
FORCE_INLINE JsonArraySubscript operator[](size_t index);
// Mimics an object.
// Returns the value associated with the specified key if the variant is
// an object.
// Return JsonVariant::invalid() if the variant is not an object.
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
FORCE_INLINE
typename EnableIf<StringTraits<TString>::has_equals,
const JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) const {
return impl()->template as<JsonObject>()[key];
}
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
FORCE_INLINE typename EnableIf<StringTraits<TString>::has_equals,
JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) {
return impl()->template as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
FORCE_INLINE typename EnableIf<StringTraits<const TString *>::has_equals,
JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) {
return impl()->template as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
FORCE_INLINE
typename EnableIf<StringTraits<TString *>::has_equals,
const JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) const {
return impl()->template as<JsonObject>()[key];
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -0,0 +1,31 @@
// 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 Internals {
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 Internals
} // namespace ArduinoJson

View File

@ -1,15 +1,12 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#ifdef _MSC_VER // Visual Studio
#define FORCE_INLINE __forceinline
#define FORCE_INLINE // __forceinline causes C4714 when returning std::string
#define NO_INLINE __declspec(noinline)
#define DEPRECATED(msg) __declspec(deprecated(msg))

View File

@ -1,14 +1,11 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Polyfills {
namespace Internals {
inline bool isdigit(char c) {
return '0' <= c && c <= '9';
@ -17,5 +14,5 @@ inline bool isdigit(char c) {
inline bool issign(char c) {
return '-' == c || c == '+';
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -11,7 +8,7 @@
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
namespace Internals {
inline bool isFloat(const char* s) {
if (!s) return false;
@ -37,5 +34,5 @@ inline bool isFloat(const char* s) {
return *s == '\0';
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,22 +1,19 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
namespace Internals {
inline bool isInteger(const char* s) {
if (!s) return false;
if (!s || !*s) return false;
if (issign(*s)) s++;
while (isdigit(*s)) s++;
return *s == '\0';
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,14 +1,11 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Polyfills {
namespace Internals {
template <typename T>
bool isNaN(T x) {
return x != x;
@ -18,5 +15,5 @@ template <typename T>
bool isInfinity(T x) {
return x != 0.0 && x * 2 == x;
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,103 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
int16_t normalize(T& value) {
int16_t powersOf10 = 0;
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
#if ARDUINOJSON_DOUBLE_IS_64BITS
if (value >= 1e256) {
value /= 1e256;
powersOf10 = int16_t(powersOf10 + 256);
}
if (value >= 1e128) {
value /= 1e128;
powersOf10 = int16_t(powersOf10 + 128);
}
if (value >= 1e64) {
value /= 1e64;
powersOf10 = int16_t(powersOf10 + 64);
}
#endif
if (value >= 1e32) {
value /= 1e32;
powersOf10 = int16_t(powersOf10 + 32);
}
if (value >= 1e16) {
value /= 1e16;
powersOf10 = int16_t(powersOf10 + 16);
}
if (value >= 1e8) {
value /= 1e8;
powersOf10 = int16_t(powersOf10 + 8);
}
if (value >= 1e4) {
value /= 1e4;
powersOf10 = int16_t(powersOf10 + 4);
}
if (value >= 1e2) {
value /= 1e2;
powersOf10 = int16_t(powersOf10 + 2);
}
if (value >= 1e1) {
value /= 1e1;
powersOf10 = int16_t(powersOf10 + 1);
}
}
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
#if ARDUINOJSON_DOUBLE_IS_64BITS
if (value < 1e-255) {
value *= 1e256;
powersOf10 = int16_t(powersOf10 - 256);
}
if (value < 1e-127) {
value *= 1e128;
powersOf10 = int16_t(powersOf10 - 128);
}
if (value < 1e-63) {
value *= 1e64;
powersOf10 = int16_t(powersOf10 - 64);
}
#endif
if (value < 1e-31) {
value *= 1e32;
powersOf10 = int16_t(powersOf10 - 32);
}
if (value < 1e-15) {
value *= 1e16;
powersOf10 = int16_t(powersOf10 - 16);
}
if (value < 1e-7) {
value *= 1e8;
powersOf10 = int16_t(powersOf10 - 8);
}
if (value < 1e-3) {
value *= 1e4;
powersOf10 = int16_t(powersOf10 - 4);
}
if (value < 1e-1) {
value *= 1e2;
powersOf10 = int16_t(powersOf10 - 2);
}
if (value < 1e0) {
value *= 1e1;
powersOf10 = int16_t(powersOf10 - 1);
}
}
return powersOf10;
}
}
}

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -12,11 +9,11 @@
#include "./math.hpp"
namespace ArduinoJson {
namespace Polyfills {
namespace Internals {
template <typename T>
inline T parseFloat(const char* s) {
typedef TypeTraits::FloatTraits<T> traits;
typedef FloatTraits<T> traits;
typedef typename traits::mantissa_type mantissa_t;
typedef typename traits::exponent_type exponent_t;
@ -26,8 +23,11 @@ inline T parseFloat(const char* s) {
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;
}
if (*s == 't') return 1; // true
@ -86,5 +86,5 @@ inline T parseFloat(const char* s) {
return negative_result ? -result : result;
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -13,7 +10,7 @@
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
namespace Internals {
template <typename T>
T parseInteger(const char *s) {
if (!s) return 0; // NULL
@ -26,6 +23,8 @@ T parseInteger(const char *s) {
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;
@ -38,5 +37,5 @@ T parseInteger(const char *s) {
return negative_result ? T(~result + 1) : result;
}
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,23 +1,46 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
// A special type of data that can be used to insert pregenerated JSON portions.
class RawJson {
template <typename T>
class RawJsonString {
public:
explicit RawJson(const char* str) : _str(str) {}
operator const char*() const {
explicit RawJsonString(T str) : _str(str) {}
operator T() const {
return _str;
}
private:
const char* _str;
T _str;
};
template <typename String>
struct StringTraits<RawJsonString<String>, void> {
static bool is_null(RawJsonString<String> source) {
return StringTraits<String>::is_null(static_cast<String>(source));
}
typedef RawJsonString<const char*> duplicate_t;
template <typename Buffer>
static duplicate_t duplicate(RawJsonString<String> source, Buffer* buffer) {
return duplicate_t(StringTraits<String>::duplicate(source, buffer));
}
static const bool has_append = false;
static const bool has_equals = false;
static const bool should_duplicate = StringTraits<String>::should_duplicate;
};
} // namespace Internals
template <typename T>
inline Internals::RawJsonString<T> RawJson(T str) {
return Internals::RawJsonString<T>(str);
}
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -21,5 +18,5 @@ class DummyPrint {
return strlen(s);
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -34,5 +31,5 @@ class DynamicStringBuilder {
TString &_str;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -0,0 +1,89 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../Configuration.hpp"
#include "../Polyfills/math.hpp"
#include "../TypeTraits/FloatTraits.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TFloat>
struct FloatParts {
uint32_t integral;
uint32_t decimal;
int16_t exponent;
int8_t decimalPlaces;
FloatParts(TFloat value) {
uint32_t maxDecimalPart = sizeof(TFloat) >= 8 ? 1000000000 : 1000000;
decimalPlaces = sizeof(TFloat) >= 8 ? 9 : 6;
exponent = normalize(value);
integral = uint32_t(value);
// reduce number of decimal places by the number of integral places
for (uint32_t tmp = integral; tmp >= 10; tmp /= 10) {
maxDecimalPart /= 10;
decimalPlaces--;
}
TFloat remainder = (value - TFloat(integral)) * TFloat(maxDecimalPart);
decimal = uint32_t(remainder);
remainder = remainder - TFloat(decimal);
// rounding:
// increment by 1 if remainder >= 0.5
decimal += uint32_t(remainder * 2);
if (decimal >= maxDecimalPart) {
decimal = 0;
integral++;
if (exponent && integral >= 10) {
exponent++;
integral = 1;
}
}
// remove trailing zeros
while (decimal % 10 == 0 && decimalPlaces > 0) {
decimal /= 10;
decimalPlaces--;
}
}
static int16_t normalize(TFloat& value) {
typedef FloatTraits<TFloat> traits;
int16_t powersOf10 = 0;
int8_t index = sizeof(TFloat) == 8 ? 8 : 5;
int bit = 1 << index;
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
for (; index >= 0; index--) {
if (value >= traits::positiveBinaryPowerOfTen(index)) {
value *= traits::negativeBinaryPowerOfTen(index);
powersOf10 = int16_t(powersOf10 + bit);
}
bit >>= 1;
}
}
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
for (; index >= 0; index--) {
if (value < traits::negativeBinaryPowerOfTenPlusOne(index)) {
value *= traits::positiveBinaryPowerOfTen(index);
powersOf10 = int16_t(powersOf10 - bit);
}
bit >>= 1;
}
}
return powersOf10;
}
};
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -67,5 +64,5 @@ class IndentedPrint {
static const int MAX_LEVEL = 15; // because it's only 4 bits
static const int MAX_TAB_SIZE = 7; // because it's only 3 bits
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -32,9 +29,8 @@ template <typename T>
class JsonPrintable {
public:
template <typename Print>
typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value,
size_t>::type
printTo(Print &print) const {
typename EnableIf<!StringTraits<Print>::has_append, size_t>::type printTo(
Print &print) const {
JsonWriter<Print> writer(print);
JsonSerializer<JsonWriter<Print> >::serialize(downcast(), writer);
return writer.bytesWritten();
@ -59,8 +55,8 @@ class JsonPrintable {
}
template <typename TString>
typename TypeTraits::EnableIf<StringTraits<TString>::has_append, size_t>::type
printTo(TString &str) const {
typename EnableIf<StringTraits<TString>::has_append, size_t>::type printTo(
TString &str) const {
DynamicStringBuilder<TString> sb(str);
return printTo(sb);
}
@ -82,15 +78,14 @@ class JsonPrintable {
}
template <typename Print>
typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value,
size_t>::type
typename EnableIf<!StringTraits<Print>::has_append, size_t>::type
prettyPrintTo(Print &print) const {
IndentedPrint<Print> indentedPrint(print);
return prettyPrintTo(indentedPrint);
}
template <typename TString>
typename TypeTraits::EnableIf<StringTraits<TString>::has_append, size_t>::type
typename EnableIf<StringTraits<TString>::has_append, size_t>::type
prettyPrintTo(TString &str) const {
DynamicStringBuilder<TString> sb(str);
return prettyPrintTo(sb);
@ -118,5 +113,5 @@ inline std::ostream &operator<<(std::ostream &os, const JsonPrintable<T> &v) {
return v.printTo(os);
}
#endif
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -12,14 +9,15 @@
namespace ArduinoJson {
class JsonArray;
class JsonArraySubscript;
class JsonObject;
template <typename TKey>
class JsonObjectSubscript;
class JsonVariant;
namespace Internals {
class JsonArraySubscript;
template <typename TKey>
class JsonObjectSubscript;
template <typename Writer>
class JsonSerializer {
public:
@ -30,5 +28,5 @@ class JsonSerializer {
static void serialize(const JsonObjectSubscript<TKey> &, Writer &);
static void serialize(const JsonVariant &, Writer &);
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -90,7 +87,8 @@ inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
return;
case JSON_NEGATIVE_INTEGER:
writer.writeRaw('-');
writer.writeRaw('-'); // Falls through.
case JSON_POSITIVE_INTEGER:
writer.writeInteger(variant._content.asInteger);
return;

View File

@ -1,20 +1,14 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include <stdint.h>
#include "../Data/Encoding.hpp"
#include "../Data/JsonFloat.hpp"
#include "../Data/JsonInteger.hpp"
#include "../Polyfills/attributes.hpp"
#include "../Polyfills/math.hpp"
#include "../Polyfills/normalize.hpp"
#include "../TypeTraits/FloatTraits.hpp"
#include "../Serialization/FloatParts.hpp"
namespace ArduinoJson {
namespace Internals {
@ -28,10 +22,6 @@ namespace Internals {
// indentation.
template <typename Print>
class JsonWriter {
static const uint8_t maxDecimalPlaces = sizeof(JsonFloat) >= 8 ? 9 : 6;
static const uint32_t maxDecimalPart =
sizeof(JsonFloat) >= 8 ? 1000000000 : 1000000;
public:
explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
@ -87,38 +77,38 @@ class JsonWriter {
}
}
void writeFloat(JsonFloat value) {
if (Polyfills::isNaN(value)) return writeRaw("NaN");
template <typename TFloat>
void writeFloat(TFloat value) {
if (isNaN(value)) return writeRaw("NaN");
if (value < 0.0) {
writeRaw('-');
value = -value;
}
if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
if (isInfinity(value)) return writeRaw("Infinity");
uint32_t integralPart, decimalPart;
int16_t powersOf10;
splitFloat(value, integralPart, decimalPart, powersOf10);
FloatParts<TFloat> parts(value);
writeInteger(integralPart);
if (decimalPart) writeDecimals(decimalPart, maxDecimalPlaces);
writeInteger(parts.integral);
if (parts.decimalPlaces) writeDecimals(parts.decimal, parts.decimalPlaces);
if (powersOf10 < 0) {
if (parts.exponent < 0) {
writeRaw("e-");
writeInteger(-powersOf10);
writeInteger(-parts.exponent);
}
if (powersOf10 > 0) {
if (parts.exponent > 0) {
writeRaw('e');
writeInteger(powersOf10);
writeInteger(parts.exponent);
}
}
template <typename UInt>
void writeInteger(UInt value) {
char buffer[22];
char *ptr = buffer + sizeof(buffer) - 1;
char *end = buffer + sizeof(buffer) - 1;
char *ptr = end;
*ptr = 0;
do {
@ -130,15 +120,9 @@ class JsonWriter {
}
void writeDecimals(uint32_t value, int8_t width) {
// remove trailing zeros
while (value % 10 == 0 && width > 0) {
value /= 10;
width--;
}
// buffer should be big enough for all digits, the dot and the null
// terminator
char buffer[maxDecimalPlaces + 2];
char buffer[16];
char *ptr = buffer + sizeof(buffer) - 1;
// write the string in reverse order
@ -166,30 +150,6 @@ class JsonWriter {
private:
JsonWriter &operator=(const JsonWriter &); // cannot be assigned
void splitFloat(JsonFloat value, uint32_t &integralPart,
uint32_t &decimalPart, int16_t &powersOf10) {
powersOf10 = Polyfills::normalize(value);
integralPart = uint32_t(value);
JsonFloat remainder = value - JsonFloat(integralPart);
remainder *= maxDecimalPart;
decimalPart = uint32_t(remainder);
remainder = remainder - JsonFloat(decimalPart);
// rounding:
// increment by 1 if remainder >= 0.5
decimalPart += uint32_t(remainder * 2);
if (decimalPart >= maxDecimalPart) {
decimalPart = 0;
integralPart++;
if (powersOf10 && integralPart >= 10) {
powersOf10++;
integralPart = 1;
}
}
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -132,5 +129,5 @@ class Prettyfier {
IndentedPrint<Print>& _sink;
bool _inString;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -35,5 +32,5 @@ class StaticStringBuilder {
char *end;
char *p;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -36,7 +33,7 @@ class StreamPrintAdapter {
std::ostream& _os;
};
}
}
} // namespace Internals
} // namespace ArduinoJson
#endif // ARDUINOJSON_ENABLE_STD_STREAM

View File

@ -1,25 +1,13 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "JsonBufferBase.hpp"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
namespace Internals {
class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> {
public:
@ -54,23 +42,36 @@ class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> {
StaticJsonBufferBase(char* buffer, size_t capa)
: _buffer(buffer), _capacity(capa), _size(0) {}
// Gets the capacity of the buffer in bytes
size_t capacity() const {
return _capacity;
}
// Gets the current usage of the buffer in bytes
size_t size() const {
return _size;
}
// Allocates the specified amount of bytes in the buffer
virtual void* alloc(size_t bytes) {
alignNextAlloc();
if (!canAlloc(bytes)) return NULL;
return doAlloc(bytes);
}
// Resets the buffer.
// USE WITH CAUTION: this invalidates all previously allocated data
void clear() {
_size = 0;
}
String startString() {
return String(this);
}
protected:
~StaticJsonBufferBase() {}
private:
void alignNextAlloc() {
_size = round_size_up(_size);
@ -90,19 +91,31 @@ class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> {
size_t _capacity;
size_t _size;
};
} // namespace Internals
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
// Implements a JsonBuffer with fixed memory allocation.
// The template paramenter CAPACITY specifies the capacity of the buffer in
// bytes.
template <size_t CAPACITY>
class StaticJsonBuffer : public StaticJsonBufferBase {
class StaticJsonBuffer : public Internals::StaticJsonBufferBase {
public:
explicit StaticJsonBuffer() : StaticJsonBufferBase(_buffer, CAPACITY) {}
explicit StaticJsonBuffer()
: Internals::StaticJsonBufferBase(_buffer, CAPACITY) {}
private:
char _buffer[CAPACITY];
};
}
} // namespace ArduinoJson
#if defined(__clang__)
#pragma clang diagnostic pop

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -46,16 +43,19 @@ struct ArduinoStreamTraits {
return c;
}
};
static const bool has_append = false;
static const bool has_equals = false;
};
template <typename TStream>
struct StringTraits<TStream,
// match any type that is derived from Stream:
typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<
Stream, typename TypeTraits::RemoveReference<
TStream>::type>::value>::type>
struct StringTraits<
TStream,
// match any type that is derived from Stream:
typename EnableIf<
IsBaseOf<Stream, typename RemoveReference<TStream>::type>::value>::type>
: ArduinoStreamTraits {};
}
}
} // namespace Internals
} // namespace ArduinoJson
#endif

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -33,26 +30,35 @@ struct CharPointerTraits {
};
static bool equals(const TChar* str, const char* expected) {
return strcmp(reinterpret_cast<const char*>(str), expected) == 0;
const char* actual = reinterpret_cast<const char*>(str);
if (!actual || !expected) return actual == expected;
return strcmp(actual, expected) == 0;
}
static bool is_null(const TChar* str) {
return !str;
}
typedef const char* duplicate_t;
template <typename Buffer>
static char* duplicate(const TChar* str, Buffer* buffer) {
static duplicate_t duplicate(const TChar* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen(reinterpret_cast<const char*>(str)) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy(dup, str, size);
return static_cast<char*>(dup);
return static_cast<duplicate_t>(dup);
}
static const bool has_append = false;
static const bool has_equals = true;
static const bool should_duplicate = false;
static const bool should_duplicate = !IsConst<TChar>::value;
};
// char*, unsigned char*, signed char*
// const char*, const unsigned char*, const signed char*
template <typename TChar>
struct StringTraits<TChar*, typename TypeTraits::EnableIf<
TypeTraits::IsChar<TChar>::value>::type>
struct StringTraits<TChar*, typename EnableIf<IsChar<TChar>::value>::type>
: CharPointerTraits<TChar> {};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -34,23 +31,31 @@ struct StringTraits<const __FlashStringHelper*, void> {
};
static bool equals(const __FlashStringHelper* str, const char* expected) {
return strcmp_P(expected, (PGM_P)str) == 0;
const char* actual = reinterpret_cast<const char*>(str);
if (!actual || !expected) return actual == expected;
return strcmp_P(expected, actual) == 0;
}
static bool is_null(const __FlashStringHelper* str) {
return !str;
}
typedef const char* duplicate_t;
template <typename Buffer>
static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) {
static duplicate_t duplicate(const __FlashStringHelper* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen_P((PGM_P)str) + 1;
size_t size = strlen_P((const char*)str) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy_P(dup, (PGM_P)str, size);
return static_cast<char*>(dup);
if (dup != NULL) memcpy_P(dup, (const char*)str, size);
return static_cast<duplicate_t>(dup);
}
static const bool has_append = false;
static const bool has_equals = true;
static const bool should_duplicate = true;
};
}
}
} // namespace Internals
} // namespace ArduinoJson
#endif

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -45,16 +42,19 @@ struct StdStreamTraits {
return _stream.eof() ? '\0' : static_cast<char>(_stream.get());
}
};
static const bool has_append = false;
static const bool has_equals = false;
};
template <typename TStream>
struct StringTraits<TStream,
// match any type that is derived from std::istream:
typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<
std::istream, typename TypeTraits::RemoveReference<
TStream>::type>::value>::type>
struct StringTraits<
TStream,
// match any type that is derived from std::istream:
typename EnableIf<IsBaseOf<
std::istream, typename RemoveReference<TStream>::type>::value>::type>
: StdStreamTraits {};
}
}
} // namespace Internals
} // namespace ArduinoJson
#endif

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -22,13 +19,20 @@ namespace Internals {
template <typename TString>
struct StdStringTraits {
typedef const char* duplicate_t;
template <typename Buffer>
static char* duplicate(const TString& str, Buffer* buffer) {
static duplicate_t duplicate(const TString& str, Buffer* buffer) {
if (!str.c_str()) return NULL; // <- Arduino string can return NULL
size_t size = str.length() + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy(dup, str.c_str(), size);
return static_cast<char*>(dup);
return static_cast<duplicate_t>(dup);
}
static bool is_null(const TString& str) {
// Arduino's String::c_str() can return NULL
return !str.c_str();
}
struct Reader : CharPointerTraits<char>::Reader {
@ -36,7 +40,10 @@ struct StdStringTraits {
};
static bool equals(const TString& str, const char* expected) {
return 0 == strcmp(str.c_str(), expected);
// Arduino's String::c_str() can return NULL
const char* actual = str.c_str();
if (!actual || !expected) return actual == expected;
return 0 == strcmp(actual, expected);
}
static void append(TString& str, char c) {
@ -64,7 +71,7 @@ struct StringTraits<StringSumHelper, void> : StdStringTraits<StringSumHelper> {
template <>
struct StringTraits<std::string, void> : StdStringTraits<std::string> {};
#endif
}
}
} // namespace Internals
} // namespace ArduinoJson
#endif

View File

@ -1,9 +1,6 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -12,39 +9,28 @@
#include "../TypeTraits/EnableIf.hpp"
#include "../TypeTraits/IsBaseOf.hpp"
#include "../TypeTraits/IsChar.hpp"
#include "../TypeTraits/IsConst.hpp"
#include "../TypeTraits/RemoveReference.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TString, typename Enable = void>
struct StringTraits {};
struct StringTraits {
static const bool has_append = false;
static const bool has_equals = false;
};
template <typename TString>
struct StringTraits<const TString, void> : StringTraits<TString> {};
template <typename TString>
struct StringTraits<TString&, void> : StringTraits<TString> {};
}
}
} // namespace Internals
} // namespace ArduinoJson
#include "ArduinoStream.hpp"
#include "CharPointer.hpp"
#include "FlashString.hpp"
#include "StdStream.hpp"
#include "StdString.hpp"
namespace ArduinoJson {
namespace TypeTraits {
template <typename T, typename Enable = void>
struct IsString {
static const bool value = false;
};
template <typename T>
struct IsString<T, typename TypeTraits::EnableIf<
Internals::StringTraits<T>::has_equals>::type> {
static const bool value = Internals::StringTraits<T>::has_equals;
};
}
}

View File

@ -1,14 +1,11 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
namespace Internals {
// A meta-function that return the type T if Condition is true.
template <bool Condition, typename T = void>
@ -18,5 +15,5 @@ template <typename T>
struct EnableIf<true, T> {
typedef T type;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,24 +1,21 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include <stdint.h>
#include <stdlib.h> // for size_t
#include "../Configuration.hpp"
#include "../Polyfills/alias_cast.hpp"
#include "../Polyfills/math.hpp"
namespace ArduinoJson {
namespace TypeTraits {
namespace Internals {
template <typename T, size_t = sizeof(T)>
struct FloatTraits {};
#if ARDUINOJSON_DOUBLE_IS_64BITS
template <typename T>
struct FloatTraits<T, 8 /*64bits*/> {
typedef int64_t mantissa_type;
@ -31,29 +28,81 @@ struct FloatTraits<T, 8 /*64bits*/> {
template <typename TExponent>
static T make_float(T m, TExponent e) {
if (e >= 0)
return m * (e & 1 ? 1e1 : 1) * (e & 2 ? 1e2 : 1) * (e & 4 ? 1e4 : 1) *
(e & 8 ? 1e8 : 1) * (e & 16 ? 1e16 : 1) * (e & 32 ? 1e32 : 1) *
(e & 64 ? 1e64 : 1) * (e & 128 ? 1e128 : 1) *
(e & 256 ? 1e256 : 1);
e = TExponent(-e);
return m * (e & 1 ? 1e-1 : 1) * (e & 2 ? 1e-2 : 1) * (e & 4 ? 1e-4 : 1) *
(e & 8 ? 1e-8 : 1) * (e & 16 ? 1e-16 : 1) * (e & 32 ? 1e-32 : 1) *
(e & 64 ? 1e-64 : 1) * (e & 128 ? 1e-128 : 1) *
(e & 256 ? 1e-256 : 1);
if (e > 0) {
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= positiveBinaryPowerOfTen(index);
e >>= 1;
}
} else {
e = TExponent(-e);
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= negativeBinaryPowerOfTen(index);
e >>= 1;
}
}
return m;
}
static T positiveBinaryPowerOfTen(int index) {
static T factors[] = {
1e1,
1e2,
1e4,
1e8,
1e16,
forge(0x4693B8B5, 0xB5056E17), // 1e32
forge(0x4D384F03, 0xE93FF9F5), // 1e64
forge(0x5A827748, 0xF9301D32), // 1e128
forge(0x75154FDD, 0x7F73BF3C) // 1e256
};
return factors[index];
}
static T negativeBinaryPowerOfTen(int index) {
static T factors[] = {
forge(0x3FB99999, 0x9999999A), // 1e-1
forge(0x3F847AE1, 0x47AE147B), // 1e-2
forge(0x3F1A36E2, 0xEB1C432D), // 1e-4
forge(0x3E45798E, 0xE2308C3A), // 1e-8
forge(0x3C9CD2B2, 0x97D889BC), // 1e-16
forge(0x3949F623, 0xD5A8A733), // 1e-32
forge(0x32A50FFD, 0x44F4A73D), // 1e-64
forge(0x255BBA08, 0xCF8C979D), // 1e-128
forge(0x0AC80628, 0x64AC6F43) // 1e-256
};
return factors[index];
}
static T negativeBinaryPowerOfTenPlusOne(int index) {
static T factors[] = {
1e0,
forge(0x3FB99999, 0x9999999A), // 1e-1
forge(0x3F50624D, 0xD2F1A9FC), // 1e-3
forge(0x3E7AD7F2, 0x9ABCAF48), // 1e-7
forge(0x3CD203AF, 0x9EE75616), // 1e-15
forge(0x398039D6, 0x65896880), // 1e-31
forge(0x32DA53FC, 0x9631D10D), // 1e-63
forge(0x25915445, 0x81B7DEC2), // 1e-127
forge(0x0AFE07B2, 0x7DD78B14) // 1e-255
};
return factors[index];
}
static T nan() {
uint64_t x = uint64_t(0x7ff8) << 48;
return *reinterpret_cast<T*>(&x);
return forge(0x7ff80000, 0x00000000);
}
static T inf() {
uint64_t x = uint64_t(0x7ff0) << 48;
return *reinterpret_cast<T*>(&x);
return forge(0x7ff00000, 0x00000000);
}
// constructs a double floating point values from its binary representation
// we use this function to workaround platforms with single precision literals
// (for example, when -fsingle-precision-constant is passed to GCC)
static T forge(uint32_t msb, uint32_t lsb) {
return alias_cast<T>((uint64_t(msb) << 32) | lsb);
}
};
#endif
template <typename T>
struct FloatTraits<T, 4 /*32bits*/> {
@ -67,23 +116,47 @@ struct FloatTraits<T, 4 /*32bits*/> {
template <typename TExponent>
static T make_float(T m, TExponent e) {
if (e > 0)
return m * (e & 1 ? 1e1f : 1) * (e & 2 ? 1e2f : 1) * (e & 4 ? 1e4f : 1) *
(e & 8 ? 1e8f : 1) * (e & 16 ? 1e16f : 1) * (e & 32 ? 1e32f : 1);
e = -e;
return m * (e & 1 ? 1e-1f : 1) * (e & 2 ? 1e-2f : 1) * (e & 4 ? 1e-4f : 1) *
(e & 8 ? 1e-8f : 1) * (e & 16 ? 1e-16f : 1) * (e & 32 ? 1e-32f : 1);
if (e > 0) {
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= positiveBinaryPowerOfTen(index);
e >>= 1;
}
} else {
e = -e;
for (uint8_t index = 0; e != 0; index++) {
if (e & 1) m *= negativeBinaryPowerOfTen(index);
e >>= 1;
}
}
return m;
}
static T positiveBinaryPowerOfTen(int index) {
static T factors[] = {1e1f, 1e2f, 1e4f, 1e8f, 1e16f, 1e32f};
return factors[index];
}
static T negativeBinaryPowerOfTen(int index) {
static T factors[] = {1e-1f, 1e-2f, 1e-4f, 1e-8f, 1e-16f, 1e-32f};
return factors[index];
}
static T negativeBinaryPowerOfTenPlusOne(int index) {
static T factors[] = {1e0f, 1e-1f, 1e-3f, 1e-7f, 1e-15f, 1e-31f};
return factors[index];
}
static T forge(uint32_t bits) {
return alias_cast<T>(bits);
}
static T nan() {
uint32_t x = 0x7fc00000;
return *reinterpret_cast<T*>(&x);
return forge(0x7fc00000);
}
static T inf() {
uint32_t x = 0x7f800000;
return *reinterpret_cast<T*>(&x);
return forge(0x7f800000);
}
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,14 +1,11 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
namespace Internals {
// A meta-function that return the type T without the const modifier
template <typename T>
@ -23,5 +20,5 @@ template <typename T, size_t N>
struct IsArray<T[N]> {
static const bool value = true;
};
}
}
} // namespace Internals
} // namespace ArduinoJson

View File

@ -1,14 +1,11 @@
// Copyright Benoit Blanchon 2014-2017
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
namespace Internals {
// A meta-function that returns true if Derived inherits from TBase is an
// integral type.
@ -26,5 +23,5 @@ class IsBaseOf {
value = sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes)
};
};
}
}
} // namespace Internals
} // namespace ArduinoJson

Some files were not shown because too many files have changed in this diff Show More