Compare commits

...

58 Commits

Author SHA1 Message Date
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
0d5f65c5f3 Set version to 5.8.3 2017-02-11 15:12:03 +01:00
c30241775a Fixed JsonVariant::operator[const FlashStringHelper*] (issue #441) 2017-02-11 15:09:08 +01:00
31827d03f9 Added operators == and != for two JsonVariants (issue #436) 2017-02-11 15:06:17 +01:00
7bcdf3e722 JsonHttpClient: Close socket even when connection fails (issue #445) 2017-02-11 14:01:14 +01:00
db9a76f7c6 Fixed an access violation in DynamicJsonBuffer when memory allocation fails (issue #433) 2017-01-31 10:06:40 +01:00
3fd87e8e82 Added fuzzing/ to .mbedignore 2017-01-25 15:28:15 +01:00
22a2786610 Added Christoph Schmidt to the list of donators 2017-01-24 21:21:05 +01:00
2b5a6df1e1 Set version to 5.8.2 2017-01-22 18:08:32 +01:00
5fefeae404 Added deprecated attribute on asArray(), asObject() and asString() (issue #420) 2017-01-22 17:24:17 +01:00
d4f725d1fa Fixed error with string of type unsigned char* (issue #428) 2017-01-22 15:42:47 +01:00
a096098c1f Fixed error when the key of a JsonObject is a char[] and reduced code size when using const references (issue #423) 2017-01-22 11:10:45 +01:00
cc8c0472ca Fixed ignored Stream timeout and made sure we don't read more that necessary (issue #422) 2017-01-22 10:31:05 +01:00
fb554071dc Travis: Added -fsanitize to several builds 2017-01-21 19:49:44 +01:00
17a17c8957 Fixed parsing of comments (issue #421) 2017-01-17 21:48:13 +01:00
441 changed files with 19357 additions and 151410 deletions

View File

@ -1,11 +1,14 @@
<!--
Thanks for using ArduinoJson :-)
Before opening an issue, please read the FAQ:
https://bblanchon.github.io/ArduinoJson/faq/
Before opening an issue, please make sure you've read these:
https://github.com/bblanchon/ArduinoJson/wiki/FAQ
https://github.com/bblanchon/ArduinoJson/wiki/Avoiding-pitfalls
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

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

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include "include/ArduinoJson.h"
#include "src/ArduinoJson.h"

View File

@ -1,6 +1,90 @@
ArduinoJson: change log
=======================
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
------
* Fixed an access violation in `DynamicJsonBuffer` when memory allocation fails (issue #433)
* Added operators `==` and `!=` for two `JsonVariant`s (issue #436)
* Fixed `JsonVariant::operator[const FlashStringHelper*]` (issue #441)
v5.8.2
------
* Fixed parsing of comments (issue #421)
* Fixed ignored `Stream` timeout (issue #422)
* Made sure we don't read more that necessary (issue #422)
* Fixed error when the key of a `JsonObject` is a `char[]` (issue #423)
* Reduced code size when using `const` references
* Fixed error with string of type `unsigned char*` (issue #428)
* Added `deprecated` attribute on `asArray()`, `asObject()` and `asString()` (issue #420)
v5.8.1
------
@ -16,7 +100,7 @@ v5.8.0
* Added support for `Stream` (issue #300)
* Reduced memory consumption by not duplicating spaces and comments
**BREAKING CHANGES**:
### BREAKING CHANGES :warning:
`JsonBuffer::parseObject()` and `JsonBuffer::parseArray()` have been pulled down to the derived classes `DynamicJsonBuffer` and `StaticJsonBufferBase`.
@ -34,6 +118,7 @@ void myFunction(StaticJsonBufferBase& jsonBuffer);
template<typename TJsonBuffer> void myFunction(TJsonBuffer& jsonBuffer);
```
v5.7.3
------
@ -65,7 +150,7 @@ 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**:
### 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.
@ -192,7 +277,8 @@ v5.0.7
* Made library easier to use from a CMake project: simply `add_subdirectory(ArduinoJson/src)`
* Changed `String` to be a `typedef` of `std::string` (issues #142 and #161)
**BREAKING CHANGES**:
### BREAKING CHANGES :warning:
- `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
- `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
@ -248,7 +334,8 @@ v5.0.0
* Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66)
* Switched to new the library layout (requires Arduino 1.0.6 or above)
**BREAKING CHANGES**:
### BREAKING CHANGES :warning:
- `JsonObject::add()` was renamed to `set()`
- `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
- Number of digits of floating point value are now set with `double_with_n_digits()`

View File

@ -2,7 +2,7 @@
# MIT License
#
# Arduino JSON library
# https://github.com/bblanchon/ArduinoJson
# https://bblanchon.github.io/ArduinoJson/
# If you like this project, please add a star!
cmake_minimum_required(VERSION 3.0)
@ -10,16 +10,10 @@ project(ArduinoJson)
enable_testing()
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
if(${COVERAGE})
set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
endif()
if(${SANITIZE})
set(CMAKE_CXX_FLAGS "-fsanitize=address,undefined")
endif()
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)
add_subdirectory(third-party/catch)
add_subdirectory(test)

View File

@ -1,4 +1,4 @@
Arduino JSON library
ArduinoJson - C++ JSON library for IoT
====================
[![Build status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/master?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/master) [![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=master)](https://travis-ci.org/bblanchon/ArduinoJson) [![Coverage Status](https://img.shields.io/coveralls/bblanchon/ArduinoJson.svg)](https://coveralls.io/r/bblanchon/ArduinoJson?branch=master) [![Star this project](http://githubbadges.com/star.svg?user=bblanchon&repo=ArduinoJson&style=flat&color=fff&background=007ec6)](https://github.com/bblanchon/ArduinoJson)
@ -27,16 +27,16 @@ Features
Works on
--------
* All Arduino boards (Uno, Due, Mini, Micro, Yun...)
* ESP8266
* Arduino boards: Uno, Due, Mini, Micro, Yun...
* ESP8266, ESP32
* Teensy
* Intel Edison and Galileo
* PlatformIO
* Energia
* RedBearLab boards (BLE Nano...)
* Computers (Windows, Linux, OSX...)
See [FAQ: Compatibility issues](https://github.com/bblanchon/ArduinoJson/wiki/Compatibility-issues)
* Intel Edison and Galileo
* WeMos boards: D1...
* Computers: Windows, Linux, OSX...
* PlatformIO
* Particle
* Energia
Quick start
-----------
@ -58,6 +58,8 @@ double longitude = root["data"][1];
[See JsonParserExample.ino](examples/JsonParserExample/JsonParserExample.ino)
Use [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) to compute the buffer size.
#### Encoding / Generating
```c++
@ -68,8 +70,8 @@ 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:
@ -78,38 +80,16 @@ root.printTo(Serial);
[See JsonGeneratorExample.ino](examples/JsonGeneratorExample/JsonGeneratorExample.ino)
Use [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) to compute the buffer size.
Documentation
-------------
The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)
The documentation is available online in the [ArduinoJson Website](https://bblanchon.github.io/ArduinoJson/).
Testimonials
------------
The [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) helps you get started with the library.
From Arduino's Forum user `jflaplante`:
> I tried aJson json-arduino before trying your library. I always ran into memory problem after a while.
> I have no such problem so far with your library. It is working perfectly with my web services.
From 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
--------
@ -133,6 +113,12 @@ 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'>
* 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'>
---

View File

@ -1,13 +1,15 @@
version: 5.8.1.{build}
version: 5.11.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 .

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

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>
@ -17,13 +17,13 @@ void setup() {
//
// Inside the brackets, 200 is the size of the pool in bytes.
// If the JSON object is more complex, you need to increase that value.
// See https://bblanchon.github.io/ArduinoJson/assistant/
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 +44,8 @@ void setup() {
// It's also possible to create the array separately and add it to the
// JsonObject but it's less efficient.
JsonArray& data = root.createNestedArray("data");
data.add(double_with_n_digits(48.756080, 6));
data.add(double_with_n_digits(2.302038, 6));
data.add(48.756080);
data.add(2.302038);
root.printTo(Serial);
// This prints:

View File

@ -5,7 +5,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>
@ -41,8 +41,8 @@ void loop() {
printUserData(&userData);
}
}
disconnect();
}
disconnect();
wait();
}
@ -135,7 +135,7 @@ bool skipResponseHeaders() {
// }
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.
// See https://bblanchon.github.io/ArduinoJson/assistant/
const size_t BUFFER_SIZE =
JSON_OBJECT_SIZE(8) // the root object has 8 elements
+ JSON_OBJECT_SIZE(5) // the "address" object has 5 elements

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>
@ -17,13 +17,13 @@ void setup() {
//
// Inside the brackets, 200 is the size of the pool in bytes,
// If the JSON object is more complex, you need to increase that value.
// See https://bblanchon.github.io/ArduinoJson/assistant/
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.
//

View File

@ -2,9 +2,9 @@
// Created by Benoit Blanchon.
// Heavily inspired by "Web Server" from David A. Mellis and Tom Igoe
#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);
@ -64,6 +64,8 @@ void loop() {
if (client) {
bool success = readRequest(client);
if (success) {
// Use https://bblanchon.github.io/ArduinoJson/assistant/ to
// compute the right size for the buffer
StaticJsonBuffer<500> jsonBuffer;
JsonObject& json = prepareResponse(jsonBuffer);
writeResponse(client, json);

View File

@ -49,6 +49,8 @@ void setup() {
void loop() {
delay(1000);
// Use https://bblanchon.github.io/ArduinoJson/assistant/ to
// compute the right size for the buffer
StaticJsonBuffer<300> jsonBuffer;
JsonObject& json = buildJson(jsonBuffer);
sendJson(json);

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>

View File

@ -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,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,41 +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;
}
};
}
}

View File

@ -1,41 +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 Internals {
// Parse JSON string to create JsonArrays and JsonObjects
// This internal class is not indended to be used directly.
// Instead, use JsonBuffer.parseArray() or .parseObject()
template <typename TIterator>
class StringReader {
TIterator _input;
char _current, _next;
public:
StringReader(const TIterator& input) : _input(input) {
_current = _input.next();
_next = _input.next();
}
void move() {
_current = _next;
_next = _input.next();
}
char current() const {
return _current;
}
char next() const {
return _next;
}
};
}
}

View File

@ -1,106 +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 {
template <typename TVariant, typename TComparand, typename Enable = void>
struct JsonVariantComparer {
static bool equals(const TVariant &variant, const TComparand &comparand) {
return variant.template as<TComparand>() == comparand;
}
};
template <typename TVariant, typename TString>
struct JsonVariantComparer<
TVariant, TString, typename TypeTraits::EnableIf<Internals::StringTraits<
TString>::has_equals>::type> {
static bool equals(const TVariant &variant, const TString &comparand) {
const char *value = variant.template as<const char *>();
return Internals::StringTraits<TString>::equals(comparand, value);
}
};
template <typename TImpl, typename TComparand>
inline bool operator==(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
typedef JsonVariantBase<TImpl> TVariant;
return JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator==(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
typedef JsonVariantBase<TImpl> TVariant;
return JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator!=(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
typedef JsonVariantBase<TImpl> TVariant;
return !JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator!=(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
typedef JsonVariantBase<TImpl> TVariant;
return !JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator<=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() <= right;
}
template <typename TImpl, typename TComparand>
inline bool operator<=(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand <= variant.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>=(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
return variant.template as<TComparand>() >= comparand;
}
template <typename TImpl, typename TComparand>
inline bool operator>=(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand >= variant.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator<(const JsonVariantBase<TImpl> &varian,
TComparand comparand) {
return varian.template as<TComparand>() < comparand;
}
template <typename TImpl, typename TComparand>
inline bool operator<(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand < variant.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
return variant.template as<TComparand>() > comparand;
}
template <typename TImpl, typename TComparand>
inline bool operator>(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand > variant.template as<TComparand>();
}
}

View File

@ -1,16 +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
#ifdef _MSC_VER
#define FORCE_INLINE __forceinline
#define NO_INLINE __declspec(noinline)
#else
#define FORCE_INLINE __attribute__((always_inline))
#define NO_INLINE __attribute__((noinline))
#endif

View File

@ -1,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,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

@ -1,51 +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 Internals {
struct CharPointerTraits {
class Iterator {
const char* _ptr;
public:
Iterator(const char* ptr) : _ptr(ptr ? ptr : "") {}
char next() {
char c = *_ptr;
if (c) ++_ptr;
return c;
}
};
static bool equals(const char* str, const char* expected) {
return strcmp(str, expected) == 0;
}
template <typename Buffer>
static char* duplicate(const char* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen(str) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy(dup, str, size);
return static_cast<char*>(dup);
}
static const bool has_append = false;
static const bool has_equals = true;
static const bool should_duplicate = false;
};
template <>
struct StringTraits<const char*, void> : CharPointerTraits {};
template <>
struct StringTraits<char*, void> : CharPointerTraits {};
}
}

View File

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

View File

@ -1,9 +1,9 @@
name=ArduinoJson
version=5.8.1
version=5.11.0
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=An efficient and elegant JSON library for Arduino.
paragraph=Like this project? Please star it on GitHub!
category=Data Processing
url=https://github.com/bblanchon/ArduinoJson
url=https://bblanchon.github.io/ArduinoJson/
architectures=*

View File

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

View File

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

View File

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

View File

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

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

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

View File

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

View File

@ -1,7 +0,0 @@
#!/bin/sh -eux
curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1
/tmp/bin/cmake -DSANITIZE=true .
cmake --build .
ctest -VV .

View File

@ -2,8 +2,11 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "ArduinoJson.hpp"
using namespace ArduinoJson;

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -19,5 +19,3 @@
#include "ArduinoJson/JsonObjectImpl.hpp"
#include "ArduinoJson/JsonVariantImpl.hpp"
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"
using namespace ArduinoJson;

View File

@ -2,19 +2,28 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#ifdef ARDUINO // assume this is an embedded platform
// Small or big machine?
#ifndef ARDUINOJSON_EMBEDDED_MODE
#if defined(ARDUINO) || defined(__IAR_SYSTEMS_ICC__)
#define ARDUINOJSON_EMBEDDED_MODE 1
#else
#define ARDUINOJSON_EMBEDDED_MODE 0
#endif
#endif
// store using float instead of double to reduce the memory usage (issue #134)
#if ARDUINOJSON_EMBEDDED_MODE
// 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
@ -22,57 +31,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
@ -81,7 +62,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
@ -90,41 +71,91 @@
#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
// how many bits in a double
#ifndef ARDUINOJSON_DOUBLE_IS_64BITS
#if /*GCC*/ (defined(__SIZEOF_DOUBLE__) && __SIZEOF_DOUBLE__ < 8) || \
/*IAR*/ (defined(__DOUBLE__) && __DOUBLE__ < 64)
#define ARDUINOJSON_DOUBLE_IS_64BITS 0
#else
#define ARDUINOJSON_DOUBLE_IS_64BITS 1 // by default support 64-bit
#endif
#endif
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64

View File

@ -2,13 +2,11 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -38,6 +38,14 @@ class ListConstIterator {
return *this;
}
ListConstIterator<T> &operator+=(size_t distance) {
while (_node && distance) {
_node = _node->next;
--distance;
}
return *this;
}
private:
const ListNode<T> *_node;
};

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -13,9 +13,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 +44,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

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -18,7 +18,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,26 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
// 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

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -27,39 +27,27 @@ void skipSpacesAndComments(TInput& input) {
// C-style block comment
case '*':
input.move(); // skip '/'
input.move(); // skip '*'
// no need to skip '*'
for (;;) {
switch (input.current()) {
case '\0':
return;
case '*':
input.move(); // skip '*'
if (input.current() == '/') {
input.move(); // skip '/'
return;
}
break;
default:
input.move();
input.move();
if (input.current() == '\0') return;
if (input.current() == '*' && input.next() == '/') {
input.move(); // skip '*'
input.move(); // skip '/'
break;
}
}
break;
// C++-style line comment
case '/':
input.move(); // skip '/'
// not need to skip "//"
for (;;) {
switch (input.current()) {
case '\0':
return;
case '\n':
input.move();
return;
default:
input.move();
}
input.move();
if (input.current() == '\0') return;
if (input.current() == '\n') break;
}
return;
break;
// not a comment, just a '/'
default:

View File

@ -2,14 +2,14 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include "../JsonVariant.hpp"
#include "StringReader.hpp"
#include "../TypeTraits/IsConst.hpp"
#include "StringWriter.hpp"
namespace ArduinoJson {
@ -72,25 +72,28 @@ class JsonParser {
uint8_t _nestingLimit;
};
template <typename TJsonBuffer, typename TString>
template <typename TJsonBuffer, typename TString, typename Enable = void>
struct JsonParserBuilder {
typedef typename Internals::StringTraits<TString>::Iterator InputIterator;
typedef JsonParser<StringReader<InputIterator>, TJsonBuffer &> TParser;
typedef typename Internals::StringTraits<TString>::Reader InputReader;
typedef JsonParser<InputReader, TJsonBuffer &> TParser;
static TParser makeParser(TJsonBuffer *buffer, TString &json,
uint8_t nestingLimit) {
return TParser(buffer, InputIterator(json), *buffer, nestingLimit);
return TParser(buffer, InputReader(json), *buffer, nestingLimit);
}
};
template <typename TJsonBuffer>
struct JsonParserBuilder<TJsonBuffer, char *> {
typedef typename Internals::StringTraits<char *>::Iterator InputIterator;
typedef JsonParser<StringReader<InputIterator>, StringWriter> TParser;
template <typename TJsonBuffer, typename TChar>
struct JsonParserBuilder<
TJsonBuffer, TChar *,
typename TypeTraits::EnableIf<!TypeTraits::IsConst<TChar>::value>::type> {
typedef typename Internals::StringTraits<TChar *>::Reader TReader;
typedef StringWriter<TChar> TWriter;
typedef JsonParser<TReader, TWriter> TParser;
static TParser makeParser(TJsonBuffer *buffer, char *json,
static TParser makeParser(TJsonBuffer *buffer, TChar *json,
uint8_t nestingLimit) {
return TParser(buffer, InputIterator(json), json, nestingLimit);
return TParser(buffer, TReader(json), TWriter(json), nestingLimit);
}
};

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -16,14 +16,12 @@ inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat(
skipSpacesAndComments(reader);
if (reader.current() != charToSkip) return false;
reader.move();
skipSpacesAndComments(reader);
return true;
}
template <typename TReader, typename TWriter>
inline bool
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
JsonVariant *destination) {
inline bool ArduinoJson::Internals::JsonParser<
TReader, TWriter>::parseAnythingTo(JsonVariant *destination) {
if (_nestingLimit == 0) return false;
_nestingLimit--;
bool success = parseAnythingToUnsafe(destination);
@ -32,9 +30,8 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
}
template <typename TReader, typename TWriter>
inline bool
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
JsonVariant *destination) {
inline bool ArduinoJson::Internals::JsonParser<
TReader, TWriter>::parseAnythingToUnsafe(JsonVariant *destination) {
skipSpacesAndComments(_reader);
switch (_reader.current()) {
@ -148,6 +145,7 @@ ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
typename TypeTraits::RemoveReference<TWriter>::type::String str =
_writer.startString();
skipSpacesAndComments(_reader);
char c = _reader.current();
if (isQuote(c)) { // quotes

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -10,34 +10,35 @@
namespace ArduinoJson {
namespace Internals {
template <typename TChar>
class StringWriter {
public:
class String {
public:
String(char** ptr) : _writePtr(ptr), _startPtr(*ptr) {}
String(TChar** ptr) : _writePtr(ptr), _startPtr(*ptr) {}
void append(char c) {
*(*_writePtr)++ = c;
*(*_writePtr)++ = TChar(c);
}
const char* c_str() const {
*(*_writePtr)++ = 0;
return _startPtr;
return reinterpret_cast<const char*>(_startPtr);
}
private:
char** _writePtr;
char* _startPtr;
TChar** _writePtr;
TChar* _startPtr;
};
StringWriter(char* buffer) : _ptr(buffer) {}
StringWriter(TChar* buffer) : _ptr(buffer) {}
String startString() {
return String(&_ptr);
}
private:
char* _ptr;
TChar* _ptr;
};
}
}

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -46,30 +46,35 @@ 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;
}
freeAllBlocks();
}
// 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() {
freeAllBlocks();
_head = 0;
}
class String {
public:
String(DynamicJsonBufferBase* parent)
@ -84,7 +89,7 @@ class DynamicJsonBufferBase
char* newStart =
static_cast<char*>(_parent->allocInNewBlock(_length + 1));
if (_start && newStart) memcpy(newStart, _start, _length);
newStart[_length] = c;
if (newStart) newStart[_length] = c;
_start = newStart;
}
_length++;
@ -98,7 +103,7 @@ class DynamicJsonBufferBase
private:
DynamicJsonBufferBase* _parent;
char* _start;
int _length;
size_t _length;
};
String startString() {
@ -129,7 +134,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;
@ -139,6 +144,16 @@ class DynamicJsonBufferBase
return true;
}
void freeAllBlocks() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
Block* nextBlock = currentBlock->next;
_allocator.deallocate(currentBlock);
currentBlock = nextBlock;
}
}
TAllocator _allocator;
Block* _head;
size_t _nextBlockCapacity;

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -39,19 +39,18 @@ 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
JsonVariant operator[](size_t index) const {
return get<JsonVariant>(index);
}
const JsonArraySubscript operator[](size_t index) const;
// Gets or sets the value at specified index
JsonArraySubscript operator[](size_t index);
@ -78,8 +77,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.
@ -113,16 +113,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.
@ -134,9 +133,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.
@ -195,33 +195,30 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
void copyTo(T (&array)[N1][N2]) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
it->asArray().copyTo(array[i++]);
it->as<JsonArray>().copyTo(array[i++]);
}
}
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

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -81,8 +81,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:
@ -101,15 +102,19 @@ inline JsonArraySubscript JsonArray::operator[](size_t index) {
return JsonArraySubscript(*this, index);
}
inline const JsonArraySubscript JsonArray::operator[](size_t index) const {
return JsonArraySubscript(*const_cast<JsonArray*>(this), index);
}
template <typename TImplem>
inline JsonArraySubscript JsonVariantBase<TImplem>::operator[](int index) {
return asArray()[index];
inline JsonArraySubscript JsonVariantBase<TImplem>::operator[](size_t index) {
return as<JsonArray>()[index];
}
template <typename TImplem>
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
int index) const {
return asArray()[index];
size_t index) const {
return as<JsonArray>()[index];
}
} // namespace ArduinoJson

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -11,6 +11,7 @@
#include <stdint.h> // for uint8_t
#include <string.h>
#include "Data/NonCopyable.hpp"
#include "JsonVariant.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsArray.hpp"
@ -34,7 +35,7 @@ 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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -38,13 +38,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.
//
@ -66,18 +68,24 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// Gets the value associated with the specified key.
//
// JsonVariant operator[](TKey) const;
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
const JsonVariant operator[](const TString& key) const {
return get_impl<const TString&, JsonVariant>(key);
typename TypeTraits::EnableIf<
!TypeTraits::IsArray<TString>::value,
const JsonObjectSubscript<const TString&> >::type
operator[](const TString& key) const {
return JsonObjectSubscript<const TString&>(*const_cast<JsonObject*>(this),
key);
}
//
// JsonVariant operator[](TKey) const;
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
const JsonVariant operator[](const TString* key) const {
return get_impl<const TString*, JsonVariant>(key);
const JsonObjectSubscript<const TString*> operator[](
const TString* key) const {
return JsonObjectSubscript<const TString*>(*const_cast<JsonObject*>(this),
key);
}
// Sets the specified key with the specified value.
@ -128,23 +136,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.
@ -241,14 +251,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.
@ -259,15 +269,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.
@ -280,41 +293,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

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -93,8 +93,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

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -17,6 +17,7 @@
#include "RawJson.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsChar.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsIntegral.hpp"
#include "TypeTraits/IsSame.hpp"
@ -39,8 +40,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
@ -51,31 +52,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;
@ -98,9 +107,16 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
}
// Create a JsonVariant containing a string.
JsonVariant(const char *value) {
// JsonVariant(const char*);
// JsonVariant(const signed char*);
// JsonVariant(const unsigned char*);
template <typename TChar>
JsonVariant(
const TChar *value,
typename TypeTraits::EnableIf<TypeTraits::IsChar<TChar>::value>::type * =
0) {
_type = Internals::JSON_STRING;
_content.asString = value;
_content.asString = reinterpret_cast<const char *>(value);
}
// Create a JsonVariant containing an unparsed string
@ -121,24 +137,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>(asInteger());
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;
@ -147,7 +165,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
T>::type
as() const {
return static_cast<T>(asFloat());
return variantAsFloat<T>();
}
//
// const char* as<const char*>() const;
@ -157,7 +175,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
TypeTraits::IsSame<T, char *>::value,
const char *>::type
as() const {
return asString();
return variantAsString();
}
//
// std::string as<std::string>() const;
@ -165,21 +183,13 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
template <typename T>
typename TypeTraits::EnableIf<Internals::StringTraits<T>::has_append, T>::type
as() const {
const char *cstr = asString();
const char *cstr = variantAsString();
if (cstr) return T(cstr);
T s;
printTo(s);
return s;
}
//
// const bool as<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
T>::type
as() const {
return asInteger() != 0;
}
//
// JsonArray& as<JsonArray> const;
// JsonArray& as<JsonArray&> const;
template <typename T>
@ -188,7 +198,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonArray>::value,
JsonArray &>::type
as() const {
return asArray();
return variantAsArray();
}
//
// const JsonArray& as<const JsonArray&> const;
@ -198,7 +208,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
const JsonArray>::value,
const JsonArray &>::type
as() const {
return asArray();
return variantAsArray();
}
//
// JsonObject& as<JsonObject> const;
@ -209,7 +219,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonObject>::value,
JsonObject &>::type
as() const {
return asObject();
return variantAsObject();
}
//
// JsonObject& as<const JsonObject> const;
@ -220,7 +230,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
const JsonObject>::value,
const JsonObject &>::type
as() const {
return asObject();
return variantAsObject();
}
//
// JsonVariant as<JsonVariant> const;
@ -234,32 +244,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;
@ -269,7 +282,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
TypeTraits::IsSame<T, char *>::value,
bool>::type
is() const {
return isString();
return variantIsString();
}
//
// bool is<JsonArray> const;
@ -283,7 +296,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonArray>::value,
bool>::type
is() const {
return isArray();
return variantIsArray();
}
//
// bool is<JsonObject> const;
@ -297,7 +310,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonObject>::value,
bool>::type
is() const {
return isObject();
return variantIsObject();
}
// Returns true if the variant has a value
@ -305,34 +318,24 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
return _type != Internals::JSON_UNDEFINED;
}
// DEPRECATED: use as<char*>() instead
const char *asString() const;
// DEPRECATED: use as<JsonArray>() instead
JsonArray &asArray() const;
// DEPRECATED: use as<JsonObject>() instead
JsonObject &asObject() const;
private:
// It's not allowed to store a char
JsonArray &variantAsArray() const;
JsonObject &variantAsObject() const;
const char *variantAsString() const;
template <typename T>
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsSame<T, char>::value>::type * = 0);
Internals::JsonFloat asFloat() const;
Internals::JsonInteger asInteger() const;
Internals::JsonUInt asUnsignedInteger() const;
bool isBoolean() const;
bool isFloat() const;
bool isInteger() const;
bool isArray() const {
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));
@ -345,11 +348,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

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -21,10 +21,22 @@ class JsonObjectSubscript;
template <typename TImpl>
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
public:
// DEPRECATED: use as<char*>() instead
#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
@ -34,11 +46,6 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
return as<JsonArray &>();
}
// DEPRECATED: use as<JsonArray>() instead
FORCE_INLINE JsonArray &asArray() const {
return as<JsonArray &>();
}
// Gets the variant as an object.
// Returns a reference to the JsonObject or JsonObject::invalid() if the
// variant is not an object.
@ -46,11 +53,6 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
return as<JsonObject &>();
}
// DEPRECATED: use as<JsonObject>() instead
FORCE_INLINE JsonObject &asObject() const {
return as<JsonObject &>();
}
template <typename T>
FORCE_INLINE operator T() const {
return as<T>();
@ -61,18 +63,23 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
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 asArray().size() + asObject().size();
return as<JsonArray>().size() + as<JsonObject>().size();
}
// Mimics an array.
// Returns the element at specified index if the variant is an array.
// Returns JsonVariant::invalid() if the variant is not an array.
FORCE_INLINE const JsonArraySubscript operator[](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
@ -86,27 +93,27 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<TString>::has_equals,
const JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) const {
return asObject()[key];
return as<JsonObject>()[key];
}
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = const std::string&, const String&
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<TString>::has_equals,
JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) {
return asObject()[key];
return as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
// TKey = const std::string&, const String&
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<TString *>::has_equals,
Internals::StringTraits<const TString *>::has_equals,
JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) {
return asObject()[key];
return as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
@ -116,7 +123,7 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<TString *>::has_equals,
const JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) const {
return asObject()[key];
return as<JsonObject>()[key];
}
private:
@ -124,4 +131,9 @@ 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

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

@ -2,19 +2,20 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "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 {
@ -37,56 +38,36 @@ inline JsonVariant::JsonVariant(const JsonObject &object) {
}
}
inline JsonArray &JsonVariant::asArray() const {
inline JsonArray &JsonVariant::variantAsArray() const {
if (_type == Internals::JSON_ARRAY) return *_content.asArray;
return JsonArray::invalid();
}
inline JsonObject &JsonVariant::asObject() const {
inline JsonObject &JsonVariant::variantAsObject() const {
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
return JsonObject::invalid();
}
inline Internals::JsonInteger JsonVariant::asInteger() 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);
return T(_content.asFloat);
}
}
inline Internals::JsonUInt JsonVariant::asUnsignedInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
case JSON_NEGATIVE_INTEGER:
return _content.asInteger;
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonUInt>(_content.asString);
default:
return static_cast<Internals::JsonUInt>(_content.asFloat);
}
}
inline const char *JsonVariant::asString() const {
inline const char *JsonVariant::variantAsString() const {
using namespace Internals;
if (_type == JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString))
@ -95,25 +76,26 @@ inline const char *JsonVariant::asString() const {
return NULL;
}
inline Internals::JsonFloat JsonVariant::asFloat() 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 +105,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,32 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#ifdef _MSC_VER // Visual Studio
#define FORCE_INLINE __forceinline
#define NO_INLINE __declspec(noinline)
#define DEPRECATED(msg) __declspec(deprecated(msg))
#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)
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
#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,21 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
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,41 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include <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,22 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "./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,22 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace 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,103 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
int16_t normalize(T& value) {
int16_t powersOf10 = 0;
if (value >= ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD) {
#if ARDUINOJSON_DOUBLE_IS_64BITS
if (value >= 1e256) {
value /= 1e256;
powersOf10 = int16_t(powersOf10 + 256);
}
if (value >= 1e128) {
value /= 1e128;
powersOf10 = int16_t(powersOf10 + 128);
}
if (value >= 1e64) {
value /= 1e64;
powersOf10 = int16_t(powersOf10 + 64);
}
#endif
if (value >= 1e32) {
value /= 1e32;
powersOf10 = int16_t(powersOf10 + 32);
}
if (value >= 1e16) {
value /= 1e16;
powersOf10 = int16_t(powersOf10 + 16);
}
if (value >= 1e8) {
value /= 1e8;
powersOf10 = int16_t(powersOf10 + 8);
}
if (value >= 1e4) {
value /= 1e4;
powersOf10 = int16_t(powersOf10 + 4);
}
if (value >= 1e2) {
value /= 1e2;
powersOf10 = int16_t(powersOf10 + 2);
}
if (value >= 1e1) {
value /= 1e1;
powersOf10 = int16_t(powersOf10 + 1);
}
}
if (value > 0 && value <= ARDUINOJSON_NEGATIVE_EXPONENTIATION_THRESHOLD) {
#if ARDUINOJSON_DOUBLE_IS_64BITS
if (value < 1e-255) {
value *= 1e256;
powersOf10 = int16_t(powersOf10 - 256);
}
if (value < 1e-127) {
value *= 1e128;
powersOf10 = int16_t(powersOf10 - 128);
}
if (value < 1e-63) {
value *= 1e64;
powersOf10 = int16_t(powersOf10 - 64);
}
#endif
if (value < 1e-31) {
value *= 1e32;
powersOf10 = int16_t(powersOf10 - 32);
}
if (value < 1e-15) {
value *= 1e16;
powersOf10 = int16_t(powersOf10 - 16);
}
if (value < 1e-7) {
value *= 1e8;
powersOf10 = int16_t(powersOf10 - 8);
}
if (value < 1e-3) {
value *= 1e4;
powersOf10 = int16_t(powersOf10 - 4);
}
if (value < 1e-1) {
value *= 1e2;
powersOf10 = int16_t(powersOf10 - 2);
}
if (value < 1e0) {
value *= 1e1;
powersOf10 = int16_t(powersOf10 - 1);
}
}
return powersOf10;
}
}
}

View File

@ -0,0 +1,90 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../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;
case '+':
s++;
}
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,42 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include <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;
case '+':
s++;
break;
}
while (isdigit(*s)) {
result = T(result * 10 + T(*s - '0'));
s++;
}
return negative_result ? T(~result + 1) : result;
}
}
}

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once

View File

@ -2,22 +2,24 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// 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

@ -2,12 +2,11 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
#include "../StringTraits/StringTraits.hpp"
namespace ArduinoJson {
@ -15,15 +14,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

@ -2,20 +2,19 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// 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 +22,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 +60,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;
}

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -31,9 +31,12 @@ namespace Internals {
template <typename T>
class JsonPrintable {
public:
size_t printTo(Print &print) const {
JsonWriter writer(print);
JsonSerializer::serialize(downcast(), writer);
template <typename Print>
typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value,
size_t>::type
printTo(Print &print) const {
JsonWriter<Print> writer(print);
JsonSerializer<JsonWriter<Print> >::serialize(downcast(), writer);
return writer.bytesWritten();
}
@ -62,8 +65,9 @@ class JsonPrintable {
return printTo(sb);
}
size_t prettyPrintTo(IndentedPrint &print) const {
Prettyfier p(print);
template <typename Print>
size_t prettyPrintTo(IndentedPrint<Print> &print) const {
Prettyfier<Print> p(print);
return printTo(p);
}
@ -77,8 +81,11 @@ class JsonPrintable {
return prettyPrintTo(buffer, N);
}
size_t prettyPrintTo(Print &print) const {
IndentedPrint indentedPrint = IndentedPrint(print);
template <typename Print>
typename TypeTraits::EnableIf<!TypeTraits::IsString<Print>::value,
size_t>::type
prettyPrintTo(Print &print) const {
IndentedPrint<Print> indentedPrint(print);
return prettyPrintTo(indentedPrint);
}

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -20,14 +20,15 @@ class JsonVariant;
namespace Internals {
template <typename Writer>
class JsonSerializer {
public:
static void serialize(const JsonArray &, JsonWriter &);
static void serialize(const JsonArraySubscript &, JsonWriter &);
static void serialize(const JsonObject &, JsonWriter &);
static void serialize(const JsonArray &, Writer &);
static void serialize(const JsonArraySubscript &, Writer &);
static void serialize(const JsonObject &, Writer &);
template <typename TKey>
static void serialize(const JsonObjectSubscript<TKey> &, JsonWriter &);
static void serialize(const JsonVariant &, JsonWriter &);
static void serialize(const JsonObjectSubscript<TKey> &, Writer &);
static void serialize(const JsonVariant &, Writer &);
};
}
}

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -14,8 +14,9 @@
#include "../JsonVariant.hpp"
#include "JsonSerializer.hpp"
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonArray& array, JsonWriter& writer) {
template <typename Writer>
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
const JsonArray& array, Writer& writer) {
writer.beginArray();
JsonArray::const_iterator it = array.begin();
@ -31,13 +32,15 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize(
writer.endArray();
}
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonArraySubscript& arraySubscript, JsonWriter& writer) {
template <typename Writer>
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
const JsonArraySubscript& arraySubscript, Writer& writer) {
serialize(arraySubscript.as<JsonVariant>(), writer);
}
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonObject& object, JsonWriter& writer) {
template <typename Writer>
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
const JsonObject& object, Writer& writer) {
writer.beginObject();
JsonObject::const_iterator it = object.begin();
@ -55,16 +58,19 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize(
writer.endObject();
}
template <typename Writer>
template <typename TKey>
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonObjectSubscript<TKey>& objectSubscript, JsonWriter& writer) {
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
const JsonObjectSubscript<TKey>& objectSubscript, Writer& writer) {
serialize(objectSubscript.template as<JsonVariant>(), writer);
}
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonVariant& variant, JsonWriter& writer) {
template <typename Writer>
inline void ArduinoJson::Internals::JsonSerializer<Writer>::serialize(
const JsonVariant& variant, Writer& writer) {
switch (variant._type) {
case JSON_UNDEFINED:
case JSON_FLOAT:
writer.writeFloat(variant._content.asFloat);
return;
case JSON_ARRAY:
@ -93,9 +99,7 @@ inline void ArduinoJson::Internals::JsonSerializer::serialize(
writer.writeBoolean(variant._content.asInteger != 0);
return;
default:
uint8_t decimals =
static_cast<uint8_t>(variant._type - JSON_FLOAT_0_DECIMALS);
writer.writeFloat(variant._content.asFloat, decimals);
default: // JSON_UNDEFINED
return;
}
}

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