Compare commits

..

77 Commits

Author SHA1 Message Date
b55e57a7cf Set version to 5.12.0 2017-12-11 17:50:18 +01:00
7626db624e Changed all link to point to HTTPS version 2017-12-11 17:26:50 +01:00
6d8329b255 Added an example that shows how to save and load a configuration file 2017-12-11 17:20:27 +01:00
461e30148c Reworked all examples 2017-12-11 15:19:28 +01:00
57d98e48f7 Added detection of Keil ARM Compiler (issue #629) 2017-12-05 21:24:28 +01:00
cf2babc598 Added detection of MPLAB XC compiler (issue #629) 2017-12-05 21:18:21 +01:00
d10277df31 Added a clear error message when compiled as C (issue #629) 2017-12-03 13:49:51 +01:00
d3a1203782 Added JsonVariant::operator| to return a default value 2017-11-29 09:49:40 +01:00
126f7ab819 Rewrote example JsonHttpClient.ino (fixes #600) 2017-11-13 16:17:44 +01:00
221c2861fc Changed all links to point to arduinojson.org 2017-11-07 20:42:50 +01:00
66667382e1 Added Alexander Wilms to the list of donators 2017-11-01 09:19:40 +01:00
a7e928d126 Set version to 5.11.2 2017-10-17 10:21:52 +02:00
591fe7e92b Fixed incorrect rounding for float values (fixes #588) 2017-10-17 10:19:21 +02:00
d6e61cbcda Added banner with the new logo 2017-10-16 10:21:44 +02:00
5825366fe4 Added Patrick Elliott to the list of donators 2017-10-07 16:33:53 +02:00
6df204cf40 Split CONTRIBUTING and SUPPORT 2017-10-03 13:01:47 +02:00
3f7e1db549 Added guidelines for contributing 2017-10-03 12:26:49 +02:00
a6091136b0 Fix GCC 7 warning 2017-09-27 11:13:45 +02:00
353bbd0e8c Fix GCC 4.8.5 warning 2017-09-27 09:45:48 +02:00
a428e125fa Travis: Added GCC 7 2017-09-27 09:29:08 +02:00
2e262b2689 Travis: Removed GCC 4.5 2017-09-27 09:29:08 +02:00
a2d055e408 Added Günther Jehle to the list of donators 2017-09-26 09:43:32 +02:00
57defe00ee Fixed DynamicJsonBuffer::clear() not resetting allocation size (fixes #561) 2017-08-30 21:51:10 +02:00
ac5a2676e7 Upgraded to Catch 1.9.7 2017-08-27 15:12:20 +02:00
ed98ea4e43 Implemented JsonVariant comparisons with template friends 2017-08-06 16:26:38 +02:00
729bf0afd2 Made JsonBuffer destructor protected 2017-07-18 22:00:06 +02:00
2ea7ea153c Set version to 5.11.1 2017-07-14 11:17:11 +02:00
2772e66064 Fixed warning "this statement may fall through" (issue #539) 2017-07-14 11:14:56 +02:00
d41f7a8165 Fixed too many decimals places in float serialization (issue #543) 2017-07-14 10:51:46 +02:00
abfd3997eb Fixed "constant exceeds range of float [-Woverflow]" (issue #544) 2017-07-09 15:24:58 +02:00
788c9be016 Removed dependency on PGM_P as Particle 0.6.2 doesn't define it (issue #546) 2017-07-07 23:04:42 +02:00
c3d7a79a83 Travis: Removed Arduino DUE on platformio (fatal error: Ethernet.h: No such file or directory) 2017-07-06 20:56:05 +02:00
1782348275 Added Charles Walker to the list of donators 2017-07-06 20:55:05 +02:00
edfe5c6622 Set version to 5.11.0 2017-06-25 15:11:57 +02:00
2b9492317b Added Charles Haynes to the list of donators 2017-06-22 21:56:41 +02:00
5da41edf6a Removed implementation of JsonBufferAllocated::delete. 2017-06-19 10:05:38 +02:00
476e5aaa86 Added DynamicJsonBuffer::clear() 2017-06-17 16:48:40 +02:00
789fa507b5 Added StaticJsonBuffer::clear() 2017-06-17 15:00:46 +02:00
508f936317 Made JsonBuffer non-copyable (PR #524 by @luisrayas3) 2017-06-17 14:17:01 +02:00
e9d88dda8e Set version to 5.10.1 2017-06-12 21:10:02 +02:00
ecceb71a1e AppVeyor: Added Visual Studio 2017 and restored MinGW 2017-06-07 11:15:22 +02:00
bff77abe6a Fixed reading "true" as a float (issue #516) 2017-06-03 16:22:26 +02:00
98413089f6 Added Google to the list of donators 2017-06-01 20:49:50 +02:00
a2446f6c68 Fixed compilation in IAR Embedded Workbench (issue #515) 2017-06-01 20:47:09 +02:00
c955049207 Fixed IntelliSense errors in Visual Micro (issue #483) 2017-05-28 15:33:03 +02:00
574c00c096 Added links to the ArduinoJson assistant (issue #513) 2017-05-27 15:32:12 +02:00
7415f206ea Reduced code size 2017-05-27 15:08:11 +02:00
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
450 changed files with 20263 additions and 152471 deletions

View File

@ -1,11 +1,14 @@
<!--
Thanks for using ArduinoJson :-)
Before opening an issue, please read the FAQ:
https://arduinojson.org/faq/
Before opening an issue, please make sure you've read these:
https://bblanchon.github.io/ArduinoJson/faq/
https://github.com/bblanchon/ArduinoJson/wiki/Avoiding-pitfalls
Please provide all the relevant information:
* good title
* short description of the problem
* target platform
* compiler model and version
* MVCE (https://stackoverflow.com/help/mcve)
* compiler output
Next, make sure you provide all the relevant information: platform, code snippet, and error messages.
Please be concise!
Good questions get fast answers!
-->

View File

@ -8,12 +8,6 @@ matrix:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.4']
env: SCRIPT=cmake GCC=4.4
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.5']
env: SCRIPT=cmake GCC=4.5
- compiler: gcc
addons:
apt:
@ -44,6 +38,18 @@ matrix:
sources: ['ubuntu-toolchain-r-test']
packages: ['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: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-7']
env: SCRIPT=cmake GCC=7
- compiler: clang
env: SCRIPT=cmake
- compiler: clang
@ -76,28 +82,14 @@ matrix:
osx_image: xcode6.4
compiler: clang
env: SCRIPT=cmake
- os: osx
osx_image: xcode7
compiler: clang
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.1
compiler: clang
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.2
compiler: clang
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.3
compiler: clang
env: SCRIPT=cmake SANITIZE=address
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.6.12 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
cache:
directories:
- "~/.platformio"

View File

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

View File

@ -1,6 +1,113 @@
ArduinoJson: change log
=======================
v5.12.0
-------
* Added `JsonVariant::operator|` to return a default value (see bellow)
* Added a clear error message when compiled as C instead of C++ (issue #629)
* Added detection of MPLAB XC compiler (issue #629)
* Added detection of Keil ARM Compiler (issue #629)
* Added an example that shows how to save and load a configuration file
* Reworked all other examples
> ### How to use the new feature?
>
> If you have a block like this:
>
> ```c++
> const char* ssid = root["ssid"];
> if (!ssid)
> ssid = "default ssid";
> ```
>
> You can simplify like that:
>
> ```c++
> const char* ssid = root["ssid"] | "default ssid";
> ```
v5.11.2
-------
* Fixed `DynamicJsonBuffer::clear()` not resetting allocation size (issue #561)
* Fixed incorrect rounding for float values (issue #588)
v5.11.1
-------
* Removed dependency on `PGM_P` as Particle 0.6.2 doesn't define it (issue #546)
* Fixed warning "dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]"
* Fixed warning "floating constant exceeds range of 'float' [-Woverflow]" (issue #544)
* Fixed warning "this statement may fall through" [-Wimplicit-fallthrough=] (issue #539)
* Removed `ARDUINOJSON_DOUBLE_IS_64BITS` as it became useless.
* Fixed too many decimals places in float serialization (issue #543)
v5.11.0
-------
* Made `JsonBuffer` non-copyable (PR #524 by @luisrayas3)
* Added `StaticJsonBuffer::clear()`
* Added `DynamicJsonBuffer::clear()`
v5.10.1
-------
* Fixed IntelliSense errors in Visual Micro (issue #483)
* Fixed compilation in IAR Embedded Workbench (issue #515)
* Fixed reading "true" as a float (issue #516)
* Added `ARDUINOJSON_DOUBLE_IS_64BITS`
* Added `ARDUINOJSON_EMBEDDED_MODE`
v5.10.0
-------
* Removed configurable number of decimal places (issues #288, #427 and #506)
* Changed exponentiation 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
------
@ -34,23 +141,23 @@ v5.8.0
* Added support for `Stream` (issue #300)
* Reduced memory consumption by not duplicating spaces and comments
**BREAKING CHANGES**:
`JsonBuffer::parseObject()` and `JsonBuffer::parseArray()` have been pulled down to the derived classes `DynamicJsonBuffer` and `StaticJsonBufferBase`.
This means that if you have code like:
```c++
void myFunction(JsonBuffer& jsonBuffer);
```
you need to replace it with one of the following:
```c++
void myFunction(DynamicJsonBuffer& jsonBuffer);
void myFunction(StaticJsonBufferBase& jsonBuffer);
template<typename TJsonBuffer> void myFunction(TJsonBuffer& jsonBuffer);
```
> ### BREAKING CHANGES :warning:
>
> `JsonBuffer::parseObject()` and `JsonBuffer::parseArray()` have been pulled down to the derived classes `DynamicJsonBuffer` and `StaticJsonBufferBase`.
>
> This means that if you have code like:
>
> ```c++
> void myFunction(JsonBuffer& jsonBuffer);
> ```
>
> you need to replace it with one of the following:
>
> ```c++
> void myFunction(DynamicJsonBuffer& jsonBuffer);
> void myFunction(StaticJsonBufferBase& jsonBuffer);
> template<typename TJsonBuffer> void myFunction(TJsonBuffer& jsonBuffer);
> ```
v5.7.3
------
@ -83,27 +190,26 @@ v5.7.0
* Added example `StringExample.ino` to show where `String` can be used
* Increased default nesting limit to 50 when compiled for a computer (issue #349)
**BREAKING CHANGES**:
The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
Old code:
```c++
#define ARDUINOJSON_USE_ARDUINO_STRING 0
JsonVariant value1 = myObject.get("myKey");
JsonVariant value2 = myArray.get(0);
```
New code:
```c++
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#define ARDUINOJSON_ENABLE_STD_STRING 1
JsonVariant value1 = myObject.get<JsonVariant>("myKey");
JsonVariant value2 = myArray.get<JsonVariant>(0);
```
> ### BREAKING CHANGES :warning:
>
> The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
>
> Old code:
>
> ```c++
> #define ARDUINOJSON_USE_ARDUINO_STRING 0
> JsonVariant value1 = myObject.get("myKey");
> JsonVariant value2 = myArray.get(0);
> ```
>
> New code:
>
> ```c++
> #define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
> #define ARDUINOJSON_ENABLE_STD_STRING 1
> JsonVariant value1 = myObject.get<JsonVariant>("myKey");
> JsonVariant value2 = myArray.get<JsonVariant>(0);
> ```
v5.6.7
------
@ -195,8 +301,9 @@ v5.1.0
* Added support of `long long` (issue #171)
* Moved all build settings to `ArduinoJson/Configuration.hpp`
**BREAKING CHANGE**:
If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
> ### BREAKING CHANGE :warning:
>
> If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
v5.0.8
------
@ -210,9 +317,10 @@ v5.0.7
* Made library easier to use from a CMake project: simply `add_subdirectory(ArduinoJson/src)`
* Changed `String` to be a `typedef` of `std::string` (issues #142 and #161)
**BREAKING CHANGES**:
- `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
- `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
> ### BREAKING CHANGES :warning:
>
> - `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
> - `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
v5.0.6
------
@ -266,10 +374,11 @@ v5.0.0
* Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66)
* Switched to new the library layout (requires Arduino 1.0.6 or above)
**BREAKING CHANGES**:
- `JsonObject::add()` was renamed to `set()`
- `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
- Number of digits of floating point value are now set with `double_with_n_digits()`
> ### BREAKING CHANGES :warning:
>
> - `JsonObject::add()` was renamed to `set()`
> - `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
> - Number of digits of floating point value are now set with `double_with_n_digits()`
**Personal note about the `String` class**:
Support of the `String` class has been added to the library because many people use it in their programs.
@ -322,106 +431,7 @@ v4.0
* Unified parser and generator API (issue #23)
* Updated library layout, now requires Arduino 1.0.6 or newer
**BREAKING CHANGE**: API changed significantly, see [Migrating code to the new API](https://github.com/bblanchon/ArduinoJson/wiki/Migrating-code-to-the-new-API).
> ### BREAKING CHANGES :warning:
>
> API changed significantly since v3, see [Migrating code to the new API](https://arduinojson.org/doc/migration/).
v3.4
----
* Fixed escaped char parsing (issue #16)
v3.3
----
* Added indented output for the JSON generator (issue #11), see example bellow.
* Added `IndentedPrint`, a decorator for `Print` to allow indented output
Example:
JsonOject<2> json;
json["key"] = "value";
json.prettyPrintTo(Serial);
v3.2
----
* Fixed a bug when adding nested object in `JsonArray` (bug introduced in v3.1).
v3.1
----
* Calling `Generator::JsonObject::add()` twice with the same `key` now replaces the `value`
* Added `Generator::JsonObject::operator[]`, see bellow the new API
* Added `Generator::JsonObject::remove()` (issue #9)
Old generator API:
JsonObject<3> root;
root.add("sensor", "gps");
root.add("time", 1351824120);
root.add("data", array);
New generator API:
JsonObject<3> root;
root["sensor"] = "gps";
root["time"] = 1351824120;
root["data"] = array;
v3.0
----
* New parser API, see bellow
* Renamed `JsonHashTable` into `JsonObject`
* Added iterators for `JsonArray` and `JsonObject` (issue #4)
Old parser API:
JsonHashTable root = parser.parseHashTable(json);
char* sensor = root.getString("sensor");
long time = root.getLong("time");
double latitude = root.getArray("data").getDouble(0);
double longitude = root.getArray("data").getDouble(1);
New parser API:
JsonObject root = parser.parse(json);
char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
v2.1
----
* Fixed case `#include "jsmn.cpp"` which caused an error in Linux (issue #6)
* Fixed a buffer overrun in JSON Parser (issue #5)
v2.0
----
* Added JSON encoding (issue #2)
* Renamed the library `ArduinoJsonParser` becomes `ArduinoJson`
**Breaking change**: you need to add the following line at the top of your program.
using namespace ArduinoJson::Parser;
v1.2
----
* Fixed error in JSON parser example (issue #1)
v1.1
----
* Example: changed `char* json` into `char[] json` so that the bytes are not write protected
* Fixed parsing bug when the JSON contains multi-dimensional arrays
v1.0
----
Initial release

View File

@ -1,21 +1,16 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2017
# MIT License
#
# Arduino JSON library
# https://github.com/bblanchon/ArduinoJson
# If you like this project, please add a star!
cmake_minimum_required(VERSION 3.0)
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)

11
CONTRIBUTING.md Normal file
View File

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

View File

@ -1,8 +1,10 @@
[![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)
![ArduinoJson's logo](banner.svg)
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 is able to work without any allocation on the heap (no malloc).
@ -23,20 +25,21 @@ Features
* Small footprint
* Header-only library
* MIT License
* [Comprehensive documentation](https://arduinojson.org)
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://bblanchon.github.io/ArduinoJson/faq/compilation-fails-device-crashes-nothing-on-serial-console)
* Intel Edison and Galileo
* WeMos boards: D1...
* Computers: Windows, Linux, OSX...
* PlatformIO
* Particle
* Energia
Quick start
-----------
@ -56,7 +59,9 @@ double latitude = root["data"][0];
double longitude = root["data"][1];
```
[See JsonParserExample.ino](examples/JsonParserExample/JsonParserExample.ino)
[See JsonParserExample.ino](https://arduinojson.org/example/parser/)
Use [ArduinoJson Assistant](https://arduinojson.org/assistant/) to compute the buffer size.
#### Encoding / Generating
@ -68,52 +73,27 @@ 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)
[See JsonGeneratorExample.ino](https://arduinojson.org/example/generator/)
Use [ArduinoJson Assistant](https://arduinojson.org/assistant/) to compute the buffer size.
Documentation
-------------
The documentation is available online in the [ArduinoJson wiki](https://github.com/bblanchon/ArduinoJson/wiki).
The documentation is available online in the [ArduinoJson Website](https://arduinojson.org/).
The [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) helps you get started with the library.
The [ArduinoJson Assistant](https://arduinojson.org/assistant/) helps you get started with the library.
Testimonials
------------
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 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.
[From GitHub user `sticilface`](https://github.com/bblanchon/ArduinoJson/issues/381#issuecomment-260203594):
> its a great lib:) and i use it in everything!
Donators
--------
@ -136,7 +116,16 @@ Special thanks to the following persons and companies who made generous donation
* 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'>
* Christoph Schmidt <img alt='Germany' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e9-1f1ea.svg' width='18' height='18'>
* OpenEVSE LLC <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Prokhoryatov Alexey <img alt='Russia' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f7-1f1fa.svg' width='18' height='18'>
* Google Inc. <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Charles Haynes <img alt='Australia' src='https://d1j8pt39hxlh3d.cloudfront.net/development/emojione/2.2/989/2546.svg' width='18' height='18'>
* Charles Walker <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Günther Jehle <img alt='Liechtenstein' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f1-1f1ee.svg' width='18' height='18'>
* Patrick Elliott
* Alexander Wilms <img alt='Germany' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e9-1f1ea.svg' width='18' height='18'>
---

27
SUPPORT.md Normal file
View File

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

View File

@ -1,13 +1,15 @@
version: 5.8.3.{build}
version: 5.12.0.{build}
environment:
matrix:
- CMAKE_GENERATOR: Visual Studio 14 2015
- CMAKE_GENERATOR: Visual Studio 12 2013
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
CMAKE_GENERATOR: Visual Studio 15 2017
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
CMAKE_GENERATOR: Visual Studio 14 2015
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2013
CMAKE_GENERATOR: Visual Studio 12 2013
- CMAKE_GENERATOR: Visual Studio 11 2012
- CMAKE_GENERATOR: Visual Studio 10 2010
# - 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
- CMAKE_GENERATOR: MinGW Makefiles
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
@ -15,4 +17,4 @@ before_build:
build_script:
- cmake --build . --config %CONFIGURATION%
test_script:
- ctest -V .
- ctest --output-on-failure .

367
banner.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -1,35 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// 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

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

View File

@ -1,29 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
// This example shows how to generate a JSON document with ArduinoJson.
#include <ArduinoJson.h>
void setup() {
// Initialize Serial port
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
while (!Serial) continue;
// Memory pool for JSON object tree.
//
// Inside the brackets, 200 is the size of the pool in bytes.
// If the JSON object is more complex, you need to increase that value.
// Don't forget to change this value to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity.
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer allocates memory on the stack, it can be
// replaced by DynamicJsonBuffer which allocates in the heap.
// It's simpler but less efficient.
//
// DynamicJsonBuffer jsonBuffer;
// DynamicJsonBuffer jsonBuffer(200);
// Create the root of the object tree.
//
@ -44,8 +42,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:
@ -68,3 +66,16 @@ void setup() {
void loop() {
// not used in this example
}
// See also
// --------
//
// The website arduinojson.org contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
// Please check it out at: https://arduinojson.org/
//
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
// It begins with a simple example, like the one above, and then adds more
// features like serializing directly to a file or an HTTP request.
// Please check it out at: https://leanpub.com/arduinojson/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,13 +1,13 @@
# CAUTION: this file is invoked by https://github.com/google/oss-fuzz
CXXFLAGS += -I../include
CXXFLAGS += -I../src
all: \
$(OUT)/json_fuzzer \
$(OUT)/json_fuzzer_seed_corpus.zip \
$(OUT)/json_fuzzer.options
$(OUT)/json_fuzzer: fuzzer.cpp
$(OUT)/json_fuzzer: fuzzer.cpp $(shell find ../src -type f)
$(CXX) $(CXXFLAGS) $< -o$@ $(LIB_FUZZING_ENGINE)
$(OUT)/json_fuzzer_seed_corpus.zip: seed_corpus/*

View File

@ -1,8 +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
./json_fuzzer my_corpus seed_corpus -max_len=1024 -timeout=10

View File

@ -18,6 +18,9 @@ class memstream : public std::istream {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
DynamicJsonBuffer jsonBuffer;
memstream json(data, size);
jsonBuffer.parse(json);
JsonVariant variant = jsonBuffer.parse(json);
if (variant.success()) {
variant.as<std::string>(); // <- serialize to JSON
}
return 0;
}

View File

@ -1,8 +0,0 @@
{
"sensor": "gps",
"time": 1351824120,
"data": [
48.75608,
2.302038
]
}

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,8 @@
[
"hello",
'hello',
hello,
{"hello":"world"},
{'hello':'world'},
{hello:world}
]

View File

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

View File

@ -1,69 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/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,66 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// 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,53 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// 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"
#include "../StringTraits/StringTraits.hpp"
#include "../TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TSource, typename Enable = void>
struct ValueSetter {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination,
const TSource& source) {
destination = source;
return true;
}
};
template <typename TSource>
struct ValueSetter<TSource, typename TypeTraits::EnableIf<StringTraits<
TSource>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer* buffer, TDestination& destination,
const TSource& source) {
const char* copy = buffer->strdup(source);
if (!copy) return false;
destination = copy;
return true;
}
};
template <typename TSource>
struct ValueSetter<TSource, typename TypeTraits::EnableIf<!StringTraits<
TSource>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination,
const TSource& source) {
// unsigned char* -> char*
destination = reinterpret_cast<const char*>(source);
return true;
}
};
}
}

View File

@ -1,88 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Data/JsonVariantComparer.hpp"
namespace ArduinoJson {
template <typename TVariant, typename TComparand>
inline bool operator==(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return Internals::JsonVariantComparer<TComparand>::equals(variant, comparand);
}
template <typename TVariant, typename TComparand>
inline typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator==(TComparand comparand, const JsonVariantBase<TVariant> &variant) {
return Internals::JsonVariantComparer<TComparand>::equals(variant, comparand);
}
template <typename TVariant, typename TComparand>
inline bool operator!=(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return !Internals::JsonVariantComparer<TComparand>::equals(variant,
comparand);
}
template <typename TVariant, typename TComparand>
inline typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator!=(TComparand comparand, const JsonVariantBase<TVariant> &variant) {
return !Internals::JsonVariantComparer<TComparand>::equals(variant,
comparand);
}
template <typename TVariant, typename TComparand>
inline bool operator<=(const JsonVariantBase<TVariant> &left,
TComparand right) {
return left.template as<TComparand>() <= right;
}
template <typename TVariant, typename TComparand>
inline bool operator<=(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand <= variant.template as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator>=(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return variant.template as<TComparand>() >= comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator>=(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand >= variant.template as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator<(const JsonVariantBase<TVariant> &varian,
TComparand comparand) {
return varian.template as<TComparand>() < comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator<(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand < variant.template as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator>(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return variant.template as<TComparand>() > comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator>(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand > variant.template as<TComparand>();
}
}

View File

@ -1,111 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// 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>
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
bool isNaN(T x) {
return _isnan(x) != 0;
}
template <typename T>
bool isInfinity(T x) {
return !_finite(x);
}
}
}
#else
#include <math.h>
// 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
// Workaround for libs that #undef isnan or isinf
// https://github.com/bblanchon/ArduinoJson/issues/284
#if !defined(isnan) || !defined(isinf)
namespace std {}
#endif
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
bool isNaN(T x) {
// Workaround for libs that #undef isnan
// https://github.com/bblanchon/ArduinoJson/issues/284
#ifndef isnan
using namespace std;
#endif
return isnan(x);
}
#if defined(_GLIBCXX_HAVE_ISNANL) && _GLIBCXX_HAVE_ISNANL
template <>
inline bool isNaN<double>(double x) {
return isnanl(x);
}
#endif
#if defined(_GLIBCXX_HAVE_ISNANF) && _GLIBCXX_HAVE_ISNANF
template <>
inline bool isNaN<float>(float x) {
return isnanf(x);
}
#endif
template <typename T>
bool isInfinity(T x) {
// Workaround for libs that #undef isinf
// https://github.com/bblanchon/ArduinoJson/issues/284
#ifndef isinf
using namespace std;
#endif
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
#if defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif
}
}
#endif

View File

@ -1,47 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// 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,44 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// 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(static_cast<uint8_t>(*s++));
}
return n;
}
size_t println() {
size_t n = 0;
n += write('\r');
n += write('\n');
return n;
}
};
}
#else
#include <Print.h>
#endif

View File

@ -1,33 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonWriter.hpp"
namespace ArduinoJson {
class JsonArray;
class JsonArraySubscript;
class JsonObject;
template <typename TKey>
class JsonObjectSubscript;
class JsonVariant;
namespace Internals {
class JsonSerializer {
public:
static void serialize(const JsonArray &, JsonWriter &);
static void serialize(const JsonArraySubscript &, JsonWriter &);
static void serialize(const JsonObject &, JsonWriter &);
template <typename TKey>
static void serialize(const JsonObjectSubscript<TKey> &, JsonWriter &);
static void serialize(const JsonVariant &, JsonWriter &);
};
}
}

View File

@ -1,37 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// 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

@ -6,14 +6,14 @@
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "5.8.3",
"version": "5.12.0",
"authors": {
"name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr"
},
"exclude": [
"fuzzing",
"scripts",
"src/ArduinoJson.h",
"test",
"third-party"
],

View File

@ -1,9 +1,9 @@
name=ArduinoJson
version=5.8.3
version=5.12.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!
paragraph=ArduinoJson supports ✔ serialization, ✔ deserialization, ✔ fixed allocation, ✔ zero-copy, ✔ streams, and more. It is the most popular Arduino library on GitHub ❤❤❤❤❤. Check out arduinojson.org for a comprehensive documentation.
category=Data Processing
url=https://github.com/bblanchon/ArduinoJson
url=https://arduinojson.org/
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

View File

@ -26,5 +26,8 @@ Vagrant.configure(2) do |config|
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

@ -27,4 +27,4 @@ fi
$CMAKE .
$CMAKE --build .
$CTEST -VV .
$CTEST --output-on-failure .

17
src/ArduinoJson.h Normal file
View File

@ -0,0 +1,17 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#ifdef __cplusplus
#include "ArduinoJson.hpp"
using namespace ArduinoJson;
#else
#error ArduinoJson requires a C++ compiler, please change file extension to .cc or .cpp
#endif

View File

@ -1,16 +1,12 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// 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/JsonVariantComparisons.hpp"
#include "ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson/Deserialization/JsonParserImpl.hpp"
@ -19,5 +15,3 @@
#include "ArduinoJson/JsonObjectImpl.hpp"
#include "ArduinoJson/JsonVariantImpl.hpp"
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"
using namespace ArduinoJson;

View File

@ -1,25 +1,27 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/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
// Small or big machine?
#ifndef ARDUINOJSON_EMBEDDED_MODE
#if defined(ARDUINO) || defined(__IAR_SYSTEMS_ICC__) || defined(__XC) || \
defined(__ARMCC_VERSION)
#define ARDUINOJSON_EMBEDDED_MODE 1
#else
#define ARDUINOJSON_EMBEDDED_MODE 0
#endif
#endif
#ifdef ARDUINO // assume this is an embedded platform
#if ARDUINOJSON_EMBEDDED_MODE
// store using float instead of double to reduce the memory usage (issue #134)
// Store floats by default 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.
// Store longs by default, because they usually match the size of a float.
#ifndef ARDUINOJSON_USE_LONG_LONG
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
@ -27,57 +29,29 @@
#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
// Embedded systems usually don't have std::string
#ifndef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 0
#endif
// Arduino doesn't support STL stream
// Embedded systems usually don't have std::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
// Limit nesting as the stack is likely to be small
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
#endif
#else // assume this is a computer
#else // ARDUINOJSON_EMBEDDED_MODE
// on a computer we have plenty of memory so we can use doubles
// On a computer we have plenty of memory so we can use doubles
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 1
#endif
// use long long when available
// 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
@ -86,7 +60,7 @@
#endif
#endif
// use _int64 on old versions of Visual Studio
// Use _int64 on old versions of Visual Studio
#ifndef ARDUINOJSON_USE_INT64
#if defined(_MSC_VER) && _MSC_VER <= 1700
#define ARDUINOJSON_USE_INT64 1
@ -95,41 +69,81 @@
#endif
#endif
// on a computer, we can use std::string
// 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
// On a computer, we can assume std::stream
#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
// On a computer, the stack is large so we can increase nesting limit
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
#endif
#endif // ARDUINOJSON_EMBEDDED_MODE
#ifdef ARDUINO
// Enable support for Arduino String
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#endif
// Enable support for Arduino Stream
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
#endif
#else // ARDUINO
// Disable support for Arduino String
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#endif
// Disable support for Arduino Stream
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
#endif
#endif // ARDUINO
#ifndef ARDUINOJSON_ENABLE_PROGMEM
#ifdef PROGMEM
#define ARDUINOJSON_ENABLE_PROGMEM 1
#else
#define ARDUINOJSON_ENABLE_PROGMEM 0
#endif
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
#ifdef ARDUINO_ARCH_AVR
// alignment isn't needed for 8-bit AVR
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#else
// but most processors need pointers to be align on word size
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
#endif
// 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
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64

View File

@ -1,14 +1,9 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// 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 {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -20,20 +17,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,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -48,6 +45,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 +73,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 +84,10 @@ class List {
}
}
protected:
JsonBuffer *_buffer;
private:
node_type *_firstNode;
};
}

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -38,6 +35,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,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -13,9 +10,14 @@
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) {}
@ -39,6 +41,14 @@ class ListIterator {
return *this;
}
ListIterator<T> &operator+=(size_t distance) {
while (_node && distance) {
_node = _node->next;
--distance;
}
return *this;
}
operator ListConstIterator<T>() const {
return ListConstIterator<T>(_node);
}

View File

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

View File

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

View File

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

View File

@ -0,0 +1,48 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#include "../JsonBuffer.hpp"
#include "../JsonVariant.hpp"
#include "../StringTraits/StringTraits.hpp"
#include "../TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TSourceRef, typename Enable = void>
struct ValueSetter {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
destination = source;
return true;
}
};
template <typename TSourceRef>
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<StringTraits<
TSourceRef>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer* buffer, TDestination& destination,
TSourceRef source) {
const char* copy = buffer->strdup(source);
if (!copy) return false;
destination = copy;
return true;
}
};
template <typename TSourceRef>
struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<!StringTraits<
TSourceRef>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) {
// unsigned char* -> char*
destination = reinterpret_cast<const char*>(source);
return true;
}
};
}
}

View File

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

View File

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

View File

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

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -17,8 +14,8 @@ class StringWriter {
public:
String(TChar** ptr) : _writePtr(ptr), _startPtr(*ptr) {}
void append(TChar c) {
*(*_writePtr)++ = c;
void append(char c) {
*(*_writePtr)++ = TChar(c);
}
const char* c_str() const {

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -46,30 +43,41 @@ class DynamicJsonBufferBase
};
public:
enum { EmptyBlockSize = sizeof(EmptyBlock) };
DynamicJsonBufferBase(size_t initialSize = 256)
: _head(NULL), _nextBlockCapacity(initialSize) {}
~DynamicJsonBufferBase() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
Block* nextBlock = currentBlock->next;
_allocator.deallocate(currentBlock);
currentBlock = nextBlock;
}
clear();
}
// Gets the number of bytes occupied in the buffer
size_t size() const {
size_t total = 0;
for (const Block* b = _head; b; b = b->next) total += b->size;
return total;
}
// Allocates the specified amount of bytes in the buffer
virtual void* alloc(size_t bytes) {
alignNextAlloc();
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
}
// Resets the buffer.
// USE WITH CAUTION: this invalidates all previously allocated data
void clear() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
_nextBlockCapacity = currentBlock->capacity;
Block* nextBlock = currentBlock->next;
_allocator.deallocate(currentBlock);
currentBlock = nextBlock;
}
_head = 0;
}
class String {
public:
String(DynamicJsonBufferBase* parent)
@ -98,7 +106,7 @@ class DynamicJsonBufferBase
private:
DynamicJsonBufferBase* _parent;
char* _start;
int _length;
size_t _length;
};
String startString() {
@ -129,7 +137,7 @@ class DynamicJsonBufferBase
}
bool addNewBlock(size_t capacity) {
size_t bytes = sizeof(EmptyBlock) + capacity;
size_t bytes = EmptyBlockSize + capacity;
Block* block = static_cast<Block*>(_allocator.allocate(bytes));
if (block == NULL) return false;
block->capacity = capacity;

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -39,13 +36,14 @@ class JsonArraySubscript;
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
class JsonArray : public Internals::JsonPrintable<JsonArray>,
public Internals::ReferenceType,
public Internals::NonCopyable,
public Internals::List<JsonVariant>,
public Internals::JsonBufferAllocated {
public:
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not call this constructor directly.
// Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
explicit JsonArray(JsonBuffer *buffer)
explicit JsonArray(JsonBuffer *buffer) throw()
: Internals::List<JsonVariant>(buffer) {}
// Gets the value at the specified index
@ -76,8 +74,9 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
// bool add(TValue value, uint8_t decimals);
// TValue = float, double
template <typename T>
bool add(T value, uint8_t decimals) {
return add_impl<const JsonVariant &>(JsonVariant(value, decimals));
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.
@ -111,16 +110,15 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
// Gets the value at the specified index.
template <typename T>
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
node_type *node = findNode(index);
return node ? node->content.as<T>()
: Internals::JsonVariantDefault<T>::get();
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 {
node_type *node = findNode(index);
return node ? node->content.is<T>() : false;
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.
@ -132,9 +130,10 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
JsonObject &createNestedObject();
// Removes element at specified index.
void removeAt(size_t index) {
removeNode(findNode(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.
@ -197,29 +196,26 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
}
}
private:
node_type *findNode(size_t index) const {
node_type *node = _firstNode;
while (node && index--) node = node->next;
return node;
#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) {
node_type *node = findNode(index);
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
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) {
node_type *node = addNewNode();
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
value);
iterator it = Internals::List<JsonVariant>::add();
if (it == end()) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
}
};

View File

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

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -81,8 +78,9 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
// bool set(TValue, uint8_t decimals);
// TValue = float, double
template <typename TValue>
FORCE_INLINE bool set(const TValue& value, uint8_t decimals) {
return _array.set(_index, value, decimals);
DEPRECATED("Second argument is not supported anymore")
FORCE_INLINE bool set(const TValue& value, uint8_t) {
return _array.set(_index, value);
}
private:
@ -105,15 +103,16 @@ 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 TImpl>
inline JsonArraySubscript JsonVariantSubscripts<TImpl>::operator[](
size_t index) {
return impl()->template as<JsonArray>()[index];
}
template <typename TImplem>
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
int index) const {
return as<JsonArray>()[index];
template <typename TImpl>
inline const JsonArraySubscript JsonVariantSubscripts<TImpl>::operator[](
size_t index) const {
return impl()->template as<JsonArray>()[index];
}
} // namespace ArduinoJson

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -11,20 +8,11 @@
#include <stdint.h> // for uint8_t
#include <string.h>
#include "Data/NonCopyable.hpp"
#include "JsonVariant.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsArray.hpp"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
class JsonArray;
class JsonObject;
@ -34,13 +22,8 @@ class JsonObject;
// Handle the memory management (done in derived classes) and calls the parser.
// This abstract class is implemented by StaticJsonBuffer which implements a
// fixed memory allocation.
class JsonBuffer {
class JsonBuffer : Internals::NonCopyable {
public:
// CAUTION: NO VIRTUAL DESTRUCTOR!
// If we add a virtual constructor the Arduino compiler will add malloc() and
// free() to the binary, adding 706 useless bytes.
// virtual ~JsonBuffer() {}
// Allocates an empty JsonArray.
//
// Returns a reference to the new JsonArray or JsonArray::invalid() if the
@ -76,6 +59,11 @@ class JsonBuffer {
virtual void *alloc(size_t size) = 0;
protected:
// CAUTION: NO VIRTUAL DESTRUCTOR!
// If we add a virtual constructor the Arduino compiler will add malloc()
// and free() to the binary, adding 706 useless bytes.
~JsonBuffer() {}
// Preserve aligment if necessary
static FORCE_INLINE size_t round_size_up(size_t bytes) {
#if ARDUINOJSON_ENABLE_ALIGNMENT
@ -87,11 +75,3 @@ class JsonBuffer {
}
};
}
#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 +1,11 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/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 {
@ -127,17 +114,12 @@ class JsonBufferBase : public JsonBuffer {
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
}
protected:
~JsonBufferBase() {}
private:
TDerived *that() {
return static_cast<TDerived *>(this);
}
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

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

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -38,13 +35,15 @@ class JsonBuffer;
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
class JsonObject : public Internals::JsonPrintable<JsonObject>,
public Internals::ReferenceType,
public Internals::NonCopyable,
public Internals::List<JsonPair>,
public Internals::JsonBufferAllocated {
public:
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not use this constructor directly.
// Instead, use JsonBuffer::createObject() or JsonBuffer.parseObject().
explicit JsonObject(JsonBuffer* buffer) : Internals::List<JsonPair>(buffer) {}
explicit JsonObject(JsonBuffer* buffer) throw()
: Internals::List<JsonPair>(buffer) {}
// Gets or sets the value associated with the specified key.
//
@ -134,23 +133,25 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// 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 decimals) {
return set_impl<const TString&, const JsonVariant&>(
key, JsonVariant(value, decimals));
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 decimals) {
return set_impl<const TString*, const JsonVariant&>(
key, JsonVariant(value, decimals));
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.
@ -247,14 +248,14 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
bool>::type
containsKey(const TString& key) const {
return findNode<const TString&>(key) != NULL;
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 findNode<const TString*>(key) != NULL;
return findKey<const TString*>(key) != end();
}
// Removes the specified key and the associated value.
@ -265,15 +266,18 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
void>::type
remove(const TString& key) {
removeNode(findNode<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) {
removeNode(findNode<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.
@ -286,41 +290,44 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
private:
// Returns the list node that matches the specified key.
template <typename TStringRef>
node_type* findNode(TStringRef key) const {
for (node_type* node = _firstNode; node; node = node->next) {
if (Internals::StringTraits<TStringRef>::equals(key, node->content.key))
return node;
iterator findKey(TStringRef key) {
iterator it;
for (it = begin(); it != end(); ++it) {
if (Internals::StringTraits<TStringRef>::equals(key, it->key)) break;
}
return NULL;
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 {
node_type* node = findNode<TStringRef>(key);
return node ? node->content.value.as<TValue>()
: Internals::JsonVariantDefault<TValue>::get();
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) {
node_type* node = findNode<TStringRef>(key);
if (!node) {
node = addNewNode();
if (!node) return false;
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, node->content.key, key);
bool key_ok =
Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key);
if (!key_ok) return false;
}
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content.value,
value);
return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value);
}
template <typename TStringRef, typename TValue>
bool is_impl(TStringRef key) const {
node_type* node = findNode<TStringRef>(key);
return node ? node->content.value.is<TValue>() : false;
const_iterator it = findKey<TStringRef>(key);
return it != end() ? it->value.is<TValue>() : false;
}
template <typename TStringRef>

View File

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

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -93,8 +90,9 @@ class JsonObjectSubscript
// bool set(TValue, uint8_t decimals);
// TValue = float, double
template <typename TValue>
FORCE_INLINE bool set(const TValue& value, uint8_t decimals) {
return _object.set(_key, value, decimals);
DEPRECATED("Second argument is not supported anymore")
FORCE_INLINE bool set(const TValue& value, uint8_t) {
return _object.set(_key, value);
}
private:

View File

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

View File

@ -1,9 +1,6 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -40,8 +37,8 @@ class JsonObject;
// - a string (const char*)
// - a reference to a JsonArray or JsonObject
class JsonVariant : public JsonVariantBase<JsonVariant> {
friend void Internals::JsonSerializer::serialize(const JsonVariant &,
JsonWriter &);
template <typename Print>
friend class Internals::JsonSerializer;
public:
// Creates an uninitialized JsonVariant
@ -52,31 +49,39 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonVariant(bool value) {
using namespace Internals;
_type = JSON_BOOLEAN;
_content.asInteger = static_cast<JsonInteger>(value);
_content.asInteger = static_cast<JsonUInt>(value);
}
// Create a JsonVariant containing a floating point value.
// The second argument specifies the number of decimal digits to write in
// the JSON string.
// JsonVariant(double value, uint8_t decimals);
// JsonVariant(float value, uint8_t decimals);
// JsonVariant(double value);
// JsonVariant(float value);
template <typename T>
JsonVariant(T value, uint8_t decimals = 2,
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
using namespace Internals;
_type = JSON_FLOAT;
_content.asFloat = static_cast<JsonFloat>(value);
}
template <typename T>
DEPRECATED("Second argument is not supported anymore")
JsonVariant(T value, uint8_t,
typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
using namespace Internals;
_type = static_cast<JsonVariantType>(JSON_FLOAT_0_DECIMALS + decimals);
_type = JSON_FLOAT;
_content.asFloat = static_cast<JsonFloat>(value);
}
// Create a JsonVariant containing an integer value.
// JsonVariant(char)
// JsonVariant(signed short)
// JsonVariant(signed int)
// JsonVariant(signed long)
// JsonVariant(signed char)
template <typename T>
JsonVariant(T value,
typename TypeTraits::EnableIf<
TypeTraits::IsSignedIntegral<T>::value>::type * = 0) {
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsSignedIntegral<T>::value ||
TypeTraits::IsSame<T, char>::value>::type * = 0) {
using namespace Internals;
if (value >= 0) {
_type = JSON_POSITIVE_INTEGER;
@ -129,24 +134,26 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// Get the variant as the specified type.
//
// short as<signed short>() const;
// int as<signed int>() const;
// long as<signed long>() const;
// char as<char>() const;
// signed char as<signed char>() const;
// signed short as<signed short>() const;
// signed int as<signed int>() const;
// signed long as<signed long>() const;
// unsigned char as<unsigned char>() const;
// unsigned short as<unsigned short>() const;
// unsigned int as<unsigned int>() const;
// unsigned long as<unsigned long>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSignedIntegral<T>::value,
T>::type
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, T>::type
as() const {
return static_cast<T>(variantAsInteger());
return variantAsInteger<T>();
}
//
// short as<unsigned short>() const;
// int as<unsigned int>() const;
// long as<unsigned long>() const;
// bool as<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsUnsignedIntegral<T>::value,
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
T>::type
as() const {
return static_cast<T>(asUnsignedInteger());
return variantAsInteger<int>() != 0;
}
//
// double as<double>() const;
@ -155,7 +162,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
T>::type
as() const {
return static_cast<T>(variantAsFloat());
return variantAsFloat<T>();
}
//
// const char* as<const char*>() const;
@ -180,14 +187,6 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
return s;
}
//
// const bool as<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
T>::type
as() const {
return variantAsInteger() != 0;
}
//
// JsonArray& as<JsonArray> const;
// JsonArray& as<JsonArray&> const;
template <typename T>
@ -242,32 +241,35 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// Tells weither the variant has the specified type.
// Returns true if the variant has type type T, false otherwise.
//
// short as<short>() const;
// int as<int>() const;
// long as<long>() const;
// bool is<char>() const;
// bool is<signed char>() const;
// bool is<signed short>() const;
// bool is<signed int>() const;
// bool is<signed long>() const;
// bool is<unsigned char>() const;
// bool is<unsigned short>() const;
// bool is<unsigned int>() const;
// bool is<unsigned long>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value &&
!TypeTraits::IsSame<T, bool>::value,
bool>::type
typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, bool>::type
is() const {
return isInteger();
return variantIsInteger();
}
//
// double is<double>() const;
// float is<float>() const;
// bool is<double>() const;
// bool is<float>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
is() const {
return isFloat();
return variantIsFloat();
}
//
// const bool is<bool>() const
// bool is<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
bool>::type
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value, bool>::type
is() const {
return isBoolean();
return variantIsBoolean();
}
//
// bool is<const char*>() const;
@ -277,7 +279,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
TypeTraits::IsSame<T, char *>::value,
bool>::type
is() const {
return isString();
return variantIsString();
}
//
// bool is<JsonArray> const;
@ -291,7 +293,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonArray>::value,
bool>::type
is() const {
return isArray();
return variantIsArray();
}
//
// bool is<JsonObject> const;
@ -305,7 +307,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonObject>::value,
bool>::type
is() const {
return isObject();
return variantIsObject();
}
// Returns true if the variant has a value
@ -314,27 +316,23 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
}
private:
// It's not allowed to store a char
template <typename T>
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsSame<T, char>::value>::type * = 0);
JsonArray &variantAsArray() const;
JsonObject &variantAsObject() const;
const char *variantAsString() const;
Internals::JsonFloat variantAsFloat() const;
Internals::JsonInteger variantAsInteger() const;
Internals::JsonUInt asUnsignedInteger() const;
bool isBoolean() const;
bool isFloat() const;
bool isInteger() const;
bool isArray() const {
template <typename T>
T variantAsFloat() const;
template <typename T>
T variantAsInteger() const;
bool variantIsBoolean() const;
bool variantIsFloat() const;
bool variantIsInteger() const;
bool variantIsArray() const {
return _type == Internals::JSON_ARRAY;
}
bool isObject() const {
bool variantIsObject() const {
return _type == Internals::JSON_OBJECT;
}
bool isString() const {
bool variantIsString() const {
return _type == Internals::JSON_STRING ||
(_type == Internals::JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString));
@ -347,11 +345,13 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
Internals::JsonVariantContent _content;
};
inline JsonVariant float_with_n_digits(float value, uint8_t digits) {
return JsonVariant(value, digits);
DEPRECATED("Decimal places are ignored, use the float value instead")
inline JsonVariant float_with_n_digits(float value, uint8_t) {
return JsonVariant(value);
}
inline JsonVariant double_with_n_digits(double value, uint8_t digits) {
return JsonVariant(value, digits);
DEPRECATED("Decimal places are ignored, use the double value instead")
inline JsonVariant double_with_n_digits(double value, uint8_t) {
return JsonVariant(value);
}
}

View File

@ -0,0 +1,22 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#include "JsonVariantCasts.hpp"
#include "JsonVariantComparisons.hpp"
#include "JsonVariantOr.hpp"
#include "JsonVariantSubscripts.hpp"
#include "Serialization/JsonPrintable.hpp"
namespace ArduinoJson {
template <typename TImpl>
class JsonVariantBase : public Internals::JsonPrintable<TImpl>,
public JsonVariantCasts<TImpl>,
public JsonVariantComparisons<TImpl>,
public JsonVariantOr<TImpl>,
public JsonVariantSubscripts<TImpl>,
public TypeTraits::JsonVariantTag {};
}

View File

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

View File

@ -0,0 +1,141 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsVariant.hpp"
namespace ArduinoJson {
template <typename TImpl>
class JsonVariantComparisons {
public:
template <typename TComparand>
friend bool operator==(const JsonVariantComparisons &variant,
TComparand comparand) {
return variant.equals(comparand);
}
template <typename TComparand>
friend
typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator==(TComparand comparand, const JsonVariantComparisons &variant) {
return variant.equals(comparand);
}
template <typename TComparand>
friend bool operator!=(const JsonVariantComparisons &variant,
TComparand comparand) {
return !variant.equals(comparand);
}
template <typename TComparand>
friend
typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator!=(TComparand comparand, const JsonVariantComparisons &variant) {
return !variant.equals(comparand);
}
template <typename TComparand>
friend bool operator<=(const JsonVariantComparisons &left, TComparand right) {
return left.as<TComparand>() <= right;
}
template <typename TComparand>
friend bool operator<=(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand <= variant.as<TComparand>();
}
template <typename TComparand>
friend bool operator>=(const JsonVariantComparisons &variant,
TComparand comparand) {
return variant.as<TComparand>() >= comparand;
}
template <typename TComparand>
friend bool operator>=(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand >= variant.as<TComparand>();
}
template <typename TComparand>
friend bool operator<(const JsonVariantComparisons &varian,
TComparand comparand) {
return varian.as<TComparand>() < comparand;
}
template <typename TComparand>
friend bool operator<(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand < variant.as<TComparand>();
}
template <typename TComparand>
friend bool operator>(const JsonVariantComparisons &variant,
TComparand comparand) {
return variant.as<TComparand>() > comparand;
}
template <typename TComparand>
friend bool operator>(TComparand comparand,
const JsonVariantComparisons &variant) {
return comparand > variant.as<TComparand>();
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
template <typename T>
const typename Internals::JsonVariantAs<T>::type as() const {
return impl()->template as<T>();
}
template <typename T>
bool is() const {
return impl()->template is<T>();
}
template <typename TString>
typename TypeTraits::EnableIf<TypeTraits::IsString<TString>::value,
bool>::type
equals(const TString &comparand) const {
const char *value = as<const char *>();
return Internals::StringTraits<TString>::equals(comparand, value);
}
template <typename TComparand>
typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value &&
!TypeTraits::IsString<TComparand>::value,
bool>::type
equals(const TComparand &comparand) const {
return as<TComparand>() == comparand;
}
template <typename TVariant2>
bool equals(const JsonVariantComparisons<TVariant2> &right) const {
using namespace Internals;
if (is<bool>() && right.template is<bool>())
return as<bool>() == right.template as<bool>();
if (is<JsonInteger>() && right.template is<JsonInteger>())
return as<JsonInteger>() == right.template as<JsonInteger>();
if (is<JsonFloat>() && right.template is<JsonFloat>())
return as<JsonFloat>() == right.template as<JsonFloat>();
if (is<JsonArray>() && right.template is<JsonArray>())
return as<JsonArray>() == right.template as<JsonArray>();
if (is<JsonObject>() && right.template is<JsonObject>())
return as<JsonObject>() == right.template as<JsonObject>();
if (is<char *>() && right.template is<char *>())
return strcmp(as<char *>(), right.template as<char *>()) == 0;
return false;
}
};
}

View File

@ -1,20 +1,18 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// 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 "Data/Parse.hpp"
#include "JsonArray.hpp"
#include "JsonObject.hpp"
#include "JsonVariant.hpp"
#include "Polyfills/isFloat.hpp"
#include "Polyfills/isInteger.hpp"
#include "Polyfills/parseFloat.hpp"
#include "Polyfills/parseInteger.hpp"
#include <errno.h> // for errno
#include <stdlib.h> // for strtol, strtod
#include <string.h> // for strcmp
namespace ArduinoJson {
@ -47,42 +45,22 @@ inline JsonObject &JsonVariant::variantAsObject() const {
return JsonObject::invalid();
}
inline Internals::JsonInteger JsonVariant::variantAsInteger() const {
template <typename T>
inline T JsonVariant::variantAsInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return _content.asInteger;
return T(_content.asInteger);
case JSON_NEGATIVE_INTEGER:
return -static_cast<Internals::JsonInteger>(_content.asInteger);
return T(~_content.asInteger + 1);
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonInteger>(_content.asString);
return Polyfills::parseInteger<T>(_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);
return T(_content.asFloat);
}
}
@ -95,25 +73,26 @@ inline const char *JsonVariant::variantAsString() const {
return NULL;
}
inline Internals::JsonFloat JsonVariant::variantAsFloat() const {
template <typename T>
inline T JsonVariant::variantAsFloat() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return static_cast<JsonFloat>(_content.asInteger);
return static_cast<T>(_content.asInteger);
case JSON_NEGATIVE_INTEGER:
return -static_cast<JsonFloat>(_content.asInteger);
return -static_cast<T>(_content.asInteger);
case JSON_STRING:
case JSON_UNPARSED:
return _content.asString ? parse<JsonFloat>(_content.asString) : 0;
return Polyfills::parseFloat<T>(_content.asString);
default:
return _content.asFloat;
return static_cast<T>(_content.asFloat);
}
}
inline bool JsonVariant::isBoolean() const {
inline bool JsonVariant::variantIsBoolean() const {
using namespace Internals;
if (_type == JSON_BOOLEAN) return true;
@ -123,31 +102,19 @@ inline bool JsonVariant::isBoolean() const {
!strcmp(_content.asString, "false");
}
inline bool JsonVariant::isInteger() const {
inline bool JsonVariant::variantIsInteger() 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;
return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER ||
(_type == JSON_UNPARSED && Polyfills::isInteger(_content.asString));
}
inline bool JsonVariant::isFloat() const {
inline bool JsonVariant::variantIsFloat() 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>();
return _type == JSON_FLOAT || _type == JSON_POSITIVE_INTEGER ||
_type == JSON_NEGATIVE_INTEGER ||
(_type == JSON_UNPARSED && Polyfills::isFloat(_content.asString));
}
#if ARDUINOJSON_ENABLE_STD_STREAM

View File

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

View File

@ -1,15 +1,13 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Data/JsonVariantAs.hpp"
#include "Polyfills/attributes.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
@ -19,67 +17,21 @@ template <typename TKey>
class JsonObjectSubscript;
template <typename TImpl>
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
class JsonVariantSubscripts {
public:
#if ARDUINOJSON_ENABLE_DEPRECATED
DEPRECATED("use as<JsonArray>() instead")
FORCE_INLINE JsonArray &asArray() const {
return as<JsonArray>();
}
DEPRECATED("use as<JsonObject>() instead")
FORCE_INLINE JsonObject &asObject() const {
return as<JsonObject>();
}
DEPRECATED("use as<char*>() instead")
FORCE_INLINE const char *asString() const {
return as<const char *>();
}
#endif
// Gets the variant as an array.
// Returns a reference to the JsonArray or JsonArray::invalid() if the
// variant
// is not an array.
FORCE_INLINE operator JsonArray &() const {
return as<JsonArray &>();
}
// Gets the variant as an object.
// Returns a reference to the JsonObject or JsonObject::invalid() if the
// variant is not an object.
FORCE_INLINE operator JsonObject &() const {
return as<JsonObject &>();
}
template <typename T>
FORCE_INLINE operator T() const {
return as<T>();
}
template <typename T>
FORCE_INLINE const typename Internals::JsonVariantAs<T>::type as() const {
return impl()->template as<T>();
}
template <typename T>
FORCE_INLINE bool is() const {
return impl()->template is<T>();
}
// Mimics an array or an object.
// Returns the size of the array or object if the variant has that type.
// Returns 0 if the variant is neither an array nor an object
size_t size() const {
return as<JsonArray>().size() + as<JsonObject>().size();
return impl()->template as<JsonArray>().size() +
impl()->template as<JsonObject>().size();
}
// Mimics an array.
// Returns the element at specified index if the variant is an array.
// Returns JsonVariant::invalid() if the variant is not an array.
FORCE_INLINE const JsonArraySubscript operator[](int index) const;
FORCE_INLINE JsonArraySubscript operator[](int index);
FORCE_INLINE const JsonArraySubscript operator[](size_t index) const;
FORCE_INLINE JsonArraySubscript operator[](size_t index);
// Mimics an object.
// Returns the value associated with the specified key if the variant is
@ -93,7 +45,7 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<TString>::has_equals,
const JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) const {
return as<JsonObject>()[key];
return impl()->template as<JsonObject>()[key];
}
//
// const JsonObjectSubscript operator[](TKey) const;
@ -103,7 +55,7 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<TString>::has_equals,
JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) {
return as<JsonObject>()[key];
return impl()->template as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
@ -113,7 +65,7 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<const TString *>::has_equals,
JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) {
return as<JsonObject>()[key];
return impl()->template as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
@ -123,7 +75,7 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<TString *>::has_equals,
const JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) const {
return as<JsonObject>()[key];
return impl()->template as<JsonObject>()[key];
}
private:
@ -131,9 +83,4 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
return static_cast<const TImpl *>(this);
}
};
namespace TypeTraits {
template <typename T>
struct IsVariant : IsBaseOf<JsonVariantBase<T>, T> {};
}
}

View File

@ -1,17 +1,17 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifdef _MSC_VER
#ifdef _MSC_VER // Visual Studio
#define FORCE_INLINE __forceinline
#define NO_INLINE __declspec(noinline)
#define DEPRECATED(msg) __declspec(deprecated(msg))
#else
#elif defined(__GNUC__) // GCC or Clang
#define FORCE_INLINE __attribute__((always_inline))
#define NO_INLINE __attribute__((noinline))
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
@ -19,4 +19,11 @@
#else
#define DEPRECATED(msg) __attribute__((deprecated))
#endif
#else // Other compilers
#define FORCE_INLINE
#define NO_INLINE
#define DEPRECATED(msg)
#endif

View File

@ -0,0 +1,18 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
namespace ArduinoJson {
namespace Polyfills {
inline bool isdigit(char c) {
return '0' <= c && c <= '9';
}
inline bool issign(char c) {
return '-' == c || c == '+';
}
}
}

View File

@ -0,0 +1,38 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#include <string.h> // for strcmp
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
inline bool isFloat(const char* s) {
if (!s) return false;
if (!strcmp(s, "NaN")) return true;
if (issign(*s)) s++;
if (!strcmp(s, "Infinity")) return true;
if (*s == '\0') return false;
while (isdigit(*s)) s++;
if (*s == '.') {
s++;
while (isdigit(*s)) s++;
}
if (*s == 'e' || *s == 'E') {
s++;
if (issign(*s)) s++;
if (!isdigit(*s)) return false;
while (isdigit(*s)) s++;
}
return *s == '\0';
}
}
}

View File

@ -0,0 +1,19 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
inline bool isInteger(const char* s) {
if (!s) return false;
if (issign(*s)) s++;
while (isdigit(*s)) s++;
return *s == '\0';
}
}
}

View File

@ -0,0 +1,19 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
bool isNaN(T x) {
return x != x;
}
template <typename T>
bool isInfinity(T x) {
return x != 0.0 && x * 2 == x;
}
}
}

View File

@ -0,0 +1,90 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#include "../TypeTraits/FloatTraits.hpp"
#include "./ctype.hpp"
#include "./math.hpp"
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
inline T parseFloat(const char* s) {
typedef TypeTraits::FloatTraits<T> traits;
typedef typename traits::mantissa_type mantissa_t;
typedef typename traits::exponent_type exponent_t;
if (!s) return 0; // NULL
bool negative_result = false;
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;
}
if (*s == 't') return 1; // true
if (*s == 'n' || *s == 'N') return traits::nan();
if (*s == 'i' || *s == 'I')
return negative_result ? -traits::inf() : traits::inf();
mantissa_t mantissa = 0;
exponent_t exponent_offset = 0;
while (isdigit(*s)) {
if (mantissa < traits::mantissa_max / 10)
mantissa = mantissa * 10 + (*s - '0');
else
exponent_offset++;
s++;
}
if (*s == '.') {
s++;
while (isdigit(*s)) {
if (mantissa < traits::mantissa_max / 10) {
mantissa = mantissa * 10 + (*s - '0');
exponent_offset--;
}
s++;
}
}
int exponent = 0;
if (*s == 'e' || *s == 'E') {
s++;
bool negative_exponent = false;
if (*s == '-') {
negative_exponent = true;
s++;
} else if (*s == '+') {
s++;
}
while (isdigit(*s)) {
exponent = exponent * 10 + (*s - '0');
if (exponent + exponent_offset > traits::exponent_max) {
if (negative_exponent)
return negative_result ? -0.0f : 0.0f;
else
return negative_result ? -traits::inf() : traits::inf();
}
s++;
}
if (negative_exponent) exponent = -exponent;
}
exponent += exponent_offset;
T result = traits::make_float(static_cast<T>(mantissa), exponent);
return negative_result ? -result : result;
}
}
}

View File

@ -0,0 +1,41 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// MIT License
#pragma once
#include <stdlib.h>
#include "../Configuration.hpp"
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
T parseInteger(const char *s) {
if (!s) return 0; // NULL
if (*s == 't') return 1; // "true"
T result = 0;
bool negative_result = false;
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;
}
while (isdigit(*s)) {
result = T(result * 10 + T(*s - '0'));
s++;
}
return negative_result ? T(~result + 1) : result;
}
}
}

View File

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

View File

@ -1,23 +1,22 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// 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 dummy Print implementation used in JsonPrintable::measureLength()
class DummyPrint : public Print {
class DummyPrint {
public:
virtual size_t write(uint8_t) {
size_t print(char) {
return 1;
}
size_t print(const char* s) {
return strlen(s);
}
};
}
}

View File

@ -1,13 +1,9 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// 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 "../StringTraits/StringTraits.hpp"
namespace ArduinoJson {
@ -15,15 +11,21 @@ namespace Internals {
// A Print implementation that allows to write in a String
template <typename TString>
class DynamicStringBuilder : public Print {
class DynamicStringBuilder {
public:
DynamicStringBuilder(TString &str) : _str(str) {}
virtual size_t write(uint8_t c) {
StringTraits<TString>::append(_str, static_cast<char>(c));
size_t print(char c) {
StringTraits<TString>::append(_str, c);
return 1;
}
size_t print(const char *s) {
size_t initialLen = _str.length();
StringTraits<TString>::append(_str, s);
return _str.length() - initialLen;
}
private:
DynamicStringBuilder &operator=(const DynamicStringBuilder &);

View File

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

View File

@ -1,21 +1,17 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2017
// 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 {
// Decorator on top of Print to allow indented output.
// This class is used by JsonPrintable::prettyPrintTo() but can also be used
// for your own purpose, like logging.
class IndentedPrint : public Print {
template <typename Print>
class IndentedPrint {
public:
explicit IndentedPrint(Print &p) : sink(&p) {
level = 0;
@ -23,14 +19,21 @@ class IndentedPrint : public Print {
isNewLine = true;
}
virtual size_t write(uint8_t c) {
size_t print(char c) {
size_t n = 0;
if (isNewLine) n += writeTabs();
n += sink->write(c);
n += sink->print(c);
isNewLine = c == '\n';
return n;
}
size_t print(const char *s) {
// TODO: optimize
size_t n = 0;
while (*s) n += print(*s++);
return n;
}
// Adds one level of indentation
void indent() {
if (level < MAX_LEVEL) level++;
@ -54,7 +57,7 @@ class IndentedPrint : public Print {
size_t writeTabs() {
size_t n = 0;
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
for (int i = 0; i < level * tabSize; i++) n += sink->print(' ');
return n;
}

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