Compare commits

..

108 Commits

Author SHA1 Message Date
f76017a015 Set version to 5.10.0 2017-05-20 09:11:03 +02:00
cda05aec04 Removed configurable number of decimal places (issues #288, #427 and #506) 2017-05-20 09:06:53 +02:00
639286f8b6 Travis: Removed retired images 2017-05-04 22:10:43 +02:00
cc66618e70 Fixed error forming reference to reference (issue #495) 2017-05-04 21:58:28 +02:00
9efc0ec40d Travis: Added GCC 6 2017-05-02 21:32:19 +02:00
34674fc282 Fixed error IsBaseOf is not a member of ArduinoJson::TypeTraits (issue #495) 2017-05-02 21:29:45 +02:00
01c3166043 Moved testimonials to https://bblanchon.github.io/ArduinoJson/ 2017-04-29 17:54:26 +02:00
bf2e3d5669 Updated the list of supported hardware (issue #491) 2017-04-28 10:28:38 +02:00
4e9f0b2e2e Set version to 5.9.0 2017-04-24 21:43:03 +02:00
223f14710d Now compatible with Particle 0.6.1 (issue #294 and PR #461 by @foodbag) 2017-04-24 21:40:19 +02:00
f7ae91b85d Removed unused stuffs 2017-04-22 11:35:55 +02:00
445dff499b ctest --output-on-failure 2017-04-22 11:34:12 +02:00
9afa05e2f4 Removed Print class and converted printTo() to a template method (issue #276) 2017-04-22 11:33:40 +02:00
c3e1677b7d Fixed warnings floating constant exceeds range of floatand floating constant truncated to zero (issue #483) 2017-04-20 14:46:52 +02:00
024976cda2 Renamed folder include/ to src/ (issue #461) 2017-04-20 10:26:40 +02:00
df541a2a22 Changed unit testing framework from Google Test to Catch 2017-04-18 18:22:24 +02:00
f2ef338cb8 Renamed JsonArray::removeAt() into remove() 2017-04-12 21:07:30 +02:00
8c6f64c111 Added JsonArray::remove(iterator) and JsonObject::remove(iterator) (issue #479) 2017-04-12 21:00:13 +02:00
5a16b2117b Travis: Disabled Teensy (PlatformioException: Could not load broken JSON) 2017-04-10 18:55:24 +02:00
71edcaf20f Split unit test into several executables 2017-04-10 15:36:59 +02:00
ac89d91db5 Organized test files in subfolders 2017-04-10 14:32:45 +02:00
e664c1ab05 Set version to 5.8.4 2017-03-26 21:33:12 +02:00
adba668109 Updated project URL 2017-03-25 22:05:06 +01:00
ad972725de Added a script to build a single file distribution 2017-03-25 21:56:37 +01:00
185eccf6f5 Added custom implementation of strtol() (issue #465)
`char` is now treated as an integral type (issue #337, #370)
2017-03-25 21:55:13 +01:00
c4567bac18 Added custom implementation of strtod() (issue #453) 2017-03-19 15:23:06 +01:00
13409c433a Added OpenEVSE LLC to the list of donators 2017-02-22 18:15:21 +01:00
20431debe0 Fuzzing: Run serializer too 2017-02-19 21:41:12 +01:00
797ea356ef Fuzzing: Better seed corpus 2017-02-19 21:30:22 +01:00
2321473c34 Added Prokhoryatov Alexey to the list of donators 2017-02-19 21:01:26 +01:00
0d5f65c5f3 Set version to 5.8.3 2017-02-11 15:12:03 +01:00
c30241775a Fixed JsonVariant::operator[const FlashStringHelper*] (issue #441) 2017-02-11 15:09:08 +01:00
31827d03f9 Added operators == and != for two JsonVariants (issue #436) 2017-02-11 15:06:17 +01:00
7bcdf3e722 JsonHttpClient: Close socket even when connection fails (issue #445) 2017-02-11 14:01:14 +01:00
db9a76f7c6 Fixed an access violation in DynamicJsonBuffer when memory allocation fails (issue #433) 2017-01-31 10:06:40 +01:00
3fd87e8e82 Added fuzzing/ to .mbedignore 2017-01-25 15:28:15 +01:00
22a2786610 Added Christoph Schmidt to the list of donators 2017-01-24 21:21:05 +01:00
2b5a6df1e1 Set version to 5.8.2 2017-01-22 18:08:32 +01:00
5fefeae404 Added deprecated attribute on asArray(), asObject() and asString() (issue #420) 2017-01-22 17:24:17 +01:00
d4f725d1fa Fixed error with string of type unsigned char* (issue #428) 2017-01-22 15:42:47 +01:00
a096098c1f Fixed error when the key of a JsonObject is a char[] and reduced code size when using const references (issue #423) 2017-01-22 11:10:45 +01:00
cc8c0472ca Fixed ignored Stream timeout and made sure we don't read more that necessary (issue #422) 2017-01-22 10:31:05 +01:00
fb554071dc Travis: Added -fsanitize to several builds 2017-01-21 19:49:44 +01:00
17a17c8957 Fixed parsing of comments (issue #421) 2017-01-17 21:48:13 +01:00
2e7d498865 Set version to 5.8.1 2017-01-15 21:02:22 +01:00
567157b005 Fixed error "Stream does not name a type" (issue #412) 2017-01-15 21:01:58 +01:00
ec6cbc5135 Fixed error when both ARDUINOJSON_ENABLE_STD_STREAM and ARDUINOJSON_ENABLE_ARDUINO_STREAM are set to 1 2017-01-15 15:18:59 +01:00
8499f0b960 Fixed errors with Variable Length Arrays (issue #416) 2017-01-15 15:11:26 +01:00
11432253a1 Fixed error when assigning a volatile int to a JsonVariant (issue #415) 2017-01-11 10:17:27 +01:00
f17e1c4a80 Added "Breaking Changes" section for v5.8.0 2017-01-10 10:07:57 +01:00
6b2f6a4f87 Added fuzzer 2017-01-08 16:17:01 +01:00
671329a3e9 Updated copyright year from 2016 to 2017 2017-01-06 21:07:34 +01:00
7e7074502f Set version to 5.8.0 2017-01-03 22:39:44 +01:00
aa306d5573 Travis: Removed XCode 6.1, 6.2 and 6.3 2017-01-03 22:35:58 +01:00
55669e306e Added support for Stream (issue #300) 2017-01-03 22:03:50 +01:00
3f96e070ce Reduced memory consumption by not duplicating spaces and comments 2017-01-01 21:30:20 +01:00
8032a4b564 Extracted StringReader and StringWriter from JsonParser
Split `Internals/` folder into `Data/`, `Deserialization/`, `Serialization/`
2017-01-01 21:30:20 +01:00
b923e8f4df Travis: Added Clang AddressSanitizer and UndefinedBehaviorSanitizer 2017-01-01 21:29:38 +01:00
c5388cf8e7 Travis: Compile all examples with PlatformIO 2016-12-28 20:23:27 +01:00
cb908a2373 Travis: Fixed SSL error problem with coveralls 2016-12-28 20:22:07 +01:00
cecbcd1929 Added operator == to compare JsonVariant and strings (issue #402) 2016-12-23 14:45:32 +01:00
90e0cc6091 JsonHttpClient: use HTTP 1.0 instead of 1.1 (issue #397, PR #399 by @Chris685)
Downgrading to HTTP 1.0 to prevent HTTP Chunked Transfer Encoding.
2016-12-14 19:41:10 +01:00
45bbf6db86 Set version to 5.7.3 2016-12-10 16:00:52 +01:00
432476c98a Added an printTo(char[N]) and prettyPrintTo(char[N]) (issue #292) 2016-12-10 15:59:48 +01:00
1f3e227a8b Added ability to set a nested value like this: root["A"]["B"] = "C" (issue #352) 2016-12-10 15:22:57 +01:00
66c28020c5 Renamed *.ipp to *Impl.hpp because they were ignored by Arduino IDE (issue #396) 2016-12-03 22:19:11 +01:00
6cfe2a58eb Added Doanh Luong to the list of donators 2016-11-25 18:41:33 +01:00
fc6ad51e68 Added the workaround for issue #118 in StringExample.ino 2016-11-24 18:11:02 +01:00
d3bc52951a Set version to 5.7.2 2016-11-23 21:54:56 +01:00
2f7232859e Fixed PROGMEM causing an exception on ESP8266 (issue #383) 2016-11-23 21:53:29 +01:00
4a7232ac99 Added DynamicJsonBuffer to the keywords 2016-11-23 21:25:49 +01:00
72d78432c9 Made PROGMEM available on more platforms (issue #381) 2016-11-16 22:24:58 +01:00
f6cd42d916 Travis: Added Arduino 1.6.12, removed 1.5.8 2016-11-16 22:24:41 +01:00
542dff2a08 Added Andrew Melvin to the list of donators 2016-11-15 21:48:40 +01:00
e75e843c88 Moved JsonBuffer size calculator to https://bblanchon.github.io/ArduinoJson/ 2016-11-13 20:48:03 +01:00
146a76247c Set version to 5.7.1 2016-11-13 20:21:16 +01:00
f28157cab7 Fixed compilation error when index is not an int (issue #381) 2016-11-13 20:19:36 +01:00
1ce16ce449 Added support for PROGMEM (issue #76) 2016-11-13 20:16:12 +01:00
c310e7e8b7 Set version to 5.7.0 2016-11-06 17:52:57 +01:00
aa2ef79e55 Templatized all functions using String or std::string
* Removed `ArduinoJson::String`
* Removed `JsonVariant::defaultValue<T>()`
* Removed non-template `JsonObject::get()` and `JsonArray.get()`
* Fixed support for `StringSumHelper` (issue #184)
* Replaced `ARDUINOJSON_USE_ARDUINO_STRING` by `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_ARDUINO_STRING` (issue #378)
* Added example `StringExample.ino` to show where `String` can be used
2016-11-06 17:52:18 +01:00
7ad57f1c33 Added Yoeri Kroon to the list of donators 2016-10-27 15:19:13 +02:00
cbfd331e50 JsonBuffer calculator now generates more compact expression 2016-09-30 10:44:05 +02:00
e6f55b1f6f Increased default nesting limit to 50 when compiled for a computer (issue #349) 2016-09-21 22:11:38 +02:00
bb805e93cb Set version to 5.6.7 2016-09-20 10:11:19 +02:00
deb57b960b Fixed parser that incorrectly rejected floats containing a + (issue #349) 2016-09-19 10:08:14 +02:00
8a9b918bf4 Fixed undefined behavior in Prettyfier and Print (issue #354) 2016-09-17 13:51:54 +02:00
2f6f3d0629 Fixed return value of JsonObject::set() (issue #350) 2016-09-16 10:10:31 +02:00
a60b35f41c Extracted class JsonSerializer 2016-09-11 13:43:21 +02:00
6757f35a3a Set version to 5.6.6 2016-08-29 20:55:36 +02:00
ffb9b6d1ba Fixed JsonVariant::success() which didn't propagate JsonArray::success() nor JsonObject::success() (issue #342). 2016-08-29 20:54:39 +02:00
e401498e4a Fixed JsonBuffer size calculator 2016-08-26 10:10:19 +02:00
d30e940b3b Added JsonBuffer size calculator 2016-08-25 19:08:12 +02:00
05ea5e04c8 Added Darlington Adibe to the list of donators 2016-08-25 11:40:31 +02:00
a7ef99d0fe Added .mbedignore for ARM mbdeb (PR #334 by @nuket) 2016-08-25 11:40:04 +02:00
f2a8b52c2c PlatformIO: Use the same name as for Arduino IDE (PR #339) 2016-08-24 13:44:10 +02:00
409ca7ee4e Fixed -Wparentheses warning introduced in v5.6.5 (PR #335 by @nuket) 2016-08-17 20:37:44 +02:00
387b565705 Set version to 5.6.5 2016-08-15 12:25:48 +02:00
96f486001d as<char*>() now returns true when input is null (issue #330) 2016-08-15 12:24:08 +02:00
a498abc14a Set version to 5.6.4 2016-07-20 13:16:14 +02:00
c64340a9bb Fixed error in float serialization (issue #324) 2016-07-20 13:15:17 +02:00
79d80a5dbf Set version to 5.6.3 2016-07-19 08:59:42 +02:00
7ebff5949f Fixed call of overloaded isinf(double&) is ambiguous (issue #284) 2016-07-19 08:57:19 +02:00
434080572c AppVeyor: Disabled build on MinGW32 2016-07-17 18:29:38 +02:00
c87a0e97ab Added as<JsonArray>() as a synonym for as<JsonArray&>()... (issue #291) 2016-07-17 17:22:58 +02:00
2dbd94951c Improved speed of float serialization (about twice faster) 2016-07-10 16:12:49 +02:00
1e044f50c7 Set version to 5.6.2 2016-06-30 20:23:58 +02:00
a7aa98510c Restored Travis build on all clang version 2016-06-30 20:23:21 +02:00
729ab56878 Fixed build when another lib does #undef isnan (issue #284) 2016-06-30 20:22:47 +02:00
455 changed files with 22195 additions and 151662 deletions

View File

@ -2,10 +2,10 @@
Thanks for using ArduinoJson :-)
Before opening an issue, please make sure you've read these:
https://github.com/bblanchon/ArduinoJson/wiki/FAQ
https://github.com/bblanchon/ArduinoJson/wiki/Avoiding-pitfalls
https://bblanchon.github.io/ArduinoJson/faq/
https://bblanchon.github.io/ArduinoJson/doc/pitfalls/
Next, make sure you provide all the relevant information: platform, code snippet, and error messages.
Please be concise!
-->
-->

3
.gitignore vendored
View File

@ -6,3 +6,6 @@
/sftp-config.json
.tags
.tags_sorted_by_file
/fuzzing/*_fuzzer
/fuzzing/*_fuzzer.options
/fuzzing/*_fuzzer_seed_corpus.zip

6
.mbedignore Normal file
View File

@ -0,0 +1,6 @@
.github/
examples/
fuzzing/
scripts/
test/
third-party/

View File

@ -7,111 +7,91 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.4']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=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 CMAKE_CXX_COMPILER=g++-4.5
env: SCRIPT=cmake GCC=4.5
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.6']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.6
env: SCRIPT=cmake GCC=4.6
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.7']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.7
env: SCRIPT=cmake GCC=4.7
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.8
env: SCRIPT=cmake GCC=4.8 SANITIZE=address
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.9
env: SCRIPT=cmake GCC=4.9 SANITIZE=leak
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-5
env: SCRIPT=cmake GCC=5 SANITIZE=undefined
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6']
env: SCRIPT=cmake GCC=6
- compiler: clang
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++
# - compiler: clang
# addons:
# apt:
# sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
# packages: ['clang-3.5']
# env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.5
# - compiler: clang
# addons:
# apt:
# sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
# packages: ['clang-3.6']
# env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.6
# - compiler: clang
# addons:
# apt:
# sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
# packages: ['clang-3.7']
# env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.7
# - compiler: clang
# addons:
# apt:
# sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
# packages: ['clang-3.8']
# env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.8
env: SCRIPT=cmake
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
packages: ['clang-3.5']
env: SCRIPT=cmake CLANG=3.5 SANITIZE=address
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
packages: ['clang-3.6']
env: SCRIPT=cmake CLANG=3.6 SANITIZE=leak
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
packages: ['clang-3.7']
env: SCRIPT=cmake CLANG=3.7
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
packages: ['clang-3.8']
env: SCRIPT=cmake CLANG=3.8 SANITIZE=undefined
- compiler: gcc
env: SCRIPT=coverage
- os: osx
osx_image: beta-xcode6.1
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: beta-xcode6.2
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: beta-xcode6.3
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode6.4
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode7
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode7.1
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode7.2
compiler: clang
env: SCRIPT=cmake-osx
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.3
compiler: clang
env: SCRIPT=cmake-osx
- env: SCRIPT=arduino VERSION=1.5.8 BOARD=arduino:avr:uno
env: SCRIPT=cmake SANITIZE=address
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.6.8 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.6.9 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=teensy31
#- env: SCRIPT=platformio BOARD=teensy31C
cache:
directories:
- "~/.platformio"

View File

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

View File

@ -1,6 +1,198 @@
ArduinoJson: change log
=======================
v5.10.0
-------
* Removed configurable number of decimal places (issues #288, #427 and #506)
* Changed exponentation thresholds to `1e7` and `1e-5` (issues #288, #427 and #506)
* `JsonVariant::is<double>()` now returns `true` for integers
* 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` |
v5.9.0
------
* Added `JsonArray::remove(iterator)` (issue #479)
* Added `JsonObject::remove(iterator)`
* Renamed `JsonArray::removeAt(size_t)` into `remove(size_t)`
* Renamed folder `include/` to `src/`
* Fixed warnings `floating constant exceeds range of float`and `floating constant truncated to zero` (issue #483)
* Removed `Print` class and converted `printTo()` to a template method (issue #276)
* Removed example `IndentedPrintExample.ino`
* Now compatible with Particle 0.6.1, thanks to Jacob Nite (issue #294 and PR #461 by @foodbag)
v5.8.4
------
* Added custom implementation of `strtod()` (issue #453)
* Added custom implementation of `strtol()` (issue #465)
* `char` is now treated as an integral type (issue #337, #370)
v5.8.3
------
* Fixed an access violation in `DynamicJsonBuffer` when memory allocation fails (issue #433)
* Added operators `==` and `!=` for two `JsonVariant`s (issue #436)
* Fixed `JsonVariant::operator[const FlashStringHelper*]` (issue #441)
v5.8.2
------
* Fixed parsing of comments (issue #421)
* Fixed ignored `Stream` timeout (issue #422)
* Made sure we don't read more that necessary (issue #422)
* Fixed error when the key of a `JsonObject` is a `char[]` (issue #423)
* Reduced code size when using `const` references
* Fixed error with string of type `unsigned char*` (issue #428)
* Added `deprecated` attribute on `asArray()`, `asObject()` and `asString()` (issue #420)
v5.8.1
------
* Fixed error when assigning a `volatile int` to a `JsonVariant` (issue #415)
* Fixed errors with Variable Length Arrays (issue #416)
* Fixed error when both `ARDUINOJSON_ENABLE_STD_STREAM` and `ARDUINOJSON_ENABLE_ARDUINO_STREAM` are set to `1`
* Fixed error "Stream does not name a type" (issue #412)
v5.8.0
------
* Added operator `==` to compare `JsonVariant` and strings (issue #402)
* 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);
```
v5.7.3
------
* Added an `printTo(char[N])` and `prettyPrintTo(char[N])` (issue #292)
* Added ability to set a nested value like this: `root["A"]["B"] = "C"` (issue #352)
* Renamed `*.ipp` to `*Impl.hpp` because they were ignored by Arduino IDE (issue #396)
v5.7.2
------
* Made PROGMEM available on more platforms (issue #381)
* Fixed PROGMEM causing an exception on ESP8266 (issue #383)
v5.7.1
------
* Added support for PROGMEM (issue #76)
* Fixed compilation error when index is not an `int` (issue #381)
v5.7.0
------
* Templatized all functions using `String` or `std::string`
* Removed `ArduinoJson::String`
* Removed `JsonVariant::defaultValue<T>()`
* Removed non-template `JsonObject::get()` and `JsonArray.get()`
* Fixed support for `StringSumHelper` (issue #184)
* Replaced `ARDUINOJSON_USE_ARDUINO_STRING` by `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_ARDUINO_STRING` (issue #378)
* 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);
```
v5.6.7
------
* Fixed `array[idx].as<JsonVariant>()` and `object[key].as<JsonVariant>()`
* Fixed return value of `JsonObject::set()` (issue #350)
* Fixed undefined behavior in `Prettyfier` and `Print` (issue #354)
* Fixed parser that incorrectly rejected floats containing a `+` (issue #349)
v5.6.6
------
* Fixed `-Wparentheses` warning introduced in v5.6.5 (PR #335 by @nuket)
* Added `.mbedignore` for ARM mbdeb (PR #334 by @nuket)
* Fixed `JsonVariant::success()` which didn't propagate `JsonArray::success()` nor `JsonObject::success()` (issue #342).
v5.6.5
------
* `as<char*>()` now returns `true` when input is `null` (issue #330)
v5.6.4
------
* Fixed error in float serialization (issue #324)
v5.6.3
------
* Improved speed of float serialization (about twice faster)
* Added `as<JsonArray>()` as a synonym for `as<JsonArray&>()`... (issue #291)
* Fixed `call of overloaded isinf(double&) is ambiguous` (issue #284)
v5.6.2
------
* Fixed build when another lib does `#undef isnan` (issue #284)
v5.6.1
------
@ -69,7 +261,8 @@ 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**:
### BREAKING CHANGES :warning:
- `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
- `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
@ -100,7 +293,7 @@ v5.0.3
v5.0.2
------
* Fixed segmentation fault in `parseObject(String)` and `parseArray(String)`, when the
* Fixed segmentation fault in `parseObject(String)` and `parseArray(String)`, when the
`StaticJsonBuffer` is too small to hold a copy of the string
* Fixed Clang warning "register specifier is deprecated" (issue #102)
* Fixed GCC warning "declaration shadows a member" (issue #103)
@ -125,7 +318,8 @@ 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**:
### 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()`
@ -216,14 +410,14 @@ v3.1
Old generator API:
JsonObject<3> root;
JsonObject<3> root;
root.add("sensor", "gps");
root.add("time", 1351824120);
root.add("data", array);
New generator API:
JsonObject<3> root;
JsonObject<3> root;
root["sensor"] = "gps";
root["time"] = 1351824120;
root["data"] = array;
@ -280,7 +474,7 @@ 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
v1.0
----
Initial release

View File

@ -1,8 +1,8 @@
# Copyright Benoit Blanchon 2014-2016
# Copyright Benoit Blanchon 2014-2017
# MIT License
#
# Arduino JSON library
# https://github.com/bblanchon/ArduinoJson
# https://bblanchon.github.io/ArduinoJson/
# If you like this project, please add a star!
cmake_minimum_required(VERSION 3.0)
@ -10,12 +10,10 @@ project(ArduinoJson)
enable_testing()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
if(${COVERAGE})
set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
endif()
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)
add_subdirectory(third-party/catch)
add_subdirectory(test)

View File

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

View File

@ -1,13 +1,14 @@
Arduino JSON library
ArduinoJson - C++ JSON library for IoT
====================
[![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.*
It's designed to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc).
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).
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
--------
@ -26,16 +27,16 @@ Features
Works on
--------
* All Arduino boards (Uno, Due, Mini, Micro, Yun...)
* ESP8266
* Arduino boards: Uno, Due, Mini, Micro, Yun...
* ESP8266, ESP32
* Teensy
* Intel Edison and Galileo
* PlatformIO
* Energia
* RedBearLab boards (BLE Nano...)
* Computers (Windows, Linux, OSX...)
See [FAQ: Compatibility issues](https://github.com/bblanchon/ArduinoJson/wiki/Compatibility-issues)
* Intel Edison and Galileo
* WeMos boards: D1...
* Computers: Windows, Linux, OSX...
* PlatformIO
* Particle
* Energia
Quick start
-----------
@ -55,6 +56,8 @@ double latitude = root["data"][0];
double longitude = root["data"][1];
```
[See JsonParserExample.ino](examples/JsonParserExample/JsonParserExample.ino)
#### Encoding / Generating
```c++
@ -65,46 +68,24 @@ root["sensor"] = "gps";
root["time"] = 1351824120;
JsonArray& data = root.createNestedArray("data");
data.add(48.756080, 6); // 6 is the number of decimals to print
data.add(2.302038, 6); // if not specified, 2 digits are printed
data.add(48.756080);
data.add(2.302038);
root.printTo(Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
```
[See JsonGeneratorExample.ino](examples/JsonGeneratorExample/JsonGeneratorExample.ino)
Documentation
-------------
The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)
The documentation is available online in the [ArduinoJson Website](https://bblanchon.github.io/ArduinoJson/).
Testimonials
------------
The [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) helps you get started with the library.
From Arduino's Forum user `jflaplante`:
> I tried aJson json-arduino before trying your library. I always ran into memory problem after a while.
> I have no such problem so far with your library. It is working perfectly with my web services.
From Arduino's Forum user `gbathree`:
> Thanks so much - this is an awesome library! If you want to see what we're doing with it - the project is located at www.photosynq.org.
From StackOverflow user `thegreendroid`:
> It has a really elegant, simple API and it works like a charm on embedded and Windows/Linux platforms. We recently started using this on an embedded project and I can vouch for its quality.
From GitHub user `zacsketches`:
> Thanks for a great library!!!
> I've been watching you consistently develop this library over the past six months, and I used it today for a publish and subscribe architecture designed to help hobbyists move into more advanced robotics. Your library allowed me to implement remote subscription in order to facilitate multi-processor robots.
> ArduinoJson saved me a week's worth of time!!
[From Reddit user `erm_what_`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusjk8c):
> This is a great library and I wouldn't be able to do the project I'm doing without it. I completely recommend it.
[From Reddit user `makerhacks`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusqg7b):
> I am just starting an ESP8266 clock project and now I can output JSON from my server script and interpret it painlessly.
[From Twitter user `@hemalchevli`](https://twitter.com/hemalchevli/status/715788439397011456):
> ArduinoJson library should be used as a benchmark/reference for making libraries. Truly elegant.
Donators
--------
@ -124,6 +105,13 @@ Special thanks to the following persons and companies who made generous donation
* 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'>
---

View File

@ -1,11 +1,13 @@
version: 5.6.1.{build}
version: 5.10.0.{build}
environment:
matrix:
- CMAKE_GENERATOR: Visual Studio 14 2015
- CMAKE_GENERATOR: Visual Studio 12 2013
- CMAKE_GENERATOR: Visual Studio 11 2012
- CMAKE_GENERATOR: Visual Studio 10 2010
- CMAKE_GENERATOR: MinGW Makefiles
# - CMAKE_GENERATOR: MinGW Makefiles
# Note: Disabled because of unexplicated error -1073741511
# This used to work fine with GCC 4.8.2 then failed after they upgraded to GCC 4.9.3
configuration: Debug
before_build:
- set PATH=C:\MinGW\bin;%PATH:C:\Program Files\Git\usr\bin;=% # Workaround for CMake not wanting sh.exe on PATH for MinGW
@ -13,4 +15,4 @@ before_build:
build_script:
- cmake --build . --config %CONFIGURATION%
test_script:
- ctest -V .
- ctest --output-on-failure .

View File

@ -1,35 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
using namespace ArduinoJson::Internals;
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
IndentedPrint serial(Serial);
serial.setTabSize(4);
serial.println("This is at indentation 0");
serial.indent();
serial.println("This is at indentation 1");
serial.println("This is also at indentation 1");
serial.indent();
serial.println("This is at indentation 2");
serial.unindent();
serial.unindent();
serial.println("This is back at indentation 0");
}
void loop() {
// not used in this example
}

View File

@ -1,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>
@ -44,8 +44,8 @@ void setup() {
// It's also possible to create the array separately and add it to the
// JsonObject but it's less efficient.
JsonArray& data = root.createNestedArray("data");
data.add(double_with_n_digits(48.756080, 6));
data.add(double_with_n_digits(2.302038, 6));
data.add(48.756080);
data.add(2.302038);
root.printTo(Serial);
// This prints:

View File

@ -1,16 +1,16 @@
// Sample Arduino Json Web Client
// Downloads and parse http://jsonplaceholder.typicode.com/users/1
//
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>
#include <SPI.h>
EthernetClient client;
@ -36,16 +36,13 @@ void setup() {
void loop() {
if (connect(server)) {
if (sendRequest(server, resource) && skipResponseHeaders()) {
char response[MAX_CONTENT_SIZE];
readReponseContent(response, sizeof(response));
UserData userData;
if (parseUserData(response, &userData)) {
if (readReponseContent(&userData)) {
printUserData(&userData);
}
}
disconnect();
}
disconnect();
wait();
}
@ -87,9 +84,9 @@ bool sendRequest(const char* host, const char* resource) {
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.1");
client.println(" HTTP/1.0");
client.print("Host: ");
client.println(server);
client.println(host);
client.println("Connection: close");
client.println();
@ -111,13 +108,6 @@ bool skipResponseHeaders() {
return ok;
}
// Read the body of the response from the HTTP server
void readReponseContent(char* content, size_t maxSize) {
size_t length = client.readBytes(content, maxSize);
content[length] = 0;
Serial.println(content);
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
// {
@ -143,21 +133,20 @@ void readReponseContent(char* content, size_t maxSize) {
// "bs": "harness real-time e-markets"
// }
// }
bool parseUserData(char* content, struct UserData* userData) {
bool readReponseContent(struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// This is only required if you use StaticJsonBuffer.
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
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 on the stack
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
// If the memory pool is too big for the stack, use this instead:
// DynamicJsonBuffer jsonBuffer;
// Allocate a temporary memory pool
DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);
JsonObject& root = jsonBuffer.parseObject(content);
JsonObject& root = jsonBuffer.parseObject(client);
if (!root.success()) {
Serial.println("JSON parsing failed!");

View File

@ -1,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>

View File

@ -3,11 +3,11 @@
// You can easily test this program with netcat:
// $ nc -ulp 8888
//
// by Benoit Blanchon, MIT License 2015-2016
// by Benoit Blanchon, MIT License 2015-2017
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>
#include <Ethernet.h>
#include <SPI.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress localIp(192, 168, 0, 177);

View File

@ -0,0 +1,56 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#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
DynamicJsonBuffer jsonBuffer;
// You can use a Flash String as your JSON input.
// WARNING: the content of the Flash String will be duplicated in the
// JsonBuffer.
JsonObject& root =
jsonBuffer.parseObject(F("{\"sensor\":\"gps\",\"time\":1351824120,"
"\"data\":[48.756080,2.302038]}"));
// You can use a Flash String to get an element of a JsonObject
// No duplication is done.
long time = root[F("time")];
// You can use a Flash String to set an element of a JsonObject
// WARNING: the content of the Flash String will be duplicated in the
// JsonBuffer.
root[F("time")] = time;
// You can set a Flash String to a JsonObject or JsonArray:
// WARNING: the content of the Flash String will be duplicated in the
// JsonBuffer.
root["sensor"] = F("gps");
// You can compare the content of a JsonVariant to a Flash String
if (root["sensor"] == F("gps")) {
// ...
}
#else
#warning PROGMEM is not supported on this platform
#endif
}
void loop() {
// not used in this example
}

View File

@ -0,0 +1,63 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#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;
// You can use a String as your JSON input.
// WARNING: the content of the String will be duplicated in the JsonBuffer.
String input =
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
JsonObject& root = jsonBuffer.parseObject(input);
// You can use a String to get an element of a JsonObject
// No duplication is done.
long time = root[String("time")];
// You can use a String to set an element of a JsonObject
// WARNING: the content of the String will be duplicated in the JsonBuffer.
root[String("time")] = time;
// You can get a String from a JsonObject or JsonArray:
// No duplication is done, at least not in the JsonBuffer.
String sensor = root["sensor"];
// Unfortunately, the following doesn't work (issue #118):
// sensor = root["sensor"]; // <- error "ambiguous overload for 'operator='"
// As a workaround, you need to replace by:
sensor = root["sensor"].as<String>();
// You can set a String to a JsonObject or JsonArray:
// WARNING: the content of the String will be duplicated in the JsonBuffer.
root["sensor"] = 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";
// You can compare the content of a JsonObject with a String
if (root["sensor"] == sensor) {
// ...
}
// Lastly, you can print the resulting JSON to a String
String output;
root.printTo(output);
}
void loop() {
// not used in this example
}

19
fuzzing/Makefile Normal file
View File

@ -0,0 +1,19 @@
# CAUTION: this file is invoked by https://github.com/google/oss-fuzz
CXXFLAGS += -I../src
all: \
$(OUT)/json_fuzzer \
$(OUT)/json_fuzzer_seed_corpus.zip \
$(OUT)/json_fuzzer.options
$(OUT)/json_fuzzer: fuzzer.cpp $(shell find ../src -type f)
$(CXX) $(CXXFLAGS) $< -o$@ $(LIB_FUZZING_ENGINE)
$(OUT)/json_fuzzer_seed_corpus.zip: seed_corpus/*
zip -j $@ $?
$(OUT)/json_fuzzer.options:
@echo "[libfuzzer]" > $@
@echo "max_len = 256" >> $@
@echo "timeout = 10" >> $@

9
fuzzing/fuzz.sh Executable file
View File

@ -0,0 +1,9 @@
#!/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

26
fuzzing/fuzzer.cpp Normal file
View File

@ -0,0 +1,26 @@
#include <ArduinoJson.h>
class memstream : public std::istream {
struct membuf : std::streambuf {
membuf(const uint8_t *p, size_t l) {
setg((char *)p, (char *)p, (char *)p + l);
}
};
membuf _buffer;
public:
memstream(const uint8_t *p, size_t l)
: std::istream(&_buffer), _buffer(p, l) {
rdbuf(&_buffer);
}
};
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
DynamicJsonBuffer jsonBuffer;
memstream json(data, size);
JsonVariant variant = jsonBuffer.parse(json);
if (variant.success()) {
variant.as<std::string>(); // <- serialize to JSON
}
return 0;
}

2
fuzzing/my_corpus/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

View File

@ -0,0 +1,10 @@
//comment
/*comment*/
[ //comment
/*comment*/"comment"/*comment*/,//comment
/*comment*/{//comment
/* comment*/"key"//comment
: //comment
"value"//comment
}/*comment*/
]//comment

View File

@ -0,0 +1 @@
[]

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1 @@
[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20,[21,[22,[23,[24,[25,[26,[27,[28,[29,[30,[31,[32,[33,[34,[35,[36,[37,[38,[39,[40,[41,[42,[43,[44,[45,[46,[47,[48,[49,[50,[51,[52,[53,[54,[55,[56,[57,[58,[59,[60,[61,[62,[63,[64,[65,[66,[67,[68,[69,[70,[71,[72,[73,[74,[75,[76,[77,[78,[79,[80,[81,[82,[83,[84,[85,[86,[87,[88,[89,[90,[91,[92,[93,[94,[95,[96,[97,[98,[99,[100,[101,[102,[103,[104,[105,[106,[107,[108,[109,[110,[111,[112,[113,[114,[115,[116,[117,[118,[119,[120]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

View File

@ -0,0 +1,24 @@
[
123,
-123,
123.456,
-123.456,
12e34,
12e-34,
12e+34,
12E34,
12E-34,
12E+34,
12.34e56,
12.34e-56,
12.34e+56,
12.34E56,
12.34E-56,
12.34E+56,
NaN,
-NaN,
+NaN,
Infinity,
+Infinity,
-Infinity
]

View File

@ -0,0 +1,53 @@
{
"coord": {
"lon": -0.13,
"lat": 51.51
},
"weather": [
{
"id": 301,
"main": "Drizzle",
"description": "drizzle",
"icon": "09n"
},
{
"id": 701,
"main": "Mist",
"description": "mist",
"icon": "50n"
},
{
"id": 741,
"main": "Fog",
"description": "fog",
"icon": "50n"
}
],
"base": "stations",
"main": {
"temp": 281.87,
"pressure": 1032,
"humidity": 100,
"temp_min": 281.15,
"temp_max": 283.15
},
"visibility": 2900,
"wind": {
"speed": 1.5
},
"clouds": {
"all": 90
},
"dt": 1483820400,
"sys": {
"type": 1,
"id": 5091,
"message": 0.0226,
"country": "GB",
"sunrise": 1483776245,
"sunset": 1483805443
},
"id": 2643743,
"name": "London",
"cod": 200
}

View File

@ -0,0 +1,8 @@
[
"hello",
'hello',
hello,
{"hello":"world"},
{'hello':'world'},
{hello:world}
]

View File

@ -0,0 +1,90 @@
{
"response": {
"version": "0.1",
"termsofService": "http://www.wunderground.com/weather/api/d/terms.html",
"features": {
"conditions": 1
}
},
"current_observation": {
"image": {
"url": "http://icons-ak.wxug.com/graphics/wu2/logo_130x80.png",
"title": "Weather Underground",
"link": "http://www.wunderground.com"
},
"display_location": {
"full": "San Francisco, CA",
"city": "San Francisco",
"state": "CA",
"state_name": "California",
"country": "US",
"country_iso3166": "US",
"zip": "94101",
"latitude": "37.77500916",
"longitude": "-122.41825867",
"elevation": "47.00000000"
},
"observation_location": {
"full": "SOMA - Near Van Ness, San Francisco, California",
"city": "SOMA - Near Van Ness, San Francisco",
"state": "California",
"country": "US",
"country_iso3166": "US",
"latitude": "37.773285",
"longitude": "-122.417725",
"elevation": "49 ft"
},
"estimated": {},
"station_id": "KCASANFR58",
"observation_time": "Last Updated on June 27, 5:27 PM PDT",
"observation_time_rfc822": "Wed, 27 Jun 2012 17:27:13 -0700",
"observation_epoch": "1340843233",
"local_time_rfc822": "Wed, 27 Jun 2012 17:27:14 -0700",
"local_epoch": "1340843234",
"local_tz_short": "PDT",
"local_tz_long": "America/Los_Angeles",
"local_tz_offset": "-0700",
"weather": "Partly Cloudy",
"temperature_string": "66.3 F (19.1 C)",
"temp_f": 66.3,
"temp_c": 19.1,
"relative_humidity": "65%",
"wind_string": "From the NNW at 22.0 MPH Gusting to 28.0 MPH",
"wind_dir": "NNW",
"wind_degrees": 346,
"wind_mph": 22,
"wind_gust_mph": "28.0",
"wind_kph": 35.4,
"wind_gust_kph": "45.1",
"pressure_mb": "1013",
"pressure_in": "29.93",
"pressure_trend": "+",
"dewpoint_string": "54 F (12 C)",
"dewpoint_f": 54,
"dewpoint_c": 12,
"heat_index_string": "NA",
"heat_index_f": "NA",
"heat_index_c": "NA",
"windchill_string": "NA",
"windchill_f": "NA",
"windchill_c": "NA",
"feelslike_string": "66.3 F (19.1 C)",
"feelslike_f": "66.3",
"feelslike_c": "19.1",
"visibility_mi": "10.0",
"visibility_km": "16.1",
"solarradiation": "",
"UV": "5",
"precip_1hr_string": "0.00 in ( 0 mm)",
"precip_1hr_in": "0.00",
"precip_1hr_metric": " 0",
"precip_today_string": "0.00 in (0 mm)",
"precip_today_in": "0.00",
"precip_today_metric": "0",
"icon": "partlycloudy",
"icon_url": "http://icons-ak.wxug.com/i/c/k/partlycloudy.gif",
"forecast_url": "http://www.wunderground.com/US/CA/San_Francisco.html",
"history_url": "http://www.wunderground.com/history/airport/KCASANFR58/2012/6/27/DailyHistory.html",
"ob_url": "http://www.wunderground.com/cgi-bin/findweather/getForecast?query=37.773285,-122.417725"
}
}

View File

@ -1,21 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "ArduinoJson/DynamicJsonBuffer.hpp"
#include "ArduinoJson/JsonArray.hpp"
#include "ArduinoJson/JsonObject.hpp"
#include "ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson/Internals/JsonParser.ipp"
#include "ArduinoJson/JsonArray.ipp"
#include "ArduinoJson/JsonBuffer.ipp"
#include "ArduinoJson/JsonObject.ipp"
#include "ArduinoJson/JsonVariant.ipp"
using namespace ArduinoJson;

View File

@ -1,89 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifdef ARDUINO // assume this is an embedded platform
// store using float instead of double to reduce the memory usage (issue #134)
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 0
#endif
// store using a long because it usually match the size of a float.
#ifndef ARDUINOJSON_USE_LONG_LONG
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#ifndef ARDUINOJSON_USE_INT64
#define ARDUINOJSON_USE_INT64 0
#endif
// arduino has its own implementation of String to replace std::string
#ifndef ARDUINOJSON_USE_ARDUINO_STRING
#define ARDUINOJSON_USE_ARDUINO_STRING 1
#endif
// arduino doesn't support STL stream
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 0
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
#ifdef ARDUINO_ARCH_AVR
// alignment isn't needed for 8-bit AVR
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#else
// but must processor needs pointer to be align on word size
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
#endif
#else // assume this is a computer
// on a computer we have plenty of memory so we can use doubles
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 1
#endif
// use long long when available
#ifndef ARDUINOJSON_USE_LONG_LONG
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define ARDUINOJSON_USE_LONG_LONG 1
#else
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#endif
// use _int64 on old versions of Visual Studio
#ifndef ARDUINOJSON_USE_INT64
#if defined(_MSC_VER) && _MSC_VER <= 1700
#define ARDUINOJSON_USE_INT64 1
#else
#define ARDUINOJSON_USE_INT64 0
#endif
#endif
// on a computer, we can use std::string
#ifndef ARDUINOJSON_USE_ARDUINO_STRING
#define ARDUINOJSON_USE_ARDUINO_STRING 0
#endif
// on a computer, we can assume that the STL is there
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 1
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
// even if not required, most cpu's are faster with aligned pointers
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#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,18 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/BlockJsonBuffer.hpp"
namespace ArduinoJson {
// Implements a JsonBuffer with dynamic memory allocation.
// You are strongly encouraged to consider using StaticJsonBuffer which is much
// more suitable for embedded systems.
typedef Internals::BlockJsonBuffer<Internals::DefaultAllocator>
DynamicJsonBuffer;
}

View File

@ -1,56 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
inline const char *skipCStyleComment(const char *ptr) {
ptr += 2;
for (;;) {
if (ptr[0] == '\0') return ptr;
if (ptr[0] == '*' && ptr[1] == '/') return ptr + 2;
ptr++;
}
}
inline const char *skipCppStyleComment(const char *ptr) {
ptr += 2;
for (;;) {
if (ptr[0] == '\0' || ptr[0] == '\n') return ptr;
ptr++;
}
}
inline const char *skipSpacesAndComments(const char *ptr) {
for (;;) {
switch (ptr[0]) {
case ' ':
case '\t':
case '\r':
case '\n':
ptr++;
continue;
case '/':
switch (ptr[1]) {
case '*':
ptr = skipCStyleComment(ptr);
break;
case '/':
ptr = skipCppStyleComment(ptr);
break;
default:
return ptr;
}
break;
default:
return ptr;
}
}
}
}
}

View File

@ -1,33 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
#include "../String.hpp"
namespace ArduinoJson {
namespace Internals {
// A Print implementation that allows to write in a String
class DynamicStringBuilder : public Print {
public:
DynamicStringBuilder(String &str) : _str(str) {}
virtual size_t write(uint8_t c) {
// Need to cast to char, otherwise String will print a number (issue #120)
_str += static_cast<char>(c);
return 1;
}
private:
DynamicStringBuilder &operator=(const DynamicStringBuilder &);
String &_str;
};
}
}

View File

@ -1,66 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include "../JsonVariant.hpp"
namespace ArduinoJson {
namespace Internals {
// Parse JSON string to create JsonArrays and JsonObjects
// This internal class is not indended to be used directly.
// Instead, use JsonBuffer.parseArray() or .parseObject()
class JsonParser {
public:
JsonParser(JsonBuffer *buffer, char *json, uint8_t nestingLimit)
: _buffer(buffer),
_readPtr(json ? json : ""),
_writePtr(json),
_nestingLimit(nestingLimit) {}
JsonArray &parseArray();
JsonObject &parseObject();
JsonVariant parseVariant() {
JsonVariant result;
parseAnythingTo(&result);
return result;
}
private:
bool skip(char charToSkip);
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) {
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 == '.';
}
static inline bool isQuote(char c) {
return c == '\'' || c == '\"';
}
JsonBuffer *_buffer;
const char *_readPtr;
char *_writePtr;
uint8_t _nestingLimit;
};
}
}

View File

@ -1,146 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Polyfills/attributes.hpp"
#include "../Polyfills/isInfinity.hpp"
#include "../Polyfills/isNaN.hpp"
#include "../Polyfills/normalize.hpp"
#include "../Print.hpp"
#include "Encoding.hpp"
#include "JsonFloat.hpp"
#include "JsonInteger.hpp"
namespace ArduinoJson {
namespace Internals {
// Writes the JSON tokens to a Print implementation
// This class is used by:
// - JsonArray::writeTo()
// - JsonObject::writeTo()
// - JsonVariant::writeTo()
// Its derived by PrettyJsonWriter that overrides some members to add
// indentation.
class JsonWriter {
public:
explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
// Returns the number of bytes sent to the Print implementation.
// This is very handy for implementations of printTo() that must return the
// number of bytes written.
size_t bytesWritten() const { return _length; }
void beginArray() { writeRaw('['); }
void endArray() { writeRaw(']'); }
void beginObject() { writeRaw('{'); }
void endObject() { writeRaw('}'); }
void writeColon() { writeRaw(':'); }
void writeComma() { writeRaw(','); }
void writeBoolean(bool value) { writeRaw(value ? "true" : "false"); }
void writeString(const char *value) {
if (!value) {
writeRaw("null");
} else {
writeRaw('\"');
while (*value) writeChar(*value++);
writeRaw('\"');
}
}
void writeChar(char c) {
char specialChar = Encoding::escapeChar(c);
if (specialChar) {
writeRaw('\\');
writeRaw(specialChar);
} else {
writeRaw(c);
}
}
void writeFloat(JsonFloat value, int digits = 2) {
if (Polyfills::isNaN(value)) return writeRaw("NaN");
if (value < 0.0) {
writeRaw('-');
value = -value;
}
if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
short powersOf10;
if (value > 1000 || value < 0.001) {
powersOf10 = Polyfills::normalize(value);
} else {
powersOf10 = 0;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
JsonFloat rounding = 0.5;
for (uint8_t i = 0; i < digits; ++i) rounding /= 10.0;
value += rounding;
// Extract the integer part of the value and print it
JsonUInt int_part = static_cast<JsonUInt>(value);
JsonFloat remainder = value - static_cast<JsonFloat>(int_part);
writeInteger(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
writeRaw('.');
}
// Extract digits from the remainder one at a time
while (digits-- > 0) {
remainder *= 10.0;
JsonUInt toPrint = JsonUInt(remainder);
writeInteger(JsonUInt(remainder));
remainder -= static_cast<JsonFloat>(toPrint);
}
if (powersOf10 < 0) {
writeRaw("e-");
writeInteger(-powersOf10);
}
if (powersOf10 > 0) {
writeRaw('e');
writeInteger(powersOf10);
}
}
void writeInteger(JsonUInt value) {
char buffer[22];
uint8_t i = 0;
do {
buffer[i++] = static_cast<char>(value % 10 + '0');
value /= 10;
} while (value);
while (i > 0) {
writeRaw(buffer[--i]);
}
}
void writeRaw(const char *s) { _length += _sink.print(s); }
void writeRaw(char c) { _length += _sink.write(c); }
protected:
Print &_sink;
size_t _length;
private:
JsonWriter &operator=(const JsonWriter &); // cannot be assigned
};
}
}

View File

@ -1,66 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include <stdlib.h>
namespace ArduinoJson {
namespace Internals {
template <typename TFloat>
TFloat parse(const char *);
template <>
inline float parse<float>(const char *s) {
return static_cast<float>(strtod(s, NULL));
}
template <>
inline double parse<double>(const char *s) {
return strtod(s, NULL);
}
template <>
inline long parse<long>(const char *s) {
return strtol(s, NULL, 10);
}
template <>
inline unsigned long parse<unsigned long>(const char *s) {
return strtoul(s, NULL, 10);
}
template <>
inline int parse<int>(const char *s) {
return atoi(s);
}
#if ARDUINOJSON_USE_LONG_LONG
template <>
inline long long parse<long long>(const char *s) {
return strtoll(s, NULL, 10);
}
template <>
inline unsigned long long parse<unsigned long long>(const char *s) {
return strtoull(s, NULL, 10);
}
#endif
#if ARDUINOJSON_USE_INT64
template <>
inline __int64 parse<__int64>(const char *s) {
return _strtoi64(s, NULL, 10);
}
template <>
inline unsigned __int64 parse<unsigned __int64>(const char *s) {
return _strtoui64(s, NULL, 10);
}
#endif
}
}

View File

@ -1,37 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// A Print implementation that allows to write in a char[]
class StaticStringBuilder : public Print {
public:
StaticStringBuilder(char *buf, size_t size)
: buffer(buf), capacity(size - 1), length(0) {
buffer[0] = '\0';
}
virtual size_t write(uint8_t c) {
if (length >= capacity) return 0;
buffer[length++] = c;
buffer[length] = '\0';
return 1;
}
private:
char *buffer;
size_t capacity;
size_t length;
};
}
}

View File

@ -1,268 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/JsonBufferAllocated.hpp"
#include "Internals/JsonPrintable.hpp"
#include "Internals/List.hpp"
#include "Internals/ReferenceType.hpp"
#include "JsonVariant.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsReference.hpp"
#include "TypeTraits/IsSame.hpp"
// Returns the size (in bytes) of an array with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type))
namespace ArduinoJson {
// Forward declarations
class JsonObject;
class JsonBuffer;
class JsonArraySubscript;
// An array of JsonVariant.
//
// The constructor is private, instances must be created via
// JsonBuffer::createArray() or JsonBuffer::parseArray().
// A JsonArray can be serialized to a JSON string via JsonArray::printTo().
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
class JsonArray : public Internals::JsonPrintable<JsonArray>,
public Internals::ReferenceType,
public Internals::List<JsonVariant>,
public Internals::JsonBufferAllocated {
public:
// A meta-function that returns true if type T can be used in
// JsonArray::set()
template <typename T>
struct CanSet {
static const bool value = JsonVariant::IsConstructibleFrom<T>::value ||
TypeTraits::IsSame<T, String &>::value ||
TypeTraits::IsSame<T, const String &>::value;
};
// 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)
: Internals::List<JsonVariant>(buffer) {}
// Gets the value at the specified index
JsonVariant operator[](size_t index) const {
return get(index);
}
// Gets or sets the value at specified index
JsonArraySubscript operator[](size_t index);
// Adds the specified value at the end of the array.
//
// bool add(bool);
// bool add(char);
// bool add(long);
// bool add(int);
// bool add(short);
// bool add(float value);
// bool add(double value);
// bool add(const char*);
template <typename T>
bool add(
T value,
typename TypeTraits::EnableIf<
CanSet<T>::value && !TypeTraits::IsReference<T>::value>::type * = 0) {
return addNode<T>(value);
}
// bool add(const String&)
// bool add(const JsonVariant&);
// bool add(JsonArray&);
// bool add(JsonObject&);
template <typename T>
bool add(const T &value,
typename TypeTraits::EnableIf<CanSet<T &>::value>::type * = 0) {
return addNode<T &>(const_cast<T &>(value));
}
// bool add(float value, uint8_t decimals);
// bool add(double value, uint8_t decimals);
template <typename T>
bool add(T value, uint8_t decimals,
typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
return addNode<JsonVariant>(JsonVariant(value, decimals));
}
// Sets the value at specified index.
//
// bool set(size_t index, bool value);
// bool set(size_t index, long value);
// bool set(size_t index, int value);
// bool set(size_t index, short value);
template <typename T>
bool set(
size_t index, T value,
typename TypeTraits::EnableIf<
CanSet<T>::value && !TypeTraits::IsReference<T>::value>::type * = 0) {
return setNodeAt<T>(index, value);
}
// bool set(size_t index, const String&)
// bool set(size_t index, const JsonVariant&);
// bool set(size_t index, JsonArray&);
// bool set(size_t index, JsonObject&);
template <typename T>
bool set(size_t index, const T &value,
typename TypeTraits::EnableIf<CanSet<T &>::value>::type * = 0) {
return setNodeAt<T &>(index, const_cast<T &>(value));
}
// bool set(size_t index, float value, uint8_t decimals = 2);
// bool set(size_t index, double value, uint8_t decimals = 2);
template <typename T>
bool set(size_t index, T value, uint8_t decimals,
typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
return setNodeAt<const JsonVariant &>(index, JsonVariant(value, decimals));
}
// Gets the value at the specified index.
JsonVariant get(size_t index) const {
node_type *node = getNodeAt(index);
return node ? node->content : JsonVariant();
}
// Gets the value at the specified index.
template <typename T>
T get(size_t index) const {
node_type *node = getNodeAt(index);
return node ? node->content.as<T>() : JsonVariant::defaultValue<T>();
}
// Check the type of the value at specified index.
template <typename T>
bool is(size_t index) const {
node_type *node = getNodeAt(index);
return node ? node->content.is<T>() : false;
}
// Creates a JsonArray and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
JsonArray &createNestedArray();
// Creates a JsonObject and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
JsonObject &createNestedObject();
// Removes element at specified index.
void removeAt(size_t index) {
removeNode(getNodeAt(index));
}
// Returns a reference an invalid JsonArray.
// This object is meant to replace a NULL pointer.
// This is used when memory allocation or JSON parsing fail.
static JsonArray &invalid() {
static JsonArray instance(NULL);
return instance;
}
// Serialize the array to the specified JsonWriter.
void writeTo(Internals::JsonWriter &writer) const {
writer.beginArray();
const node_type *child = _firstNode;
while (child) {
child->content.writeTo(writer);
child = child->next;
if (!child) break;
writer.writeComma();
}
writer.endArray();
}
// Imports a 1D array
template <typename T, size_t N>
bool copyFrom(T(&array)[N]) {
return copyFrom(array, N);
}
// Imports a 1D array
template <typename T>
bool copyFrom(T *array, size_t len) {
bool ok = true;
for (size_t i = 0; i < len; i++) {
ok &= add(array[i]);
}
return ok;
}
// Imports a 2D array
template <typename T, size_t N1, size_t N2>
bool copyFrom(T(&array)[N1][N2]) {
bool ok = true;
for (size_t i = 0; i < N1; i++) {
JsonArray &nestedArray = createNestedArray();
for (size_t j = 0; j < N2; j++) {
ok &= nestedArray.add(array[i][j]);
}
}
return ok;
}
// Exports a 1D array
template <typename T, size_t N>
size_t copyTo(T(&array)[N]) const {
return copyTo(array, N);
}
// Exports a 1D array
template <typename T>
size_t copyTo(T *array, size_t len) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < len; ++it)
array[i++] = *it;
return i;
}
// Exports a 2D array
template <typename T, size_t N1, size_t N2>
void copyTo(T(&array)[N1][N2]) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
it->asArray().copyTo(array[i++]);
}
}
private:
node_type *getNodeAt(size_t index) const {
node_type *node = _firstNode;
while (node && index--) node = node->next;
return node;
}
template <typename TValue>
bool setNodeAt(size_t index, TValue value) {
node_type *node = getNodeAt(index);
return node != NULL && setNodeValue<TValue>(node, value);
}
template <typename TValue>
bool addNode(TValue value) {
node_type *node = addNewNode();
return node != NULL && setNodeValue<TValue>(node, value);
}
template <typename T>
bool setNodeValue(node_type *node, T value) {
node->content = value;
return true;
}
};
}

View File

@ -1,52 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonArray.hpp"
#include "JsonObject.hpp"
#include "JsonArraySubscript.hpp"
namespace ArduinoJson {
template <>
inline bool JsonArray::setNodeValue(node_type *node, String &value) {
const char *copy = _buffer->strdup(value);
if (!copy) return false;
node->content = copy;
return true;
}
template <>
inline JsonArray &JsonVariant::defaultValue<JsonArray &>() {
return JsonArray::invalid();
}
template <>
inline JsonArray const &JsonVariant::defaultValue<JsonArray const &>() {
return JsonArray::invalid();
}
inline JsonArray &JsonVariant::asArray() const {
if (_type == Internals::JSON_ARRAY) return *_content.asArray;
return JsonArray::invalid();
}
inline JsonArray &JsonArray::createNestedArray() {
if (!_buffer) return JsonArray::invalid();
JsonArray &array = _buffer->createArray();
add(array);
return array;
}
inline JsonArray &JsonObject::createNestedArray(JsonObjectKey key) {
if (!_buffer) return JsonArray::invalid();
JsonArray &array = _buffer->createArray();
setNodeAt<const JsonVariant &>(key, array);
return array;
}
}

View File

@ -1,94 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#include "JsonVariantBase.hpp"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4522)
#endif
namespace ArduinoJson {
class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
public:
FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index)
: _array(array), _index(index) {}
JsonArraySubscript& operator=(const JsonArraySubscript& src) {
_array.set<const JsonVariant&>(_index, src);
return *this;
}
template <typename T>
typename TypeTraits::EnableIf<JsonArray::CanSet<T&>::value,
JsonArraySubscript>::type&
operator=(const T& src) {
_array.set<T&>(_index, const_cast<T&>(src));
return *this;
}
template <typename T>
typename TypeTraits::EnableIf<JsonArray::CanSet<T>::value,
JsonArraySubscript>::type&
operator=(T src) {
_array.set<T>(_index, src);
return *this;
}
FORCE_INLINE bool success() const { return _index < _array.size(); }
FORCE_INLINE operator JsonVariant() const { return _array.get(_index); }
template <typename T>
FORCE_INLINE T as() const {
return _array.get<T>(_index);
}
template <typename T>
FORCE_INLINE bool is() const {
return _array.is<T>(_index);
}
void writeTo(Internals::JsonWriter& writer) const {
_array.get(_index).writeTo(writer);
}
template <typename TValue>
void set(TValue value) {
_array.set(_index, value);
}
private:
JsonArray& _array;
const size_t _index;
};
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(std::ostream& os,
const JsonArraySubscript& source) {
return source.printTo(os);
}
#endif
inline JsonArraySubscript JsonArray::operator[](size_t index) {
return JsonArraySubscript(*this, index);
}
template <typename TImplem>
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
int index) const {
return asArray()[index];
}
} // namespace ArduinoJson
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View File

@ -1,163 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include <stddef.h> // for size_t
#include <stdint.h> // for uint8_t
#include <string.h>
#include "JsonVariant.hpp"
#include "String.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;
// Entry point for using the library.
//
// 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 {
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
// allocation fails.
JsonArray &createArray();
// Allocates an empty JsonObject.
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
JsonObject &createObject();
// Allocates and populate a JsonArray from a JSON string.
//
// The First argument is a pointer to the JSON string, the memory must be
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
JsonArray &parseArray(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
// Same with a const char*.
// With this overload, the JsonBuffer will make a copy of the string
JsonArray &parseArray(const char *json, uint8_t nesting = DEFAULT_LIMIT) {
return parseArray(strdup(json), nesting);
}
// Same as above with a String class
JsonArray &parseArray(const String &json, uint8_t nesting = DEFAULT_LIMIT) {
return parseArray(json.c_str(), nesting);
}
// Allocates and populate a JsonObject from a JSON string.
//
// The First argument is a pointer to the JSON string, the memory must be
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
JsonObject &parseObject(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
// Same with a const char*.
// With this overload, the JsonBuffer will make a copy of the string
JsonObject &parseObject(const char *json, uint8_t nesting = DEFAULT_LIMIT) {
return parseObject(strdup(json), nesting);
}
// Same as above with a String class
JsonObject &parseObject(const String &json, uint8_t nesting = DEFAULT_LIMIT) {
return parseObject(json.c_str(), nesting);
}
// Generalized version of parseArray() and parseObject(), also works for
// integral types.
JsonVariant parse(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
// Same with a const char*.
// With this overload, the JsonBuffer will make a copy of the string
JsonVariant parse(const char *json, uint8_t nesting = DEFAULT_LIMIT) {
return parse(strdup(json), nesting);
}
// Same as above with a String class
JsonVariant parse(const String &json, uint8_t nesting = DEFAULT_LIMIT) {
return parse(json.c_str(), nesting);
}
// Duplicate a string
char *strdup(const char *src) {
return src ? strdup(src, strlen(src)) : NULL;
}
char *strdup(const String &src) { return strdup(src.c_str(), src.length()); }
// Allocates n bytes in the JsonBuffer.
// Return a pointer to the allocated memory or NULL if allocation fails.
virtual void *alloc(size_t size) = 0;
protected:
// Preserve aligment if nessary
static FORCE_INLINE size_t round_size_up(size_t bytes) {
#if ARDUINOJSON_ENABLE_ALIGNMENT
const size_t x = sizeof(void *) - 1;
return (bytes + x) & ~x;
#else
return bytes;
#endif
}
private:
char *strdup(const char *, size_t);
// Default value of nesting limit of parseArray() and parseObject().
//
// The nesting limit is a contain on the level of nesting allowed in the
// JSON
// string.
// If set to 0, only a flat array or objects can be parsed.
// If set to 1, the object can contain nested arrays or objects but only 1
// level deep.
// And bigger values will allow more level of nesting.
//
// The purpose of this feature is to prevent stack overflow that could
// lead to
// a security risk.
static const uint8_t DEFAULT_LIMIT = 10;
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -1,46 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/JsonParser.hpp"
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() {
JsonArray *ptr = new (this) JsonArray(this);
return ptr ? *ptr : JsonArray::invalid();
}
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() {
JsonObject *ptr = new (this) JsonObject(this);
return ptr ? *ptr : JsonObject::invalid();
}
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::parseArray(
char *json, uint8_t nestingLimit) {
Internals::JsonParser parser(this, json, nestingLimit);
return parser.parseArray();
}
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::parseObject(
char *json, uint8_t nestingLimit) {
Internals::JsonParser parser(this, json, nestingLimit);
return parser.parseObject();
}
inline ArduinoJson::JsonVariant ArduinoJson::JsonBuffer::parse(
char *json, uint8_t nestingLimit) {
Internals::JsonParser parser(this, json, nestingLimit);
return parser.parseVariant();
}
inline char *ArduinoJson::JsonBuffer::strdup(const char *source,
size_t length) {
size_t size = length + 1;
char *dest = static_cast<char *>(alloc(size));
if (dest != NULL) memcpy(dest, source, size);
return dest;
}

View File

@ -1,201 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "String.hpp"
#include "Internals/JsonBufferAllocated.hpp"
#include "Internals/JsonPrintable.hpp"
#include "Internals/List.hpp"
#include "Internals/ReferenceType.hpp"
#include "JsonPair.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsReference.hpp"
#include "TypeTraits/IsSame.hpp"
// Returns the size (in bytes) of an object with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonObject) + (NUMBER_OF_ELEMENTS) * sizeof(JsonObject::node_type))
namespace ArduinoJson {
// Forward declarations
class JsonArray;
class JsonBuffer;
// A dictionary of JsonVariant indexed by string (char*)
//
// The constructor is private, instances must be created via
// JsonBuffer::createObject() or JsonBuffer::parseObject().
// A JsonObject can be serialized to a JSON string via JsonObject::printTo().
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
class JsonObject : public Internals::JsonPrintable<JsonObject>,
public Internals::ReferenceType,
public Internals::List<JsonPair>,
public Internals::JsonBufferAllocated {
public:
// A meta-function that returns true if type T can be used in
// JsonObject::set()
template <typename T>
struct CanSet {
static const bool value = JsonVariant::IsConstructibleFrom<T>::value ||
TypeTraits::IsSame<T, String&>::value ||
TypeTraits::IsSame<T, const String&>::value;
};
// 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) {}
// Gets or sets the value associated with the specified key.
JsonObjectSubscript<const char*> operator[](const char* key);
JsonObjectSubscript<const String&> operator[](const String& key);
// Gets the value associated with the specified key.
JsonVariant operator[](JsonObjectKey key) const {
return get(key);
}
// Sets the specified key with the specified value.
// bool set(TKey key, bool value);
// bool set(TKey key, char value);
// bool set(TKey key, long value);
// bool set(TKey key, int value);
// bool set(TKey key, short value);
// bool set(TKey key, float value);
// bool set(TKey key, double value);
// bool set(TKey key, const char* value);
// bool set(TKey key, RawJson value);
template <typename T>
bool set(
JsonObjectKey key, T value,
typename TypeTraits::EnableIf<
CanSet<T>::value && !TypeTraits::IsReference<T>::value>::type* = 0) {
return setNodeAt<T>(key, value);
}
// bool set(Key, String&);
// bool set(Key, JsonArray&);
// bool set(Key, JsonObject&);
// bool set(Key, JsonVariant&);
template <typename T>
bool set(JsonObjectKey key, const T& value,
typename TypeTraits::EnableIf<CanSet<T&>::value>::type* = 0) {
return setNodeAt<T&>(key, const_cast<T&>(value));
}
// bool set(Key, float value, uint8_t decimals);
// bool set(Key, double value, uint8_t decimals);
template <typename TValue>
bool set(JsonObjectKey key, TValue value, uint8_t decimals,
typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<TValue>::value>::type* = 0) {
return setNodeAt<const JsonVariant&>(key, JsonVariant(value, decimals));
}
// Gets the value associated with the specified key.
JsonVariant get(JsonObjectKey key) const {
node_type* node = getNodeAt(key.c_str());
return node ? node->content.value : JsonVariant();
}
// Gets the value associated with the specified key.
template <typename T>
T get(JsonObjectKey key) const {
node_type* node = getNodeAt(key.c_str());
return node ? node->content.value.as<T>() : JsonVariant::defaultValue<T>();
}
// Checks the type of the value associated with the specified key.
template <typename T>
bool is(JsonObjectKey key) const {
node_type* node = getNodeAt(key.c_str());
return node ? node->content.value.is<T>() : false;
}
// Creates and adds a JsonArray.
// This is a shortcut for JsonBuffer::createArray() and JsonObject::add().
JsonArray& createNestedArray(JsonObjectKey key);
// Creates and adds a JsonObject.
// This is a shortcut for JsonBuffer::createObject() and JsonObject::add().
JsonObject& createNestedObject(JsonObjectKey key);
// Tells weither the specified key is present and associated with a value.
bool containsKey(JsonObjectKey key) const {
return getNodeAt(key.c_str()) != NULL;
}
// Removes the specified key and the associated value.
void remove(JsonObjectKey key) {
removeNode(getNodeAt(key.c_str()));
}
// Returns a reference an invalid JsonObject.
// This object is meant to replace a NULL pointer.
// This is used when memory allocation or JSON parsing fail.
static JsonObject& invalid() {
static JsonObject instance(NULL);
return instance;
}
// Serialize the object to the specified JsonWriter
void writeTo(Internals::JsonWriter& writer) const {
writer.beginObject();
const node_type* node = _firstNode;
while (node) {
writer.writeString(node->content.key);
writer.writeColon();
node->content.value.writeTo(writer);
node = node->next;
if (!node) break;
writer.writeComma();
}
writer.endObject();
}
private:
// Returns the list node that matches the specified key.
node_type* getNodeAt(const char* key) const {
for (node_type* node = _firstNode; node; node = node->next) {
if (!strcmp(node->content.key, key)) return node;
}
return NULL;
}
template <typename T>
bool setNodeAt(JsonObjectKey key, T value) {
node_type* node = getNodeAt(key.c_str());
if (!node) {
node = addNewNode();
if (!node || !setNodeKey(node, key)) return false;
}
return setNodeValue<T>(node, value);
}
bool setNodeKey(node_type* node, JsonObjectKey key) {
if (key.needs_copy()) {
node->content.key = _buffer->strdup(key.c_str());
if (node->content.key == NULL) return false;
} else {
node->content.key = key.c_str();
}
return true;
}
template <typename T>
bool setNodeValue(node_type* node, T value) {
node->content.value = value;
return true;
}
};
}

View File

@ -1,56 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonArray.hpp"
#include "JsonObject.hpp"
#include "JsonObjectSubscript.hpp"
namespace ArduinoJson {
template <>
inline bool JsonObject::setNodeValue(node_type *node, String &value) {
node->content.value = _buffer->strdup(value);
return node->content.value;
}
template <>
inline bool JsonObject::setNodeValue(node_type *node, const String &value) {
node->content.value = _buffer->strdup(value);
return node->content.value;
}
template <>
inline JsonObject const &JsonVariant::defaultValue<JsonObject const &>() {
return JsonObject::invalid();
}
template <>
inline JsonObject &JsonVariant::defaultValue<JsonObject &>() {
return JsonObject::invalid();
}
inline JsonObject &JsonVariant::asObject() const {
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
return JsonObject::invalid();
}
inline JsonObject &JsonObject::createNestedObject(JsonObjectKey key) {
if (!_buffer) return JsonObject::invalid();
JsonObject &array = _buffer->createObject();
setNodeAt<const JsonVariant &>(key, array);
return array;
}
inline JsonObject &JsonArray::createNestedObject() {
if (!_buffer) return JsonObject::invalid();
JsonObject &object = _buffer->createObject();
add(object);
return object;
}
}

View File

@ -1,27 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "String.hpp"
namespace ArduinoJson {
// Represents a key in a JsonObject
class JsonObjectKey {
public:
JsonObjectKey(const char* key) : _value(key), _needs_copy(false) {}
JsonObjectKey(const String& key) : _value(key.c_str()), _needs_copy(true) {}
const char* c_str() const { return _value; }
bool needs_copy() const { return _needs_copy; }
private:
const char* _value;
bool _needs_copy;
};
}

View File

@ -1,127 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#include "JsonVariantBase.hpp"
#include "TypeTraits/EnableIf.hpp"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4522)
#endif
namespace ArduinoJson {
template <typename TKey>
class JsonObjectSubscript : public JsonVariantBase<JsonObjectSubscript<TKey> > {
public:
FORCE_INLINE JsonObjectSubscript(JsonObject& object, TKey key)
: _object(object), _key(key) {}
JsonObjectSubscript<TKey>& operator=(const JsonObjectSubscript<TKey>& src) {
_object.set<const JsonVariant&>(_key, src);
return *this;
}
template <typename T>
typename TypeTraits::EnableIf<JsonObject::CanSet<T&>::value,
JsonObjectSubscript<TKey> >::type&
operator=(const T& src) {
_object.set<T&>(_key, const_cast<T&>(src));
return *this;
}
template <typename T>
typename TypeTraits::EnableIf<JsonObject::CanSet<T>::value,
JsonObjectSubscript<TKey> >::type&
operator=(T src) {
_object.set<T>(_key, src);
return *this;
}
FORCE_INLINE bool success() const {
return _object.containsKey(_key);
}
FORCE_INLINE operator JsonVariant() const {
return _object.get(_key);
}
template <typename TValue>
FORCE_INLINE TValue as() const {
return _object.get<TValue>(_key);
}
template <typename TValue>
FORCE_INLINE bool is() const {
return _object.is<TValue>(_key);
}
template <typename TValue>
FORCE_INLINE bool set(TValue value) {
return _object.set<TValue>(_key, value);
}
template <typename TValue>
FORCE_INLINE bool set(TValue value, uint8_t decimals) {
return _object.set(_key, value, decimals);
}
FORCE_INLINE JsonVariant get() {
return _object.get(_key);
}
void writeTo(Internals::JsonWriter& writer) const {
_object.get(_key).writeTo(writer);
}
private:
JsonObject& _object;
TKey _key;
};
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(
std::ostream& os, const JsonObjectSubscript<const String&>& source) {
return source.printTo(os);
}
inline std::ostream& operator<<(
std::ostream& os, const JsonObjectSubscript<const char*>& source) {
return source.printTo(os);
}
#endif
inline JsonObjectSubscript<const char*> JsonObject::operator[](
const char* key) {
return JsonObjectSubscript<const char*>(*this, key);
}
inline JsonObjectSubscript<const String&> JsonObject::operator[](
const String& key) {
return JsonObjectSubscript<const String&>(*this, key);
}
template <typename TImplem>
inline const JsonObjectSubscript<const char*> JsonVariantBase<TImplem>::
operator[](const char* key) const {
return asObject()[key];
}
template <typename TImplem>
inline const JsonObjectSubscript<const String&> JsonVariantBase<TImplem>::
operator[](const String& key) const {
return asObject()[key];
}
} // namespace ArduinoJson
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View File

@ -1,180 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#include "JsonVariant.hpp"
#include "Internals/Parse.hpp"
#include "JsonArray.hpp"
#include "JsonObject.hpp"
#include <string.h> // for strcmp
#include <errno.h> // for errno
#include <stdlib.h> // for strtol, strtod
namespace ArduinoJson {
inline Internals::JsonInteger JsonVariant::asInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return _content.asInteger;
case JSON_NEGATIVE_INTEGER:
return -static_cast<Internals::JsonInteger>(_content.asInteger);
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonInteger>(_content.asString);
default:
return static_cast<Internals::JsonInteger>(_content.asFloat);
}
}
inline Internals::JsonUInt JsonVariant::asUnsignedInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
case JSON_NEGATIVE_INTEGER:
return _content.asInteger;
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonUInt>(_content.asString);
default:
return static_cast<Internals::JsonUInt>(_content.asFloat);
}
}
inline const char *JsonVariant::asString() const {
using namespace Internals;
if (_type == JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString))
return NULL;
if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString;
return NULL;
}
inline Internals::JsonFloat JsonVariant::asFloat() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return static_cast<JsonFloat>(_content.asInteger);
case JSON_NEGATIVE_INTEGER:
return -static_cast<JsonFloat>(_content.asInteger);
case JSON_STRING:
case JSON_UNPARSED:
return _content.asString ? parse<JsonFloat>(_content.asString) : 0;
default:
return _content.asFloat;
}
}
inline String JsonVariant::toString() const {
using namespace Internals;
String s;
if ((_type == JSON_STRING || _type == JSON_UNPARSED) &&
_content.asString != NULL)
s = _content.asString;
else
printTo(s);
return s;
}
inline bool JsonVariant::isBoolean() const {
using namespace Internals;
if (_type == JSON_BOOLEAN) return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
return !strcmp(_content.asString, "true") ||
!strcmp(_content.asString, "false");
}
inline bool JsonVariant::isInteger() const {
using namespace Internals;
if (_type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER)
return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtol(_content.asString, &end, 10);
return *end == '\0' && errno == 0;
}
inline bool JsonVariant::isFloat() const {
using namespace Internals;
if (_type >= JSON_FLOAT_0_DECIMALS) return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtod(_content.asString, &end);
return *end == '\0' && errno == 0 && !is<long>();
}
inline void JsonVariant::writeTo(Internals::JsonWriter &writer) const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return;
case JSON_ARRAY:
_content.asArray->writeTo(writer);
return;
case JSON_OBJECT:
_content.asObject->writeTo(writer);
return;
case JSON_STRING:
writer.writeString(_content.asString);
return;
case JSON_UNPARSED:
writer.writeRaw(_content.asString);
return;
case JSON_NEGATIVE_INTEGER:
writer.writeRaw('-');
case JSON_POSITIVE_INTEGER:
writer.writeInteger(_content.asInteger);
return;
case JSON_BOOLEAN:
writer.writeBoolean(_content.asInteger != 0);
return;
default:
uint8_t decimals = static_cast<uint8_t>(_type - JSON_FLOAT_0_DECIMALS);
writer.writeFloat(_content.asFloat, decimals);
}
}
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
return source.printTo(os);
}
#endif
} // namespace ArduinoJson

View File

@ -1,133 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Polyfills/attributes.hpp"
#include "JsonObjectKey.hpp"
namespace ArduinoJson {
// Forward declarations.
class JsonArraySubscript;
template <typename TKey>
class JsonObjectSubscript;
template <typename TImpl>
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
public:
FORCE_INLINE const char *asString() const { return as<const char *>(); }
// 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 &>(); }
FORCE_INLINE JsonArray &asArray() 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 &>(); }
FORCE_INLINE JsonObject &asObject() const { return as<JsonObject &>(); }
template <typename T>
FORCE_INLINE operator T() const {
return as<T>();
}
template <typename T>
FORCE_INLINE const T as() const {
return impl()->template as<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 asArray().size() + asObject().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[](int index) const;
// 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.
FORCE_INLINE const JsonObjectSubscript<const char *> operator[](
const char *key) const;
FORCE_INLINE const JsonObjectSubscript<const String &> operator[](
const String &key) const;
// Serialize the variant to a JsonWriter
void writeTo(Internals::JsonWriter &writer) const;
private:
const TImpl *impl() const { return static_cast<const TImpl *>(this); }
};
template <typename TImpl, typename TComparand>
inline bool operator==(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() == right;
}
template <typename TImpl, typename TComparand>
inline bool operator==(TComparand left, const JsonVariantBase<TImpl> &right) {
return left == right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator!=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() != right;
}
template <typename TImpl, typename TComparand>
inline bool operator!=(TComparand left, const JsonVariantBase<TImpl> &right) {
return left != right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator<=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() <= right;
}
template <typename TImpl, typename TComparand>
inline bool operator<=(TComparand left, const JsonVariantBase<TImpl> &right) {
return left <= right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() >= right;
}
template <typename TImpl, typename TComparand>
inline bool operator>=(TComparand left, const JsonVariantBase<TImpl> &right) {
return left >= right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator<(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() < right;
}
template <typename TImpl, typename TComparand>
inline bool operator<(TComparand left, const JsonVariantBase<TImpl> &right) {
return left < right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() > right;
}
template <typename TImpl, typename TComparand>
inline bool operator>(TComparand left, const JsonVariantBase<TImpl> &right) {
return left > right.template as<TComparand>();
}
}

View File

@ -1,16 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifdef _MSC_VER
#define FORCE_INLINE __forceinline
#define NO_INLINE __declspec(noinline)
#else
#define FORCE_INLINE __attribute__((always_inline))
#define NO_INLINE __attribute__((noinline))
#endif

View File

@ -1,65 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
// If Visual Studo <= 2012
#if defined(_MSC_VER) && _MSC_VER <= 1700
#include <float.h>
#else
#include <math.h>
#endif
// GCC warning: "conversion to 'float' from 'double' may alter its value"
#ifdef __GNUC__
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
#pragma GCC diagnostic ignored "-Wfloat-conversion"
#else
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#endif
namespace ArduinoJson {
namespace Polyfills {
// If Visual Studo <= 2012
#if defined(_MSC_VER) && _MSC_VER <= 1700
template <typename T>
bool isInfinity(T x) {
return !_finite(x);
}
#else
template <typename T>
bool isInfinity(T x) {
return isinf(x);
}
#if defined(_GLIBCXX_HAVE_ISINFL) && _GLIBCXX_HAVE_ISINFL
template <>
inline bool isInfinity<double>(double x) {
return isinfl(x);
}
#endif
#if defined(_GLIBCXX_HAVE_ISINFF) && _GLIBCXX_HAVE_ISINFF
template <>
inline bool isInfinity<float>(float x) {
return isinff(x);
}
#endif
#endif
}
}
#if defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -1,54 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
// If Visual Studo <= 2012
#if defined(_MSC_VER) && _MSC_VER <= 1700
#include <float.h>
#else
#include <math.h>
#endif
// GCC warning: "conversion to 'float' from 'double' may alter its value"
#ifdef __GNUC__
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
#pragma GCC diagnostic ignored "-Wfloat-conversion"
#else
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#endif
namespace ArduinoJson {
namespace Polyfills {
// If Visual Studo <= 2012
#if defined(_MSC_VER) && _MSC_VER <= 1700
template <typename T>
bool isNaN(T x) {
return _isnan(x) != 0;
}
#else
template <typename T>
bool isNaN(T x) {
return isnan(x);
}
#endif
}
}
#if defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -1,47 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Polyfills {
#ifdef ARDUINO
// on embedded platform, favor code size over speed
template <typename T>
short normalize(T& value) {
short powersOf10 = 0;
while (value && value < 1) {
powersOf10--;
value *= 10;
}
while (value > 10) {
powersOf10++;
value /= 10;
}
return powersOf10;
}
#else
// on non-embedded platform, favor speed over code size
template <typename T>
short normalize(T& value) {
if (value == 0.0) return 0;
short powersOf10 = static_cast<short>(floor(log10(value)));
value /= pow(T(10), powersOf10);
return powersOf10;
}
#endif
}
}

View File

@ -1,39 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifndef ARDUINO
#include <stddef.h>
#include <stdint.h>
namespace ArduinoJson {
// This class reproduces Arduino's Print class
class Print {
public:
virtual ~Print() {}
virtual size_t write(uint8_t) = 0;
size_t print(const char* s) {
size_t n = 0;
while (*s) {
n += write(*s++);
}
return n;
}
size_t println() { return write('\r') + write('\n'); }
};
}
#else
#include <Print.h>
#endif

View File

@ -1,58 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonBuffer.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 {
// 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 JsonBuffer {
public:
explicit StaticJsonBuffer() : _size(0) {}
size_t capacity() const {
return CAPACITY;
}
size_t size() const {
return _size;
}
virtual void* alloc(size_t bytes) {
if (_size + bytes > CAPACITY) return NULL;
void* p = &_buffer[_size];
_size += round_size_up(bytes);
return p;
}
private:
uint8_t _buffer[CAPACITY];
size_t _size;
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -1,24 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#if ARDUINOJSON_USE_ARDUINO_STRING
#include <WString.h>
#else
#include <string>
namespace ArduinoJson {
typedef std::string String;
}
#endif

View File

@ -2,6 +2,7 @@ JsonArray KEYWORD1
JsonObject KEYWORD1
JsonVariant KEYWORD1
StaticJsonBuffer KEYWORD1
DynamicJsonBuffer KEYWORD1
add KEYWORD2
createArray KEYWORD2
createNestedArray KEYWORD2

View File

@ -1,19 +1,19 @@
{
"name": "Json",
"name": "ArduinoJson",
"keywords": "json, rest, http, web",
"description": "An elegant and efficient JSON library for embedded systems",
"repository": {
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "5.6.1",
"version": "5.10.0",
"authors": {
"name": "Benoit Blanchon",
"url": "http://blog.benoitblanchon.fr"
"url": "https://blog.benoitblanchon.fr"
},
"exclude": [
"fuzzing",
"scripts",
"src/ArduinoJson.h",
"test",
"third-party"
],

View File

@ -1,9 +1,9 @@
name=ArduinoJson
version=5.6.1
version=5.10.0
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!
category=Data Processing
url=https://github.com/bblanchon/ArduinoJson
url=https://bblanchon.github.io/ArduinoJson/
architectures=*

View File

@ -12,7 +12,7 @@ rm -f $OUTPUT
7z a $OUTPUT \
ArduinoJson/CHANGELOG.md \
ArduinoJson/examples \
ArduinoJson/include \
ArduinoJson/src \
ArduinoJson/keywords.txt \
ArduinoJson/library.properties \
ArduinoJson/LICENSE.md \

View File

@ -0,0 +1,53 @@
#!/bin/bash
TAG=$(git describe)
RE_INCLUDE='^#include[[:space:]]*["<](.*)[">]'
RE_EMPTY='^(#pragma[[:space:]]+once)?[[:space:]]*(//.*)?$'
declare -A INCLUDED
process()
{
local PARENT=$1
local FOLDER=$(dirname $1)
local SHOW_COMMENT=$2
while IFS= read -r LINE; do
if [[ $LINE =~ $RE_INCLUDE ]]; then
local CHILD=${BASH_REMATCH[1]}
pushd "$FOLDER" > /dev/null
if [[ -e $CHILD ]]; then
local CHILD_PATH=$(realpath $CHILD)
if [[ ! ${INCLUDED[$CHILD_PATH]} ]]; then
#echo "// $PARENT -> $CHILD"
INCLUDED[$CHILD_PATH]=true
process "$CHILD" false
fi
else
if [[ ! ${INCLUDED[$CHILD]} ]]; then
echo "$LINE"
INCLUDED[$CHILD]=true
fi
fi
popd > /dev/null
elif [[ "${SHOW_COMMENT}" = "true" ]] ; then
echo "$LINE"
elif [[ ! $LINE =~ $RE_EMPTY ]]; then
echo "$LINE"
fi
done < $PARENT
}
cd $(dirname $0)/../
INCLUDED=()
process src/ArduinoJson.h true > ../ArduinoJson-$TAG.h
g++ -x c++ -c -o ../smoketest.o - <<END
#include "../ArduinoJson-$TAG.h"
int main() {}
END
INCLUDED=()
process src/ArduinoJson.hpp true > ../ArduinoJson-$TAG.hpp
g++ -x c++ -c -o ../smoketest.o - <<END
#include "../ArduinoJson-$TAG.hpp"
int main() {}
END

View File

@ -1,5 +0,0 @@
CPPLINT="python third-party/cpplint/cpplint.py"
FLAGS="--filter=-runtime/printf,-runtime/int,-readability/todo,-build/namespace,-runtime/references,-readability/streams"
cd ..
$CPPLINT $FLAGS $(find include src test -regex ".*\.[hc]pp$")

View File

@ -1,7 +0,0 @@
cd ..
FILES=$(find include src test -regex ".*\.[ch]pp$")
clang-format -style=Google -i $FILES
# insert newline at end of file
sed -i -e '$a\' $FILES

2
scripts/oss-fuzz/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/.vagrant/
*.log

33
scripts/oss-fuzz/Vagrantfile vendored Normal file
View File

@ -0,0 +1,33 @@
# A virtual machine to run https://github.com/google/oss-fuzz
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.synced_folder "E:\\Git\\Arduino\\libraries\\ArduinoJson", "/host/ArduinoJson"
config.vm.synced_folder "E:\\Git\\oss-fuzz", "/host/oss-fuzz"
config.vm.network "forwarded_port", guest: 8001, host: 8001
config.vm.provision "shell", privileged: false, inline: <<-SHELL
set -x
sudo apt-get update
sudo apt-get install -y make git docker.io zip
sudo groupadd docker
sudo usermod -aG docker $USER
git clone https://github.com/google/fuzzer-test-suite.git FTS
./FTS/tutorial/install-deps.sh # Get deps
./FTS/tutorial/install-clang.sh # Get fresh clang binaries
# Get libFuzzer sources and build it
svn co http://llvm.org/svn/llvm-project/llvm/trunk/lib/Fuzzer
Fuzzer/build.sh
sudo mv libFuzzer.a /usr/local/lib/
echo "export PROJECT_NAME='arduinojson'" >> $HOME/.profile
echo "export CC='clang'" >> $HOME/.profile
echo "export CXX='clang++'" >> $HOME/.profile
echo "export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/" >> $HOME/.profile
echo "Run /host/ArduinoJson/fuzzing/fuzz.sh" | sudo tee /etc/motd
SHELL
end

View File

@ -1,44 +0,0 @@
#!/bin/bash
FILE=../bin/ArduinoJsonTests.exe
MD5=""
file_changed() {
[[ ! -f "$FILE" ]] && return 1
NEW_MD5=$(md5sum $FILE)
[[ "$MD5" == "$NEW_MD5" ]] && return 1
MD5=$NEW_MD5
return 0
}
test_succeed() {
echo -en "\007"{,}
}
test_failed() {
echo -en "\007"{,,,,,,,,,,,}
}
run_tests() {
$FILE
case $? in
0)
test_succeed
;;
1)
test_failed
;;
esac
}
while true
do
if file_changed
then
run_tests
else
sleep 2
fi
done

View File

@ -1,9 +0,0 @@
#!/bin/sh -eux
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Darwin-x86_64.tar.gz
curl -sS $URL | tar xz -C /tmp --strip 1
/tmp/CMake.app/Contents/bin/cmake .
make
make test

View File

@ -1,9 +1,30 @@
#!/bin/sh -eux
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Linux-x86_64.tar.gz
#!/bin/sh -ex
if [ $(uname) = 'Darwin' ]; then
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Darwin-x86_64.tar.gz
CMAKE=/tmp/CMake.app/Contents/bin/cmake
CTEST=/tmp/CMake.app/Contents/bin/ctest
else
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Linux-x86_64.tar.gz
CMAKE=/tmp/bin/cmake
CTEST=/tmp/bin/ctest
fi
curl -sS $URL | tar xz -C /tmp --strip 1
/tmp/bin/cmake -DCMAKE_CXX_COMPILER=$CMAKE_CXX_COMPILER .
make
make test
if [ -n "$GCC" ]; then
export CC="gcc-$GCC"
export CXX="g++-$GCC"
fi
if [ -n "$CLANG" ]; then
export CC="clang-$CLANG"
export CXX="clang++-$CLANG"
fi
if [ -n "$SANITIZE" ]; then
export CXXFLAGS="-fsanitize=$SANITIZE"
fi
$CMAKE .
$CMAKE --build .
$CTEST --output-on-failure .

View File

@ -6,5 +6,5 @@ curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /t
make
make test
pip install --user cpp-coveralls
pip install --user cpp-coveralls 'requests[security]'
coveralls --exclude third-party --gcov-options '\-lp'; fi

View File

@ -4,7 +4,7 @@ pip install --user platformio
rm -r test
for EXAMPLE in JsonParserExample JsonGeneratorExample
for EXAMPLE in $PWD/examples/*/*.ino;
do
platformio ci examples/$EXAMPLE/$EXAMPLE.ino -l '.' -b $BOARD
platformio ci $EXAMPLE -l '.' -b $BOARD
done

View File

@ -1,9 +1,12 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "ArduinoJson.hpp"
using namespace ArduinoJson;

21
src/ArduinoJson.hpp Normal file
View File

@ -0,0 +1,21 @@
// 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 "ArduinoJson/DynamicJsonBuffer.hpp"
#include "ArduinoJson/JsonArray.hpp"
#include "ArduinoJson/JsonObject.hpp"
#include "ArduinoJson/JsonVariantComparisons.hpp"
#include "ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson/Deserialization/JsonParserImpl.hpp"
#include "ArduinoJson/JsonArrayImpl.hpp"
#include "ArduinoJson/JsonBufferImpl.hpp"
#include "ArduinoJson/JsonObjectImpl.hpp"
#include "ArduinoJson/JsonVariantImpl.hpp"
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"

View File

@ -0,0 +1,148 @@
// 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
// enable deprecated functions by default
#ifndef ARDUINOJSON_ENABLE_DEPRECATED
#define ARDUINOJSON_ENABLE_DEPRECATED 1
#endif
// control the exponentiation threshold for big numbers
// CAUTION: cannot be more that 1e9 !!!!
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
#define ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD 1e7
#endif
// control the exponentiation threshold for small numbers
#ifndef ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD
#define ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD 1e-5
#endif
#ifdef ARDUINO // assume this is an embedded platform
// store using float instead of double to reduce the memory usage (issue #134)
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 0
#endif
// store using a long because it usually match the size of a float.
#ifndef ARDUINOJSON_USE_LONG_LONG
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#ifndef ARDUINOJSON_USE_INT64
#define ARDUINOJSON_USE_INT64 0
#endif
// Arduino has its own implementation of String to replace std::string
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#endif
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
#endif
// On AVR archiecture, we can use PROGMEM
#ifndef ARDUINOJSON_ENABLE_PROGMEM
#ifdef PROGMEM
#define ARDUINOJSON_ENABLE_PROGMEM 1
#else
#define ARDUINOJSON_ENABLE_PROGMEM 0
#endif
#endif
// Arduino doesn't have std::string
#ifndef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 0
#endif
// Arduino doesn't support STL stream
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 0
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
#ifdef ARDUINO_ARCH_AVR
// alignment isn't needed for 8-bit AVR
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#else
// but must processor needs pointer to be align on word size
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
#endif
// low value to prevent stack overflow
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
#endif
#else // assume this is a computer
// on a computer we have plenty of memory so we can use doubles
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 1
#endif
// use long long when available
#ifndef ARDUINOJSON_USE_LONG_LONG
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define ARDUINOJSON_USE_LONG_LONG 1
#else
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#endif
// use _int64 on old versions of Visual Studio
#ifndef ARDUINOJSON_USE_INT64
#if defined(_MSC_VER) && _MSC_VER <= 1700
#define ARDUINOJSON_USE_INT64 1
#else
#define ARDUINOJSON_USE_INT64 0
#endif
#endif
// on a computer, we can use std::string
#ifndef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 1
#endif
// on a computer, there is no reason to beleive Arduino String is available
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#endif
// PROGMEM is only available on AVR architecture
#ifndef ARDUINOJSON_ENABLE_PROGMEM
#define ARDUINOJSON_ENABLE_PROGMEM 0
#endif
// on a computer, we can assume that the STL is there
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 1
#endif
// on a computer, there is no reason to beleive Arduino Stream is available
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
// even if not required, most cpu's are faster with aligned pointers
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
// on a computer, we should have a lot of space on the stack
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
#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,14 +1,12 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {

View File

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

View File

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

View File

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

View File

@ -0,0 +1,45 @@
// 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
namespace ArduinoJson {
namespace Internals {
// A metafunction that returns the type of the value returned by
// JsonVariant::as<T>()
template <typename T>
struct JsonVariantAs {
typedef T type;
};
template <>
struct JsonVariantAs<char*> {
typedef const char* type;
};
template <>
struct JsonVariantAs<JsonArray> {
typedef JsonArray& type;
};
template <>
struct JsonVariantAs<const JsonArray> {
typedef const JsonArray& type;
};
template <>
struct JsonVariantAs<JsonObject> {
typedef JsonObject& type;
};
template <>
struct JsonVariantAs<const JsonObject> {
typedef const JsonObject& type;
};
}
}

View File

@ -0,0 +1,69 @@
// 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,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -0,0 +1,26 @@
// 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
namespace ArduinoJson {
namespace Internals {
template <typename T>
struct JsonVariantDefault {
static T get() {
return T();
}
};
template <typename T>
struct JsonVariantDefault<const T> : JsonVariantDefault<T> {};
template <typename T>
struct JsonVariantDefault<T&> : JsonVariantDefault<T> {};
}
}

View File

@ -1,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -20,20 +20,11 @@ enum JsonVariantType {
JSON_UNPARSED, // JsonVariant contains an unparsed string
JSON_STRING, // JsonVariant stores a const char*
JSON_BOOLEAN, // JsonVariant stores a bool
JSON_POSITIVE_INTEGER, // JsonVariant stores an unsigned long
JSON_NEGATIVE_INTEGER, // JsonVariant stores an unsigned long that must be
// negated
JSON_POSITIVE_INTEGER, // JsonVariant stores an JsonUInt
JSON_NEGATIVE_INTEGER, // JsonVariant stores an JsonUInt that must be negated
JSON_ARRAY, // JsonVariant stores a pointer to a JsonArray
JSON_OBJECT, // JsonVariant stores a pointer to a JsonObject
// The following values are reserved for float values
// Multiple values are used for double, depending on the number of decimal
// digits that must be printed in the JSON output.
// This little trick allow to save one extra member in JsonVariant
JSON_FLOAT_0_DECIMALS
// JSON_FLOAT_1_DECIMAL
// JSON_FLOAT_2_DECIMALS
// ...
JSON_FLOAT // JsonVariant stores a JsonFloat
};
}
}

View File

@ -1,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -48,6 +48,20 @@ class List {
return nodeCount;
}
iterator add() {
node_type *newNode = new (_buffer) node_type();
if (_firstNode) {
node_type *lastNode = _firstNode;
while (lastNode->next) lastNode = lastNode->next;
lastNode->next = newNode;
} else {
_firstNode = newNode;
}
return iterator(newNode);
}
iterator begin() {
return iterator(_firstNode);
}
@ -62,22 +76,8 @@ class List {
return const_iterator(NULL);
}
protected:
node_type *addNewNode() {
node_type *newNode = new (_buffer) node_type();
if (_firstNode) {
node_type *lastNode = _firstNode;
while (lastNode->next) lastNode = lastNode->next;
lastNode->next = newNode;
} else {
_firstNode = newNode;
}
return newNode;
}
void removeNode(node_type *nodeToRemove) {
void remove(iterator it) {
node_type *nodeToRemove = it._node;
if (!nodeToRemove) return;
if (nodeToRemove == _firstNode) {
_firstNode = nodeToRemove->next;
@ -87,7 +87,10 @@ class List {
}
}
protected:
JsonBuffer *_buffer;
private:
node_type *_firstNode;
};
}

View File

@ -1,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -18,8 +18,12 @@ class ListConstIterator {
public:
explicit ListConstIterator(const ListNode<T> *node = NULL) : _node(node) {}
const T &operator*() const { return _node->content; }
const T *operator->() { return &_node->content; }
const T &operator*() const {
return _node->content;
}
const T *operator->() {
return &_node->content;
}
bool operator==(const ListConstIterator<T> &other) const {
return _node == other._node;
@ -34,6 +38,14 @@ class ListConstIterator {
return *this;
}
ListConstIterator<T> &operator+=(size_t distance) {
while (_node && distance) {
_node = _node->next;
--distance;
}
return *this;
}
private:
const ListNode<T> *_node;
};

View File

@ -1,26 +1,35 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "ListNode.hpp"
#include "ListConstIterator.hpp"
#include "ListNode.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename T>
class List;
// A read-write forward iterator for List<T>
template <typename T>
class ListIterator {
friend class List<T>;
public:
explicit ListIterator(ListNode<T> *node = NULL) : _node(node) {}
T &operator*() const { return _node->content; }
T *operator->() { return &_node->content; }
T &operator*() const {
return _node->content;
}
T *operator->() {
return &_node->content;
}
bool operator==(const ListIterator<T> &other) const {
return _node == other._node;
@ -35,7 +44,17 @@ class ListIterator {
return *this;
}
operator ListConstIterator<T>() const { return ListConstIterator<T>(_node); }
ListIterator<T> &operator+=(size_t distance) {
while (_node && distance) {
_node = _node->next;
--distance;
}
return *this;
}
operator ListConstIterator<T>() const {
return ListConstIterator<T>(_node);
}
private:
ListNode<T> *_node;

View File

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

View File

@ -1,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -19,7 +19,9 @@ class ReferenceType {
return this == &other;
}
bool operator!=(const ReferenceType& other) const { return this != &other; }
bool operator!=(const ReferenceType& other) const {
return this != &other;
}
protected:
ReferenceType() {}

View File

@ -0,0 +1,51 @@
// 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

@ -0,0 +1,64 @@
// 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
namespace ArduinoJson {
namespace Internals {
template <typename TInput>
void skipSpacesAndComments(TInput& input) {
for (;;) {
switch (input.current()) {
// spaces
case ' ':
case '\t':
case '\r':
case '\n':
input.move();
continue;
// comments
case '/':
switch (input.next()) {
// C-style block comment
case '*':
input.move(); // skip '/'
// no need to skip '*'
for (;;) {
input.move();
if (input.current() == '\0') return;
if (input.current() == '*' && input.next() == '/') {
input.move(); // skip '*'
input.move(); // skip '/'
break;
}
}
break;
// C++-style line comment
case '/':
// not need to skip "//"
for (;;) {
input.move();
if (input.current() == '\0') return;
if (input.current() == '\n') break;
}
break;
// not a comment, just a '/'
default:
return;
}
break;
default:
return;
}
}
}
}
}

View File

@ -0,0 +1,107 @@
// 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 "../TypeTraits/IsConst.hpp"
#include "StringWriter.hpp"
namespace ArduinoJson {
namespace Internals {
// Parse JSON string to create JsonArrays and JsonObjects
// This internal class is not indended to be used directly.
// Instead, use JsonBuffer.parseArray() or .parseObject()
template <typename TReader, typename TWriter>
class JsonParser {
public:
JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer,
uint8_t nestingLimit)
: _buffer(buffer),
_reader(reader),
_writer(writer),
_nestingLimit(nestingLimit) {}
JsonArray &parseArray();
JsonObject &parseObject();
JsonVariant parseVariant() {
JsonVariant result;
parseAnythingTo(&result);
return result;
}
private:
JsonParser &operator=(const JsonParser &); // non-copiable
static bool eat(TReader &, char charToSkip);
FORCE_INLINE bool eat(char charToSkip) {
return eat(_reader, charToSkip);
}
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) {
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 isQuote(char c) {
return c == '\'' || c == '\"';
}
JsonBuffer *_buffer;
TReader _reader;
TWriter _writer;
uint8_t _nestingLimit;
};
template <typename TJsonBuffer, typename TString, typename Enable = void>
struct JsonParserBuilder {
typedef typename Internals::StringTraits<TString>::Reader InputReader;
typedef JsonParser<InputReader, TJsonBuffer &> TParser;
static TParser makeParser(TJsonBuffer *buffer, TString &json,
uint8_t nestingLimit) {
return TParser(buffer, InputReader(json), *buffer, nestingLimit);
}
};
template <typename TJsonBuffer, typename TChar>
struct JsonParserBuilder<
TJsonBuffer, TChar *,
typename TypeTraits::EnableIf<!TypeTraits::IsConst<TChar>::value>::type> {
typedef typename Internals::StringTraits<TChar *>::Reader TReader;
typedef StringWriter<TChar> TWriter;
typedef JsonParser<TReader, TWriter> TParser;
static TParser makeParser(TJsonBuffer *buffer, TChar *json,
uint8_t nestingLimit) {
return TParser(buffer, TReader(json), TWriter(json), nestingLimit);
}
};
template <typename TJsonBuffer, typename TString>
inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser(
TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) {
return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json,
nestingLimit);
}
}
}

View File

@ -1,8 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -10,15 +10,18 @@
#include "Comments.hpp"
#include "JsonParser.hpp"
inline bool ArduinoJson::Internals::JsonParser::skip(char charToSkip) {
const char *ptr = skipSpacesAndComments(_readPtr);
if (*ptr != charToSkip) return false;
ptr++;
_readPtr = skipSpacesAndComments(ptr);
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat(
TReader &reader, char charToSkip) {
skipSpacesAndComments(reader);
if (reader.current() != charToSkip) return false;
reader.move();
return true;
}
inline bool ArduinoJson::Internals::JsonParser::parseAnythingTo(
template <typename TReader, typename TWriter>
inline bool
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
JsonVariant *destination) {
if (_nestingLimit == 0) return false;
_nestingLimit--;
@ -27,11 +30,13 @@ inline bool ArduinoJson::Internals::JsonParser::parseAnythingTo(
return success;
}
inline bool ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe(
template <typename TReader, typename TWriter>
inline bool
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
JsonVariant *destination) {
_readPtr = skipSpacesAndComments(_readPtr);
skipSpacesAndComments(_reader);
switch (*_readPtr) {
switch (_reader.current()) {
case '[':
return parseArrayTo(destination);
@ -43,14 +48,15 @@ inline bool ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe(
}
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonArray &
ArduinoJson::Internals::JsonParser::parseArray() {
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
// Create an empty array
JsonArray &array = _buffer->createArray();
// Check opening braket
if (!skip('[')) goto ERROR_MISSING_BRACKET;
if (skip(']')) goto SUCCESS_EMPTY_ARRAY;
if (!eat('[')) goto ERROR_MISSING_BRACKET;
if (eat(']')) goto SUCCESS_EMPTY_ARRAY;
// Read each value
for (;;) {
@ -60,8 +66,8 @@ ArduinoJson::Internals::JsonParser::parseArray() {
if (!array.add(value)) goto ERROR_NO_MEMORY;
// 2 - More values?
if (skip(']')) goto SUCCES_NON_EMPTY_ARRAY;
if (!skip(',')) goto ERROR_MISSING_COMMA;
if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY;
if (!eat(',')) goto ERROR_MISSING_COMMA;
}
SUCCESS_EMPTY_ARRAY:
@ -75,7 +81,8 @@ ERROR_NO_MEMORY:
return JsonArray::invalid();
}
inline bool ArduinoJson::Internals::JsonParser::parseArrayTo(
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
JsonVariant *destination) {
JsonArray &array = parseArray();
if (!array.success()) return false;
@ -84,21 +91,22 @@ inline bool ArduinoJson::Internals::JsonParser::parseArrayTo(
return true;
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonObject &
ArduinoJson::Internals::JsonParser::parseObject() {
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
// Create an empty object
JsonObject &object = _buffer->createObject();
// Check opening brace
if (!skip('{')) goto ERROR_MISSING_BRACE;
if (skip('}')) goto SUCCESS_EMPTY_OBJECT;
if (!eat('{')) goto ERROR_MISSING_BRACE;
if (eat('}')) goto SUCCESS_EMPTY_OBJECT;
// Read each key value pair
for (;;) {
// 1 - Parse key
const char *key = parseString();
if (!key) goto ERROR_INVALID_KEY;
if (!skip(':')) goto ERROR_MISSING_COLON;
if (!eat(':')) goto ERROR_MISSING_COLON;
// 2 - Parse value
JsonVariant value;
@ -106,8 +114,8 @@ ArduinoJson::Internals::JsonParser::parseObject() {
if (!object.set(key, value)) goto ERROR_NO_MEMORY;
// 3 - More keys/values?
if (skip('}')) goto SUCCESS_NON_EMPTY_OBJECT;
if (!skip(',')) goto ERROR_MISSING_COMMA;
if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT;
if (!eat(',')) goto ERROR_MISSING_COMMA;
}
SUCCESS_EMPTY_OBJECT:
@ -123,7 +131,8 @@ ERROR_NO_MEMORY:
return JsonObject::invalid();
}
inline bool ArduinoJson::Internals::JsonParser::parseObjectTo(
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo(
JsonVariant *destination) {
JsonObject &object = parseObject();
if (!object.success()) return false;
@ -132,54 +141,50 @@ inline bool ArduinoJson::Internals::JsonParser::parseObjectTo(
return true;
}
inline const char *ArduinoJson::Internals::JsonParser::parseString() {
const char *readPtr = _readPtr;
char *writePtr = _writePtr;
template <typename TReader, typename TWriter>
inline const char *
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
typename TypeTraits::RemoveReference<TWriter>::type::String str =
_writer.startString();
char c = *readPtr;
skipSpacesAndComments(_reader);
char c = _reader.current();
if (isQuote(c)) { // quotes
_reader.move();
char stopChar = c;
for (;;) {
c = *++readPtr;
c = _reader.current();
if (c == '\0') break;
_reader.move();
if (c == stopChar) {
readPtr++;
break;
}
if (c == stopChar) break;
if (c == '\\') {
// replace char
c = Encoding::unescapeChar(*++readPtr);
c = Encoding::unescapeChar(_reader.current());
if (c == '\0') break;
_reader.move();
}
*writePtr++ = c;
str.append(c);
}
} else { // no quotes
for (;;) {
if (!isLetterOrNumber(c)) break;
*writePtr++ = c;
c = *++readPtr;
_reader.move();
str.append(c);
c = _reader.current();
}
}
// end the string here
*writePtr++ = '\0';
const char *startPtr = _writePtr;
// update end ptr
_readPtr = readPtr;
_writePtr = writePtr;
// return pointer to unquoted string
return startPtr;
return str.c_str();
}
inline bool ArduinoJson::Internals::JsonParser::parseStringTo(
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseStringTo(
JsonVariant *destination) {
bool hasQuotes = isQuote(_readPtr[0]);
bool hasQuotes = isQuote(_reader.current());
const char *value = parseString();
if (value == NULL) return false;
if (hasQuotes) {

View File

@ -0,0 +1,44 @@
// 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
namespace ArduinoJson {
namespace Internals {
template <typename TChar>
class StringWriter {
public:
class String {
public:
String(TChar** ptr) : _writePtr(ptr), _startPtr(*ptr) {}
void append(TChar c) {
*(*_writePtr)++ = c;
}
const char* c_str() const {
*(*_writePtr)++ = 0;
return reinterpret_cast<const char*>(_startPtr);
}
private:
TChar** _writePtr;
TChar* _startPtr;
};
StringWriter(TChar* buffer) : _ptr(buffer) {}
String startString() {
return String(&_ptr);
}
private:
TChar* _ptr;
};
}
}

View File

@ -1,13 +1,13 @@
// Copyright Benoit Blanchon 2014-2016
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include "JsonBufferBase.hpp"
#include <stdlib.h>
@ -22,7 +22,6 @@
#endif
namespace ArduinoJson {
namespace Internals {
class DefaultAllocator {
public:
void* allocate(size_t size) {
@ -34,7 +33,8 @@ class DefaultAllocator {
};
template <typename TAllocator>
class BlockJsonBuffer : public JsonBuffer {
class DynamicJsonBufferBase
: public JsonBufferBase<DynamicJsonBufferBase<TAllocator> > {
struct Block;
struct EmptyBlock {
Block* next;
@ -46,10 +46,10 @@ class BlockJsonBuffer : public JsonBuffer {
};
public:
BlockJsonBuffer(size_t initialSize = 256)
: _head(NULL), _nextBlockSize(initialSize) {}
DynamicJsonBufferBase(size_t initialSize = 256)
: _head(NULL), _nextBlockCapacity(initialSize) {}
~BlockJsonBuffer() {
~DynamicJsonBufferBase() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
@ -66,25 +66,65 @@ class BlockJsonBuffer : public JsonBuffer {
}
virtual void* alloc(size_t bytes) {
alignNextAlloc();
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
}
class String {
public:
String(DynamicJsonBufferBase* parent)
: _parent(parent), _start(NULL), _length(0) {}
void append(char c) {
if (_parent->canAllocInHead(1)) {
char* end = static_cast<char*>(_parent->allocInHead(1));
*end = c;
if (_length == 0) _start = end;
} else {
char* newStart =
static_cast<char*>(_parent->allocInNewBlock(_length + 1));
if (_start && newStart) memcpy(newStart, _start, _length);
if (newStart) newStart[_length] = c;
_start = newStart;
}
_length++;
}
const char* c_str() {
append(0);
return _start;
}
private:
DynamicJsonBufferBase* _parent;
char* _start;
int _length;
};
String startString() {
return String(this);
}
private:
void alignNextAlloc() {
if (_head) _head->size = this->round_size_up(_head->size);
}
bool canAllocInHead(size_t bytes) const {
return _head != NULL && _head->size + bytes <= _head->capacity;
}
void* allocInHead(size_t bytes) {
void* p = _head->data + _head->size;
_head->size += round_size_up(bytes);
_head->size += bytes;
return p;
}
void* allocInNewBlock(size_t bytes) {
size_t capacity = _nextBlockSize;
size_t capacity = _nextBlockCapacity;
if (bytes > capacity) capacity = bytes;
if (!addNewBlock(capacity)) return NULL;
_nextBlockSize *= 2;
_nextBlockCapacity *= 2;
return allocInHead(bytes);
}
@ -101,10 +141,8 @@ class BlockJsonBuffer : public JsonBuffer {
TAllocator _allocator;
Block* _head;
size_t _nextBlockSize;
size_t _nextBlockCapacity;
};
}
}
#if defined(__clang__)
#pragma clang diagnostic pop
@ -113,3 +151,9 @@ class BlockJsonBuffer : public JsonBuffer {
#pragma GCC diagnostic pop
#endif
#endif
// 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;
}

View File

@ -0,0 +1,232 @@
// 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 "Data/JsonBufferAllocated.hpp"
#include "Data/List.hpp"
#include "Data/ReferenceType.hpp"
#include "Data/ValueSetter.hpp"
#include "JsonVariant.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsArray.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsSame.hpp"
// Returns the size (in bytes) of an array with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type))
namespace ArduinoJson {
// Forward declarations
class JsonObject;
class JsonBuffer;
class JsonArraySubscript;
// An array of JsonVariant.
//
// The constructor is private, instances must be created via
// JsonBuffer::createArray() or JsonBuffer::parseArray().
// A JsonArray can be serialized to a JSON string via JsonArray::printTo().
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
class JsonArray : public Internals::JsonPrintable<JsonArray>,
public Internals::ReferenceType,
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)
: Internals::List<JsonVariant>(buffer) {}
// Gets the value at the specified index
const JsonArraySubscript operator[](size_t index) const;
// Gets or sets the value at specified index
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&
template <typename T>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type add(
const T &value) {
return add_impl<const T &>(value);
}
//
// bool add(TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
template <typename T>
bool add(const T *value) {
return add_impl<const T *>(value);
}
//
// bool add(TValue value, uint8_t decimals);
// TValue = float, double
template <typename T>
DEPRECATED("Second argument is not supported anymore")
bool add(T value, uint8_t) {
return add_impl<const JsonVariant &>(JsonVariant(value));
}
// Sets the value at specified index.
//
// bool add(size_t index, TValue);
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
template <typename T>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type 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*
template <typename T>
bool set(size_t index, const T *value) {
return set_impl<const 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
set(size_t index, T value, uint8_t decimals) {
return set_impl<const JsonVariant &>(index, JsonVariant(value, decimals));
}
// Gets the value at the specified index.
template <typename T>
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
const_iterator it = begin() += index;
return it != end() ? it->as<T>() : Internals::JsonVariantDefault<T>::get();
}
// Check the type of the value at specified index.
template <typename T>
bool is(size_t index) const {
const_iterator it = begin() += index;
return it != end() ? it->is<T>() : false;
}
// Creates a JsonArray and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
JsonArray &createNestedArray();
// Creates a JsonObject and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
JsonObject &createNestedObject();
// Removes element at specified index.
void remove(size_t index) {
remove(begin() += index);
}
using Internals::List<JsonVariant>::remove;
// Returns a reference an invalid JsonArray.
// This object is meant to replace a NULL pointer.
// This is used when memory allocation or JSON parsing fail.
static JsonArray &invalid() {
static JsonArray instance(NULL);
return instance;
}
// Imports a 1D array
template <typename T, size_t N>
bool copyFrom(T (&array)[N]) {
return copyFrom(array, N);
}
// Imports a 1D array
template <typename T>
bool copyFrom(T *array, size_t len) {
bool ok = true;
for (size_t i = 0; i < len; i++) {
ok &= add(array[i]);
}
return ok;
}
// Imports a 2D array
template <typename T, size_t N1, size_t N2>
bool copyFrom(T (&array)[N1][N2]) {
bool ok = true;
for (size_t i = 0; i < N1; i++) {
JsonArray &nestedArray = createNestedArray();
for (size_t j = 0; j < N2; j++) {
ok &= nestedArray.add(array[i][j]);
}
}
return ok;
}
// Exports a 1D array
template <typename T, size_t N>
size_t copyTo(T (&array)[N]) const {
return copyTo(array, N);
}
// Exports a 1D array
template <typename T>
size_t copyTo(T *array, size_t len) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < len; ++it)
array[i++] = *it;
return i;
}
// Exports a 2D array
template <typename T, size_t N1, size_t N2>
void copyTo(T (&array)[N1][N2]) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
it->as<JsonArray>().copyTo(array[i++]);
}
}
#if ARDUINOJSON_ENABLE_DEPRECATED
DEPRECATED("use remove() instead")
FORCE_INLINE void removeAt(size_t index) {
return remove(index);
}
#endif
private:
template <typename TValueRef>
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);
}
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);
}
};
namespace Internals {
template <>
struct JsonVariantDefault<JsonArray> {
static JsonArray &get() {
return JsonArray::invalid();
}
};
}
}

View File

@ -0,0 +1,29 @@
// 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 "JsonArray.hpp"
#include "JsonArraySubscript.hpp"
#include "JsonObject.hpp"
namespace ArduinoJson {
inline JsonArray &JsonArray::createNestedArray() {
if (!_buffer) return JsonArray::invalid();
JsonArray &array = _buffer->createArray();
add(array);
return array;
}
inline JsonObject &JsonArray::createNestedObject() {
if (!_buffer) return JsonObject::invalid();
JsonObject &object = _buffer->createObject();
add(object);
return object;
}
}

View File

@ -0,0 +1,124 @@
// 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"
#include "JsonVariantBase.hpp"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4522)
#endif
namespace ArduinoJson {
class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
public:
FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index)
: _array(array), _index(index) {}
FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
_array.set(_index, src);
return *this;
}
// Replaces the value
//
// operator=(TValue)
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
template <typename T>
FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
_array.set(_index, src);
return *this;
}
//
// operator=(TValue)
// TValue = const char*, const char[N], const FlashStringHelper*
template <typename T>
FORCE_INLINE JsonArraySubscript& operator=(const T* src) {
_array.set(_index, src);
return *this;
}
FORCE_INLINE bool success() const {
return _index < _array.size();
}
template <typename T>
FORCE_INLINE typename Internals::JsonVariantAs<T>::type as() const {
return _array.get<T>(_index);
}
template <typename T>
FORCE_INLINE bool is() const {
return _array.is<T>(_index);
}
// Replaces the value
//
// bool set(TValue)
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const 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*
template <typename TValue>
FORCE_INLINE bool set(const TValue* value) {
return _array.set(_index, value);
}
//
// bool set(TValue, uint8_t decimals);
// TValue = float, double
template <typename TValue>
DEPRECATED("Second argument is not supported anymore")
FORCE_INLINE bool set(const TValue& value, uint8_t) {
return _array.set(_index, value);
}
private:
JsonArray& _array;
const size_t _index;
};
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(std::ostream& os,
const JsonArraySubscript& source) {
return source.printTo(os);
}
#endif
inline JsonArraySubscript JsonArray::operator[](size_t index) {
return 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[](int index) {
return as<JsonArray>()[index];
}
template <typename TImplem>
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
int index) const {
return as<JsonArray>()[index];
}
} // namespace ArduinoJson
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View File

@ -0,0 +1,97 @@
// 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 <stddef.h> // for size_t
#include <stdint.h> // for uint8_t
#include <string.h>
#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;
// Entry point for using the library.
//
// 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 {
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
// allocation fails.
JsonArray &createArray();
// Allocates an empty JsonObject.
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
JsonObject &createObject();
// Duplicates a string
//
// 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) {
return Internals::StringTraits<TString>::duplicate(src, this);
}
//
// char* strdup(TValue);
// TValue = const char*, const char[N], const FlashStringHelper*
template <typename TString>
char *strdup(const TString *src) {
return Internals::StringTraits<const TString *>::duplicate(src, this);
}
// Allocates n bytes in the JsonBuffer.
// Return a pointer to the allocated memory or NULL if allocation fails.
virtual void *alloc(size_t size) = 0;
protected:
// Preserve aligment if necessary
static FORCE_INLINE size_t round_size_up(size_t bytes) {
#if ARDUINOJSON_ENABLE_ALIGNMENT
const size_t x = sizeof(void *) - 1;
return (bytes + x) & ~x;
#else
return bytes;
#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

View File

@ -0,0 +1,143 @@
// 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 "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 {
template <typename TDerived>
class JsonBufferBase : public JsonBuffer {
public:
// Allocates and populate a JsonArray from a JSON string.
//
// The First argument is a pointer to the JSON string, the memory must be
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
// With this overload, the JsonBuffer will make a copy of the string
//
// JsonArray& parseArray(TString);
// TString = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonArray &>::type
parseArray(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseArray();
}
//
// JsonArray& parseArray(TString);
// TString = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonArray &parseArray(
TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseArray();
}
//
// JsonArray& parseArray(TString);
// TString = std::istream&, Stream&
template <typename TString>
JsonArray &parseArray(
TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseArray();
}
// Allocates and populate a JsonObject from a JSON string.
//
// The First argument is a pointer to the JSON string, the memory must be
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
//
// JsonObject& parseObject(TString);
// TString = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonObject &>::type
parseObject(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseObject();
}
//
// JsonObject& parseObject(TString);
// TString = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonObject &parseObject(
TString *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseObject();
}
//
// JsonObject& parseObject(TString);
// TString = std::istream&, Stream&
template <typename TString>
JsonObject &parseObject(
TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseObject();
}
// Generalized version of parseArray() and parseObject(), also works for
// integral types.
//
// JsonVariant parse(TString);
// TString = const std::string&, const String&
template <typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
JsonVariant>::type
parse(const TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
//
// JsonVariant parse(TString);
// TString = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonVariant parse(TString *json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
//
// JsonVariant parse(TString);
// TString = std::istream&, Stream&
template <typename TString>
JsonVariant parse(TString &json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
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

View File

@ -0,0 +1,20 @@
// 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 "Deserialization/JsonParser.hpp"
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() {
JsonArray *ptr = new (this) JsonArray(this);
return ptr ? *ptr : JsonArray::invalid();
}
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() {
JsonObject *ptr = new (this) JsonObject(this);
return ptr ? *ptr : JsonObject::invalid();
}

View File

@ -0,0 +1,349 @@
// 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 "Data/JsonBufferAllocated.hpp"
#include "Data/List.hpp"
#include "Data/ReferenceType.hpp"
#include "Data/ValueSetter.hpp"
#include "JsonPair.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsArray.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsSame.hpp"
// Returns the size (in bytes) of an object with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
(sizeof(JsonObject) + (NUMBER_OF_ELEMENTS) * sizeof(JsonObject::node_type))
namespace ArduinoJson {
// Forward declarations
class JsonArray;
class JsonBuffer;
// A dictionary of JsonVariant indexed by string (char*)
//
// The constructor is private, instances must be created via
// JsonBuffer::createObject() or JsonBuffer::parseObject().
// A JsonObject can be serialized to a JSON string via JsonObject::printTo().
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
class JsonObject : public Internals::JsonPrintable<JsonObject>,
public Internals::ReferenceType,
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) {}
// 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);
}
//
// JsonObjectSubscript operator[](TKey)
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonObjectSubscript<const TString*> operator[](const TString* key) {
return JsonObjectSubscript<const TString*>(*this, key);
}
// Gets the value associated with the specified key.
//
// 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 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);
}
// Sets the specified key with the specified value.
//
// 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&
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) {
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*
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(TKey, TValue);
// TKey = const char*, const char[N], const FlashStringHelper*
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
// const std::string&, const String&,
// const JsonArray&, const 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(TKey, TValue);
// TKey = const char*, const char[N], const FlashStringHelper*
// TValue = const char*, const char[N], 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(TKey, TValue, uint8_t decimals);
// TKey = const std::string&, const String&
// 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
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*
// 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));
}
// Gets the value associated with the specified key.
//
// TValue get<TValue>(TKey);
// TKey = const std::string&, const String&
// TValue = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<
!TypeTraits::IsArray<TString>::value,
typename Internals::JsonVariantAs<TValue>::type>::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 = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
template <typename TValue, typename TString>
typename Internals::JsonVariantAs<TValue>::type get(
const TString* key) const {
return get_impl<const TString*, TValue>(key);
}
// Checks the type of the value associated with the specified key.
//
//
// 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&
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
bool>::type
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*
// TValue = bool, char, long, int, short, float, double,
// const std::string&, const String&,
// const JsonArray&, const JsonObject&
template <typename TValue, typename TString>
bool is(const TString* key) const {
return is_impl<const TString*, TValue>(key);
}
// Creates and adds a JsonArray.
//
// 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) {
return createNestedArray_impl<const TString&>(key);
}
// JsonArray& createNestedArray(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonArray& createNestedArray(const TString* key) {
return createNestedArray_impl<const TString*>(key);
}
// Creates and adds a 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) {
return createNestedObject_impl<const TString&>(key);
}
//
// JsonObject& createNestedObject(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
JsonObject& createNestedObject(const TString* key) {
return createNestedObject_impl<const TString*>(key);
}
// Tells weither the specified key is present and associated with a value.
//
// 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 {
return findKey<const TString&>(key) != end();
}
//
// bool containsKey(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
bool containsKey(const TString* key) const {
return findKey<const TString*>(key) != end();
}
// Removes the specified key and the associated value.
//
// 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) {
remove(findKey<const TString&>(key));
}
//
// void remove(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
void remove(const TString* key) {
remove(findKey<const TString*>(key));
}
//
// void remove(iterator)
using Internals::List<JsonPair>::remove;
// Returns a reference an invalid JsonObject.
// This object is meant to replace a NULL pointer.
// This is used when memory allocation or JSON parsing fail.
static JsonObject& invalid() {
static JsonObject instance(NULL);
return instance;
}
private:
// Returns the list node that matches the specified key.
template <typename TStringRef>
iterator findKey(TStringRef key) {
iterator it;
for (it = begin(); it != end(); ++it) {
if (Internals::StringTraits<TStringRef>::equals(key, it->key)) break;
}
return it;
}
template <typename TStringRef>
const_iterator findKey(TStringRef key) const {
return const_cast<JsonObject*>(this)->findKey<TStringRef>(key);
}
template <typename TStringRef, typename TValue>
typename Internals::JsonVariantAs<TValue>::type get_impl(
TStringRef key) const {
const_iterator it = findKey<TStringRef>(key);
return it != end() ? it->value.as<TValue>()
: Internals::JsonVariantDefault<TValue>::get();
}
template <typename TStringRef, typename TValueRef>
bool set_impl(TStringRef key, TValueRef value) {
iterator it = findKey<TStringRef>(key);
if (it == end()) {
it = Internals::List<JsonPair>::add();
if (it == end()) return false;
bool key_ok =
Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key);
if (!key_ok) return false;
}
return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value);
}
template <typename TStringRef, typename TValue>
bool is_impl(TStringRef key) const {
const_iterator it = findKey<TStringRef>(key);
return it != end() ? it->value.is<TValue>() : false;
}
template <typename TStringRef>
JsonArray& createNestedArray_impl(TStringRef key);
template <typename TStringRef>
JsonObject& createNestedObject_impl(TStringRef key);
};
namespace Internals {
template <>
struct JsonVariantDefault<JsonObject> {
static JsonObject& get() {
return JsonObject::invalid();
}
};
}
}

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