forked from bblanchon/ArduinoJson
Compare commits
4 Commits
v5.8.0
...
v5.1.0-bet
Author | SHA1 | Date | |
---|---|---|---|
d655000467 | |||
428dddf2cc | |||
5f589d3836 | |||
ed4ec6ed2e |
@ -1,5 +1,4 @@
|
||||
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
|
||||
BasedOnStyle: Google
|
||||
Standard: Cpp03
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
Standard: Cpp03
|
11
.github/ISSUE_TEMPLATE.md
vendored
11
.github/ISSUE_TEMPLATE.md
vendored
@ -1,11 +0,0 @@
|
||||
<!--
|
||||
Thanks for using ArduinoJson :-)
|
||||
|
||||
Before opening an issue, please make sure you've read these:
|
||||
https://github.com/bblanchon/ArduinoJson/wiki/FAQ
|
||||
https://github.com/bblanchon/ArduinoJson/wiki/Avoiding-pitfalls
|
||||
|
||||
Next, make sure you provide all the relevant information: platform, code snippet, and error messages.
|
||||
|
||||
Please be concise!
|
||||
-->
|
@ -1,5 +0,0 @@
|
||||
.github/
|
||||
examples/
|
||||
scripts/
|
||||
test/
|
||||
third-party/
|
115
.travis.yml
115
.travis.yml
@ -1,110 +1,15 @@
|
||||
sudo: false
|
||||
language: cpp
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.4']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.4
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.5']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.5
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.6']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.6
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.7']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.7
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.8']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.8
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-4.9']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.9
|
||||
- compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test']
|
||||
packages: ['g++-5']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-5
|
||||
- compiler: clang
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
|
||||
packages: ['clang-3.5']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.5
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
|
||||
packages: ['clang-3.6']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.6
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
|
||||
packages: ['clang-3.7']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.7
|
||||
- compiler: clang
|
||||
addons:
|
||||
apt:
|
||||
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
|
||||
packages: ['clang-3.8']
|
||||
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.8
|
||||
- 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
|
||||
- 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
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.12 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=platformio BOARD=uno
|
||||
- env: SCRIPT=platformio BOARD=due
|
||||
- env: SCRIPT=platformio BOARD=esp01
|
||||
- env: SCRIPT=platformio BOARD=teensy31
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
script: scripts/travis/$SCRIPT.sh
|
||||
env:
|
||||
- COMPILER=gcc
|
||||
- COMPILER=clang
|
||||
- COMPILER=arduino VERSION=1.5.8 BOARD=arduino:avr:uno
|
||||
- COMPILER=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
|
||||
- COMPILER=platformio BOARD=uno
|
||||
- COMPILER=platformio BOARD=due
|
||||
- COMPILER=platformio BOARD=esp01
|
||||
- COMPILER=platformio BOARD=teensy31
|
||||
script: scripts/travis/$COMPILER.sh
|
||||
|
@ -5,4 +5,10 @@
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
// About this file
|
||||
// ---------------
|
||||
// This file is here for [PlatformIO](http://platformio.org/).
|
||||
// It must be present in the root for the tool to find it.
|
||||
// Feel free to ignore this file if your working in another environment.
|
||||
|
||||
#include "include/ArduinoJson.h"
|
||||
|
152
CHANGELOG.md
152
CHANGELOG.md
@ -1,150 +1,6 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
v5.8.0
|
||||
------
|
||||
|
||||
* Added operator `==` to compare `JsonVariant` and strings (issue #402)
|
||||
* Added support for `Stream` (issue #300)
|
||||
* Reduced memory consumption by not duplicating spaces and comments
|
||||
|
||||
v5.7.3
|
||||
------
|
||||
|
||||
* Added an `printTo(char[N])` and `prettyPrintTo(char[N])` (issue #292)
|
||||
* Added ability to set a nested value like this: `root["A"]["B"] = "C"` (issue #352)
|
||||
* Renamed `*.ipp` to `*Impl.hpp` because they were ignored by Arduino IDE (issue #396)
|
||||
|
||||
v5.7.2
|
||||
------
|
||||
|
||||
* Made PROGMEM available on more platforms (issue #381)
|
||||
* Fixed PROGMEM causing an exception on ESP8266 (issue #383)
|
||||
|
||||
v5.7.1
|
||||
------
|
||||
|
||||
* Added support for PROGMEM (issue #76)
|
||||
* Fixed compilation error when index is not an `int` (issue #381)
|
||||
|
||||
v5.7.0
|
||||
------
|
||||
|
||||
* Templatized all functions using `String` or `std::string`
|
||||
* Removed `ArduinoJson::String`
|
||||
* Removed `JsonVariant::defaultValue<T>()`
|
||||
* Removed non-template `JsonObject::get()` and `JsonArray.get()`
|
||||
* Fixed support for `StringSumHelper` (issue #184)
|
||||
* Replaced `ARDUINOJSON_USE_ARDUINO_STRING` by `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_ARDUINO_STRING` (issue #378)
|
||||
* Added example `StringExample.ino` to show where `String` can be used
|
||||
* Increased default nesting limit to 50 when compiled for a computer (issue #349)
|
||||
|
||||
**BREAKING CHANGES**:
|
||||
|
||||
The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
|
||||
|
||||
Old code:
|
||||
|
||||
```c++
|
||||
#define ARDUINOJSON_USE_ARDUINO_STRING 0
|
||||
JsonVariant value1 = myObject.get("myKey");
|
||||
JsonVariant value2 = myArray.get(0);
|
||||
```
|
||||
|
||||
New code:
|
||||
|
||||
```c++
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||
JsonVariant value1 = myObject.get<JsonVariant>("myKey");
|
||||
JsonVariant value2 = myArray.get<JsonVariant>(0);
|
||||
```
|
||||
|
||||
|
||||
v5.6.7
|
||||
------
|
||||
|
||||
* Fixed `array[idx].as<JsonVariant>()` and `object[key].as<JsonVariant>()`
|
||||
* Fixed return value of `JsonObject::set()` (issue #350)
|
||||
* Fixed undefined behavior in `Prettyfier` and `Print` (issue #354)
|
||||
* Fixed parser that incorrectly rejected floats containing a `+` (issue #349)
|
||||
|
||||
v5.6.6
|
||||
------
|
||||
|
||||
* Fixed `-Wparentheses` warning introduced in v5.6.5 (PR #335 by @nuket)
|
||||
* Added `.mbedignore` for ARM mbdeb (PR #334 by @nuket)
|
||||
* Fixed `JsonVariant::success()` which didn't propagate `JsonArray::success()` nor `JsonObject::success()` (issue #342).
|
||||
|
||||
v5.6.5
|
||||
------
|
||||
|
||||
* `as<char*>()` now returns `true` when input is `null` (issue #330)
|
||||
|
||||
v5.6.4
|
||||
------
|
||||
|
||||
* Fixed error in float serialization (issue #324)
|
||||
|
||||
v5.6.3
|
||||
------
|
||||
|
||||
* Improved speed of float serialization (about twice faster)
|
||||
* Added `as<JsonArray>()` as a synonym for `as<JsonArray&>()`... (issue #291)
|
||||
* Fixed `call of overloaded isinf(double&) is ambiguous` (issue #284)
|
||||
|
||||
v5.6.2
|
||||
------
|
||||
|
||||
* Fixed build when another lib does `#undef isnan` (issue #284)
|
||||
|
||||
v5.6.1
|
||||
------
|
||||
|
||||
* Added missing `#pragma once` (issue #310)
|
||||
|
||||
v5.6.0
|
||||
------
|
||||
|
||||
* ArduinoJson is now a header-only library (issue #199)
|
||||
|
||||
v5.5.1
|
||||
------
|
||||
|
||||
* Fixed compilation error with Intel Galileo (issue #299)
|
||||
|
||||
v5.5.0
|
||||
------
|
||||
|
||||
* Added `JsonVariant::success()` (issue #279)
|
||||
* Renamed `JsonVariant::invalid<T>()` to `JsonVariant::defaultValue<T>()`
|
||||
|
||||
v5.4.0
|
||||
------
|
||||
|
||||
* Changed `::String` to `ArduinoJson::String` (issue #275)
|
||||
* Changed `::Print` to `ArduinoJson::Print` too
|
||||
|
||||
v5.3.0
|
||||
------
|
||||
|
||||
* Added custom implementation of `ftoa` (issues #266, #267, #269 and #270)
|
||||
* Added `JsonVariant JsonBuffer::parse()` (issue #265)
|
||||
* Fixed `unsigned long` printed as `signed long` (issue #170)
|
||||
|
||||
v5.2.0
|
||||
------
|
||||
|
||||
* Added `JsonVariant::as<char*>()` as a synonym for `JsonVariant::as<const char*>()` (issue #257)
|
||||
* Added example `JsonHttpClient` (issue #256)
|
||||
* Added `JsonArray::copyTo()` and `JsonArray::copyFrom()` (issue #254)
|
||||
* Added `RawJson()` to insert pregenerated JSON portions (issue #259)
|
||||
|
||||
v5.1.1
|
||||
------
|
||||
|
||||
* Removed `String` duplication when one replaces a value in a `JsonObject` (PR #232 by @ulion)
|
||||
|
||||
v5.1.0
|
||||
------
|
||||
|
||||
@ -197,7 +53,7 @@ v5.0.3
|
||||
v5.0.2
|
||||
------
|
||||
|
||||
* Fixed segmentation fault in `parseObject(String)` and `parseArray(String)`, when the
|
||||
* Fixed segmentation fault in `parseObject(String)` and `parseArray(String)`, when the
|
||||
`StaticJsonBuffer` is too small to hold a copy of the string
|
||||
* Fixed Clang warning "register specifier is deprecated" (issue #102)
|
||||
* Fixed GCC warning "declaration shadows a member" (issue #103)
|
||||
@ -313,14 +169,14 @@ v3.1
|
||||
|
||||
Old generator API:
|
||||
|
||||
JsonObject<3> root;
|
||||
JsonObject<3> root;
|
||||
root.add("sensor", "gps");
|
||||
root.add("time", 1351824120);
|
||||
root.add("data", array);
|
||||
|
||||
New generator API:
|
||||
|
||||
JsonObject<3> root;
|
||||
JsonObject<3> root;
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
root["data"] = array;
|
||||
@ -377,7 +233,7 @@ v1.1
|
||||
* Example: changed `char* json` into `char[] json` so that the bytes are not write protected
|
||||
* Fixed parsing bug when the JSON contains multi-dimensional arrays
|
||||
|
||||
v1.0
|
||||
v1.0
|
||||
----
|
||||
|
||||
Initial release
|
||||
|
@ -5,7 +5,7 @@
|
||||
# https://github.com/bblanchon/ArduinoJson
|
||||
# If you like this project, please add a star!
|
||||
|
||||
cmake_minimum_required(VERSION 3.0)
|
||||
cmake_minimum_required(VERSION 2.8.12)
|
||||
project(ArduinoJson)
|
||||
|
||||
enable_testing()
|
||||
@ -18,8 +18,5 @@ if(${COVERAGE})
|
||||
set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
|
||||
endif()
|
||||
|
||||
if(${SANITIZE})
|
||||
set(CMAKE_CXX_FLAGS "-fsanitize=address,undefined")
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(test)
|
||||
|
52
README.md
52
README.md
@ -5,10 +5,9 @@ Arduino JSON library
|
||||
|
||||
*An elegant and efficient JSON library for embedded systems.*
|
||||
|
||||
It's designed to have the most intuitive API, the smallest footprint and is able to work without any allocation on the heap (no malloc).
|
||||
It's designed to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc).
|
||||
|
||||
It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project.
|
||||
For instance, it supports Aduino's `String` and `Stream`, but also `std::string`, `std::istream` and `std::ostream`.
|
||||
|
||||
Features
|
||||
--------
|
||||
@ -16,24 +15,21 @@ Features
|
||||
* JSON decoding (comments are supported)
|
||||
* JSON encoding (with optional indentation)
|
||||
* Elegant API, very easy to use
|
||||
* Fixed memory allocation (zero malloc)
|
||||
* No data duplication (zero copy)
|
||||
* Efficient (no malloc, nor copy)
|
||||
* Portable (written in C++98)
|
||||
* Self-contained (no external dependency)
|
||||
* Small footprint
|
||||
* Header-only library
|
||||
* MIT License
|
||||
|
||||
Works on
|
||||
--------
|
||||
|
||||
* All Arduino boards (Uno, Due, Mini, Micro, Yun...)
|
||||
* All Arduino boards
|
||||
* ESP8266
|
||||
* Teensy
|
||||
* Intel Edison and Galileo
|
||||
* Intel Edison
|
||||
* PlatformIO
|
||||
* Energia
|
||||
* RedBearLab boards (BLE Nano...)
|
||||
* Computers (Windows, Linux, OSX...)
|
||||
|
||||
See [FAQ: Compatibility issues](https://github.com/bblanchon/ArduinoJson/wiki/Compatibility-issues)
|
||||
@ -56,8 +52,6 @@ double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
```
|
||||
|
||||
[See JsonParserExample.ino](examples/JsonParserExample/JsonParserExample.ino)
|
||||
|
||||
#### Encoding / Generating
|
||||
|
||||
```c++
|
||||
@ -76,8 +70,6 @@ root.printTo(Serial);
|
||||
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
```
|
||||
|
||||
[See JsonGeneratorExample.ino](examples/JsonGeneratorExample/JsonGeneratorExample.ino)
|
||||
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
@ -91,48 +83,38 @@ From Arduino's Forum user `jflaplante`:
|
||||
> I tried aJson json-arduino before trying your library. I always ran into memory problem after a while.
|
||||
> I have no such problem so far with your library. It is working perfectly with my web services.
|
||||
|
||||
From Arduino's Forum user `gbathree`:
|
||||
> Thanks so much - this is an awesome library! If you want to see what we're doing with it - the project is located at www.photosynq.org.
|
||||
|
||||
From StackOverflow user `thegreendroid`:
|
||||
> It has a really elegant, simple API and it works like a charm on embedded and Windows/Linux platforms. We recently started using this on an embedded project and I can vouch for its quality.
|
||||
|
||||
From GitHub user `zacsketches`:
|
||||
|
||||
> Thanks for a great library!!!
|
||||
> I've been watching you consistently develop this library over the past six months, and I used it today for a publish and subscribe architecture designed to help hobbyists move into more advanced robotics. Your library allowed me to implement remote subscription in order to facilitate multi-processor robots.
|
||||
> ArduinoJson saved me a week's worth of time!!
|
||||
|
||||
[From Reddit user `erm_what_`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusjk8c):
|
||||
|
||||
> This is a great library and I wouldn't be able to do the project I'm doing without it. I completely recommend it.
|
||||
|
||||
[From Reddit user `makerhacks`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusqg7b):
|
||||
|
||||
> I am just starting an ESP8266 clock project and now I can output JSON from my server script and interpret it painlessly.
|
||||
|
||||
[From Twitter user `@hemalchevli`](https://twitter.com/hemalchevli/status/715788439397011456):
|
||||
> ArduinoJson library should be used as a benchmark/reference for making libraries. Truly elegant.
|
||||
|
||||
[From GitHub user `sticilface`](https://github.com/bblanchon/ArduinoJson/issues/381#issuecomment-260203594):
|
||||
> its a great lib:) and i use it in everything!
|
||||
|
||||
Donators
|
||||
--------
|
||||
|
||||
Special thanks to the following persons and companies who made generous donations to the library author:
|
||||
|
||||
* Robert Murphy <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
|
||||
* Surge Communications <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
|
||||
* Alex Scott <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
|
||||
* Firepick Services LLC <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
|
||||
* A B Doodkorte <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
|
||||
* Scott Smith <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
|
||||
* Johann Stieger <img alt='Austria' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e6-1f1f9.svg' width='18' height='18'>
|
||||
* Gustavo Donizeti Gini <img alt='Brazil' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e7-1f1f7.svg' width='18' height='18'>
|
||||
* Charles-Henri Hallard <img alt='France' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1eb-1f1f7.svg' width='18' height='18'>
|
||||
* Martijn van den Burg <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
|
||||
* Nick Koumaris <img alt='Greece' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1f7.svg' width='18' height='18'>
|
||||
* Jon Williams <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
|
||||
* Kestutis Liaugminas <img alt='Lithuania' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f1-1f1f9.svg' width='18' height='18'>
|
||||
* Darlington Adibe <img alt='Nigeria' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1ec.svg' width='18' height='18'>
|
||||
* Yoeri Kroon <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
|
||||
* Andrew Melvin <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
|
||||
* Doanh Luong <img alt ='Vietnam' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fb-1f1f3.svg' width='18' height='18'>
|
||||
* Robert Murphy
|
||||
* Surge Communications
|
||||
* Alex Scott
|
||||
* Firepick Services LLC
|
||||
* A B Doodkorte
|
||||
* Scott Smith
|
||||
* Johann Stieger
|
||||
|
||||
---
|
||||
|
||||
|
@ -1,13 +1,11 @@
|
||||
version: 5.8.0.{build}
|
||||
version: 5.1.0.{build}
|
||||
environment:
|
||||
matrix:
|
||||
- CMAKE_GENERATOR: Visual Studio 14 2015
|
||||
- CMAKE_GENERATOR: Visual Studio 12 2013
|
||||
- CMAKE_GENERATOR: Visual Studio 11 2012
|
||||
- CMAKE_GENERATOR: Visual Studio 10 2010
|
||||
# - CMAKE_GENERATOR: MinGW Makefiles
|
||||
# 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 +13,4 @@ before_build:
|
||||
build_script:
|
||||
- cmake --build . --config %CONFIGURATION%
|
||||
test_script:
|
||||
- ctest -V .
|
||||
- ctest -V .
|
||||
|
@ -1,184 +0,0 @@
|
||||
// Sample Arduino Json Web Client
|
||||
// Downloads and parse http://jsonplaceholder.typicode.com/users/1
|
||||
//
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <Ethernet.h>
|
||||
#include <SPI.h>
|
||||
|
||||
EthernetClient client;
|
||||
|
||||
const char* server = "jsonplaceholder.typicode.com"; // server's address
|
||||
const char* resource = "/users/1"; // http resource
|
||||
const unsigned long BAUD_RATE = 9600; // serial connection speed
|
||||
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
|
||||
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
|
||||
|
||||
// The type of data that we want to extract from the page
|
||||
struct UserData {
|
||||
char name[32];
|
||||
char company[32];
|
||||
};
|
||||
|
||||
// ARDUINO entry point #1: runs once when you press reset or power the board
|
||||
void setup() {
|
||||
initSerial();
|
||||
initEthernet();
|
||||
}
|
||||
|
||||
// ARDUINO entry point #2: runs over and over again forever
|
||||
void loop() {
|
||||
if (connect(server)) {
|
||||
if (sendRequest(server, resource) && skipResponseHeaders()) {
|
||||
UserData userData;
|
||||
if (readReponseContent(&userData)) {
|
||||
printUserData(&userData);
|
||||
}
|
||||
}
|
||||
disconnect();
|
||||
}
|
||||
wait();
|
||||
}
|
||||
|
||||
// Initialize Serial port
|
||||
void initSerial() {
|
||||
Serial.begin(BAUD_RATE);
|
||||
while (!Serial) {
|
||||
; // wait for serial port to initialize
|
||||
}
|
||||
Serial.println("Serial ready");
|
||||
}
|
||||
|
||||
// Initialize Ethernet library
|
||||
void initEthernet() {
|
||||
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
|
||||
if (!Ethernet.begin(mac)) {
|
||||
Serial.println("Failed to configure Ethernet");
|
||||
return;
|
||||
}
|
||||
Serial.println("Ethernet ready");
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// Open connection to the HTTP server
|
||||
bool connect(const char* hostName) {
|
||||
Serial.print("Connect to ");
|
||||
Serial.println(hostName);
|
||||
|
||||
bool ok = client.connect(hostName, 80);
|
||||
|
||||
Serial.println(ok ? "Connected" : "Connection Failed!");
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Send the HTTP GET request to the server
|
||||
bool sendRequest(const char* host, const char* resource) {
|
||||
Serial.print("GET ");
|
||||
Serial.println(resource);
|
||||
|
||||
client.print("GET ");
|
||||
client.print(resource);
|
||||
client.println(" HTTP/1.0");
|
||||
client.print("Host: ");
|
||||
client.println(host);
|
||||
client.println("Connection: close");
|
||||
client.println();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Skip HTTP headers so that we are at the beginning of the response's body
|
||||
bool skipResponseHeaders() {
|
||||
// HTTP headers end with an empty line
|
||||
char endOfHeaders[] = "\r\n\r\n";
|
||||
|
||||
client.setTimeout(HTTP_TIMEOUT);
|
||||
bool ok = client.find(endOfHeaders);
|
||||
|
||||
if (!ok) {
|
||||
Serial.println("No response or invalid response!");
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Parse the JSON from the input string and extract the interesting values
|
||||
// Here is the JSON we need to parse
|
||||
// {
|
||||
// "id": 1,
|
||||
// "name": "Leanne Graham",
|
||||
// "username": "Bret",
|
||||
// "email": "Sincere@april.biz",
|
||||
// "address": {
|
||||
// "street": "Kulas Light",
|
||||
// "suite": "Apt. 556",
|
||||
// "city": "Gwenborough",
|
||||
// "zipcode": "92998-3874",
|
||||
// "geo": {
|
||||
// "lat": "-37.3159",
|
||||
// "lng": "81.1496"
|
||||
// }
|
||||
// },
|
||||
// "phone": "1-770-736-8031 x56442",
|
||||
// "website": "hildegard.org",
|
||||
// "company": {
|
||||
// "name": "Romaguera-Crona",
|
||||
// "catchPhrase": "Multi-layered client-server neural-net",
|
||||
// "bs": "harness real-time e-markets"
|
||||
// }
|
||||
// }
|
||||
bool readReponseContent(struct UserData* userData) {
|
||||
// Compute optimal size of the JSON buffer according to what we need to parse.
|
||||
// This is only required if you use StaticJsonBuffer.
|
||||
const size_t BUFFER_SIZE =
|
||||
JSON_OBJECT_SIZE(8) // the root object has 8 elements
|
||||
+ JSON_OBJECT_SIZE(5) // the "address" object has 5 elements
|
||||
+ JSON_OBJECT_SIZE(2) // the "geo" object has 2 elements
|
||||
+ JSON_OBJECT_SIZE(3) // the "company" object has 3 elements
|
||||
+ MAX_CONTENT_SIZE; // additional space for strings
|
||||
|
||||
// Allocate a temporary memory pool
|
||||
DynamicJsonBuffer jsonBuffer(BUFFER_SIZE);
|
||||
|
||||
JsonObject& root = jsonBuffer.parseObject(client);
|
||||
|
||||
if (!root.success()) {
|
||||
Serial.println("JSON parsing failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Here were copy the strings we're interested in
|
||||
strcpy(userData->name, root["name"]);
|
||||
strcpy(userData->company, root["company"]["name"]);
|
||||
// It's not mandatory to make a copy, you could just use the pointers
|
||||
// Since, they are pointing inside the "content" buffer, so you need to make
|
||||
// sure it's still in memory when you read the string
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Print the data extracted from the JSON
|
||||
void printUserData(const struct UserData* userData) {
|
||||
Serial.print("Name = ");
|
||||
Serial.println(userData->name);
|
||||
Serial.print("Company = ");
|
||||
Serial.println(userData->company);
|
||||
}
|
||||
|
||||
// Close the connection with the HTTP server
|
||||
void disconnect() {
|
||||
Serial.println("Disconnect");
|
||||
client.stop();
|
||||
}
|
||||
|
||||
// Pause for a 1 minute
|
||||
void wait() {
|
||||
Serial.println("Wait 60 seconds");
|
||||
delay(60000);
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// About
|
||||
// -----
|
||||
// This example shows the different ways you can use PROGMEM with ArduinoJson.
|
||||
// Please don't see this as an invitation to use PROGMEM.
|
||||
// On the contrary, you should always use char[] when possible, it's much more
|
||||
// efficient in term of code size, speed and memory usage.
|
||||
|
||||
void setup() {
|
||||
#ifdef PROGMEM
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
|
||||
// You can use a Flash String as your JSON input.
|
||||
// WARNING: the content of the Flash String will be duplicated in the
|
||||
// JsonBuffer.
|
||||
JsonObject& root =
|
||||
jsonBuffer.parseObject(F("{\"sensor\":\"gps\",\"time\":1351824120,"
|
||||
"\"data\":[48.756080,2.302038]}"));
|
||||
|
||||
// You can use a Flash String to get an element of a JsonObject
|
||||
// No duplication is done.
|
||||
long time = root[F("time")];
|
||||
|
||||
// You can use a Flash String to set an element of a JsonObject
|
||||
// WARNING: the content of the Flash String will be duplicated in the
|
||||
// JsonBuffer.
|
||||
root[F("time")] = time;
|
||||
|
||||
// You can set a Flash String to a JsonObject or JsonArray:
|
||||
// WARNING: the content of the Flash String will be duplicated in the
|
||||
// JsonBuffer.
|
||||
root["sensor"] = F("gps");
|
||||
|
||||
// You can compare the content of a JsonVariant to a Flash String
|
||||
if (root["sensor"] == F("gps")) {
|
||||
// ...
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#warning PROGMEM is not supported on this platform
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
// About
|
||||
// -----
|
||||
// This example shows the different ways you can use String with ArduinoJson.
|
||||
// Please don't see this as an invitation to use String.
|
||||
// On the contrary, you should always use char[] when possible, it's much more
|
||||
// efficient in term of code size, speed and memory usage.
|
||||
|
||||
void setup() {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
|
||||
// You can use a String as your JSON input.
|
||||
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
||||
String input =
|
||||
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
JsonObject& root = jsonBuffer.parseObject(input);
|
||||
|
||||
// You can use a String to get an element of a JsonObject
|
||||
// No duplication is done.
|
||||
long time = root[String("time")];
|
||||
|
||||
// You can use a String to set an element of a JsonObject
|
||||
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
||||
root[String("time")] = time;
|
||||
|
||||
// You can get a String from a JsonObject or JsonArray:
|
||||
// No duplication is done, at least not in the JsonBuffer.
|
||||
String sensor = root["sensor"];
|
||||
|
||||
// Unfortunately, the following doesn't work (issue #118):
|
||||
// sensor = root["sensor"]; // <- error "ambiguous overload for 'operator='"
|
||||
// As a workaround, you need to replace by:
|
||||
sensor = root["sensor"].as<String>();
|
||||
|
||||
// You can set a String to a JsonObject or JsonArray:
|
||||
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
||||
root["sensor"] = sensor;
|
||||
|
||||
// You can also concatenate strings
|
||||
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
||||
root[String("sen") + "sor"] = String("gp") + "s";
|
||||
|
||||
// You can compare the content of a JsonObject with a String
|
||||
if (root["sensor"] == sensor) {
|
||||
// ...
|
||||
}
|
||||
|
||||
// Lastly, you can print the resulting JSON to a String
|
||||
String output;
|
||||
root.printTo(output);
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
@ -5,5 +5,9 @@
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include "ArduinoJson.hpp"
|
||||
#include "ArduinoJson/DynamicJsonBuffer.hpp"
|
||||
#include "ArduinoJson/JsonArray.hpp"
|
||||
#include "ArduinoJson/JsonObject.hpp"
|
||||
#include "ArduinoJson/StaticJsonBuffer.hpp"
|
||||
|
||||
using namespace ArduinoJson;
|
||||
|
@ -1,23 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ArduinoJson/DynamicJsonBuffer.hpp"
|
||||
#include "ArduinoJson/JsonArray.hpp"
|
||||
#include "ArduinoJson/JsonObject.hpp"
|
||||
#include "ArduinoJson/JsonVariantComparisons.hpp"
|
||||
#include "ArduinoJson/StaticJsonBuffer.hpp"
|
||||
|
||||
#include "ArduinoJson/Deserialization/JsonParserImpl.hpp"
|
||||
#include "ArduinoJson/JsonArrayImpl.hpp"
|
||||
#include "ArduinoJson/JsonBufferImpl.hpp"
|
||||
#include "ArduinoJson/JsonObjectImpl.hpp"
|
||||
#include "ArduinoJson/JsonVariantImpl.hpp"
|
||||
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"
|
||||
|
||||
using namespace ArduinoJson;
|
89
include/ArduinoJson/Arduino/Print.hpp
Normal file
89
include/ArduinoJson/Arduino/Print.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
#include "../Internals/JsonFloat.hpp"
|
||||
#include "../Internals/JsonInteger.hpp"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1800
|
||||
// snprintf has been added in Visual Studio 2015
|
||||
#define ARDUINOJSON_SNPRINTF _snprintf
|
||||
#else
|
||||
#define ARDUINOJSON_SNPRINTF snprintf
|
||||
#endif
|
||||
|
||||
// This class reproduces Arduino's Print class
|
||||
class Print {
|
||||
public:
|
||||
virtual ~Print() {}
|
||||
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
|
||||
size_t print(const char* s) {
|
||||
size_t n = 0;
|
||||
while (*s) {
|
||||
n += write(*s++);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t print(ArduinoJson::Internals::JsonFloat value, int digits = 2) {
|
||||
char tmp[32];
|
||||
|
||||
// https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware/arduino/sam/cores/arduino/Print.cpp#L220
|
||||
bool isBigDouble = value > 4294967040.0 || value < -4294967040.0;
|
||||
|
||||
if (isBigDouble) {
|
||||
// Arduino's implementation prints "ovf"
|
||||
// We prefer using the scientific notation, since we have sprintf
|
||||
ARDUINOJSON_SNPRINTF(tmp, sizeof(tmp), "%g", value);
|
||||
} else {
|
||||
// Here we have the exact same output as Arduino's implementation
|
||||
ARDUINOJSON_SNPRINTF(tmp, sizeof(tmp), "%.*f", digits, value);
|
||||
}
|
||||
|
||||
return print(tmp);
|
||||
}
|
||||
|
||||
size_t print(ArduinoJson::Internals::JsonInteger value) {
|
||||
// see http://clc-wiki.net/wiki/K%26R2_solutions:Chapter_3:Exercise_4
|
||||
char buffer[22];
|
||||
|
||||
size_t n = 0;
|
||||
if (value < 0) {
|
||||
value = -value;
|
||||
n += write('-');
|
||||
}
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
ArduinoJson::Internals::JsonInteger digit = value % 10;
|
||||
value /= 10;
|
||||
buffer[i++] = static_cast<char>(digit >= 0 ? '0' + digit : '0' - digit);
|
||||
} while (value);
|
||||
|
||||
while (i > 0) {
|
||||
n += write(buffer[--i]);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t println() { return write('\r') + write('\n'); }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <Print.h>
|
||||
|
||||
#endif
|
19
include/ArduinoJson/Arduino/String.hpp
Normal file
19
include/ArduinoJson/Arduino/String.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
#include <string>
|
||||
typedef std::string String;
|
||||
|
||||
#else
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#endif
|
@ -22,30 +22,7 @@
|
||||
#define ARDUINOJSON_USE_INT64 0
|
||||
#endif
|
||||
|
||||
// Arduino has its own implementation of String to replace std::string
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
|
||||
#endif
|
||||
|
||||
// On AVR archiecture, we can use PROGMEM
|
||||
#ifndef ARDUINOJSON_ENABLE_PROGMEM
|
||||
#ifdef PROGMEM
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 1
|
||||
#else
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Arduino doesn't have std::string
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 0
|
||||
#endif
|
||||
|
||||
// Arduino doesn't support STL stream
|
||||
// arduino doesn't support STL stream
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||
#endif
|
||||
@ -60,11 +37,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// low value to prevent stack overflow
|
||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
|
||||
#endif
|
||||
|
||||
#else // assume this is a computer
|
||||
|
||||
// on a computer we have plenty of memory so we can use doubles
|
||||
@ -90,41 +62,16 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// on a computer, we can use std::string
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STRING
|
||||
#define ARDUINOJSON_ENABLE_STD_STRING 1
|
||||
#endif
|
||||
|
||||
// on a computer, there is no reason to beleive Arduino String is available
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
|
||||
#endif
|
||||
|
||||
// PROGMEM is only available on AVR architecture
|
||||
#ifndef ARDUINOJSON_ENABLE_PROGMEM
|
||||
#define ARDUINOJSON_ENABLE_PROGMEM 0
|
||||
#endif
|
||||
|
||||
// on a computer, we can assume that the STL is there
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||
#endif
|
||||
|
||||
// on a computer, there is no reason to beleive Arduino Stream is available
|
||||
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
|
||||
// even if not required, most cpu's are faster with aligned pointers
|
||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
|
||||
#endif
|
||||
|
||||
// on a computer, we should have a lot of space on the stack
|
||||
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
|
||||
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
|
||||
|
@ -1,45 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A metafunction that returns the type of the value returned by
|
||||
// JsonVariant::as<T>()
|
||||
template <typename T>
|
||||
struct JsonVariantAs {
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantAs<char*> {
|
||||
typedef const char* type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantAs<JsonArray> {
|
||||
typedef JsonArray& type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantAs<const JsonArray> {
|
||||
typedef const JsonArray& type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantAs<JsonObject> {
|
||||
typedef JsonObject& type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct JsonVariantAs<const JsonObject> {
|
||||
typedef const JsonObject& type;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename T>
|
||||
struct JsonVariantDefault {
|
||||
static T get() {
|
||||
return T();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct JsonVariantDefault<const T> : JsonVariantDefault<T> {};
|
||||
|
||||
template <typename T>
|
||||
struct JsonVariantDefault<T&> : JsonVariantDefault<T> {};
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
#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<
|
||||
StringFuncs<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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
template <typename TInput>
|
||||
void skipSpacesAndComments(TInput& input) {
|
||||
for (;;) {
|
||||
switch (input.current()) {
|
||||
// spaces
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
input.move();
|
||||
continue;
|
||||
|
||||
// comments
|
||||
case '/':
|
||||
switch (input.next()) {
|
||||
// C-style block comment
|
||||
case '*':
|
||||
input.move(); // skip '/'
|
||||
input.move(); // skip '*'
|
||||
for (;;) {
|
||||
switch (input.current()) {
|
||||
case '\0':
|
||||
return;
|
||||
case '*':
|
||||
input.move(); // skip '*'
|
||||
if (input.current() == '/') {
|
||||
input.move(); // skip '/'
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
input.move();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// C++-style line comment
|
||||
case '/':
|
||||
input.move(); // skip '/'
|
||||
for (;;) {
|
||||
switch (input.current()) {
|
||||
case '\0':
|
||||
return;
|
||||
case '\n':
|
||||
input.move();
|
||||
return;
|
||||
default:
|
||||
input.move();
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
// not a comment, just a '/'
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,108 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "StringReader.hpp"
|
||||
#include "StringWriter.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Parse JSON string to create JsonArrays and JsonObjects
|
||||
// This internal class is not indended to be used directly.
|
||||
// Instead, use JsonBuffer.parseArray() or .parseObject()
|
||||
template <typename TReader, typename TWriter>
|
||||
class JsonParser {
|
||||
public:
|
||||
JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer,
|
||||
uint8_t nestingLimit)
|
||||
: _buffer(buffer),
|
||||
_reader(reader),
|
||||
_writer(writer),
|
||||
_nestingLimit(nestingLimit) {}
|
||||
|
||||
JsonArray &parseArray();
|
||||
JsonObject &parseObject();
|
||||
|
||||
JsonVariant parseVariant() {
|
||||
JsonVariant result;
|
||||
parseAnythingTo(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
JsonParser &operator=(const JsonParser &); // non-copiable
|
||||
|
||||
static bool eat(TReader &, char charToSkip);
|
||||
FORCE_INLINE bool eat(char charToSkip) {
|
||||
return eat(_reader, charToSkip);
|
||||
}
|
||||
|
||||
const char *parseString();
|
||||
bool parseAnythingTo(JsonVariant *destination);
|
||||
FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
|
||||
|
||||
inline bool parseArrayTo(JsonVariant *destination);
|
||||
inline bool parseObjectTo(JsonVariant *destination);
|
||||
inline bool parseStringTo(JsonVariant *destination);
|
||||
|
||||
static inline bool isInRange(char c, char min, char max) {
|
||||
return min <= c && c <= max;
|
||||
}
|
||||
|
||||
static inline bool isLetterOrNumber(char c) {
|
||||
return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') ||
|
||||
isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.';
|
||||
}
|
||||
|
||||
static inline bool isQuote(char c) {
|
||||
return c == '\'' || c == '\"';
|
||||
}
|
||||
|
||||
JsonBuffer *_buffer;
|
||||
TReader _reader;
|
||||
TWriter _writer;
|
||||
uint8_t _nestingLimit;
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TString>
|
||||
struct JsonParserBuilder {
|
||||
typedef typename Internals::StringFuncs<TString>::Iterator InputIterator;
|
||||
typedef JsonParser<StringReader<InputIterator>, TJsonBuffer &> TParser;
|
||||
|
||||
static TParser makeParser(TJsonBuffer *buffer, TString &json,
|
||||
uint8_t nestingLimit) {
|
||||
return TParser(buffer, InputIterator(json), *buffer, nestingLimit);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer>
|
||||
struct JsonParserBuilder<TJsonBuffer, char *> {
|
||||
typedef typename Internals::StringFuncs<char *>::Iterator InputIterator;
|
||||
typedef JsonParser<StringReader<InputIterator>, StringWriter> TParser;
|
||||
|
||||
static TParser makeParser(TJsonBuffer *buffer, char *json,
|
||||
uint8_t nestingLimit) {
|
||||
return TParser(buffer, InputIterator(json), json, nestingLimit);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, size_t N>
|
||||
struct JsonParserBuilder<TJsonBuffer, char[N]>
|
||||
: JsonParserBuilder<TJsonBuffer, char *> {};
|
||||
|
||||
template <typename TJsonBuffer, typename TString>
|
||||
inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser(
|
||||
TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) {
|
||||
return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json,
|
||||
nestingLimit);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,196 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Comments.hpp"
|
||||
#include "JsonParser.hpp"
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat(
|
||||
TReader &reader, char charToSkip) {
|
||||
skipSpacesAndComments(reader);
|
||||
if (reader.current() != charToSkip) return false;
|
||||
reader.move();
|
||||
skipSpacesAndComments(reader);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingTo(
|
||||
JsonVariant *destination) {
|
||||
if (_nestingLimit == 0) return false;
|
||||
_nestingLimit--;
|
||||
bool success = parseAnythingToUnsafe(destination);
|
||||
_nestingLimit++;
|
||||
return success;
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseAnythingToUnsafe(
|
||||
JsonVariant *destination) {
|
||||
skipSpacesAndComments(_reader);
|
||||
|
||||
switch (_reader.current()) {
|
||||
case '[':
|
||||
return parseArrayTo(destination);
|
||||
|
||||
case '{':
|
||||
return parseObjectTo(destination);
|
||||
|
||||
default:
|
||||
return parseStringTo(destination);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline ArduinoJson::JsonArray &
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray() {
|
||||
// Create an empty array
|
||||
JsonArray &array = _buffer->createArray();
|
||||
|
||||
// Check opening braket
|
||||
if (!eat('[')) goto ERROR_MISSING_BRACKET;
|
||||
if (eat(']')) goto SUCCESS_EMPTY_ARRAY;
|
||||
|
||||
// Read each value
|
||||
for (;;) {
|
||||
// 1 - Parse value
|
||||
JsonVariant value;
|
||||
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
|
||||
if (!array.add(value)) goto ERROR_NO_MEMORY;
|
||||
|
||||
// 2 - More values?
|
||||
if (eat(']')) goto SUCCES_NON_EMPTY_ARRAY;
|
||||
if (!eat(',')) goto ERROR_MISSING_COMMA;
|
||||
}
|
||||
|
||||
SUCCESS_EMPTY_ARRAY:
|
||||
SUCCES_NON_EMPTY_ARRAY:
|
||||
return array;
|
||||
|
||||
ERROR_INVALID_VALUE:
|
||||
ERROR_MISSING_BRACKET:
|
||||
ERROR_MISSING_COMMA:
|
||||
ERROR_NO_MEMORY:
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArrayTo(
|
||||
JsonVariant *destination) {
|
||||
JsonArray &array = parseArray();
|
||||
if (!array.success()) return false;
|
||||
|
||||
*destination = array;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline ArduinoJson::JsonObject &
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject() {
|
||||
// Create an empty object
|
||||
JsonObject &object = _buffer->createObject();
|
||||
|
||||
// Check opening brace
|
||||
if (!eat('{')) goto ERROR_MISSING_BRACE;
|
||||
if (eat('}')) goto SUCCESS_EMPTY_OBJECT;
|
||||
|
||||
// Read each key value pair
|
||||
for (;;) {
|
||||
// 1 - Parse key
|
||||
const char *key = parseString();
|
||||
if (!key) goto ERROR_INVALID_KEY;
|
||||
if (!eat(':')) goto ERROR_MISSING_COLON;
|
||||
|
||||
// 2 - Parse value
|
||||
JsonVariant value;
|
||||
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
|
||||
if (!object.set(key, value)) goto ERROR_NO_MEMORY;
|
||||
|
||||
// 3 - More keys/values?
|
||||
if (eat('}')) goto SUCCESS_NON_EMPTY_OBJECT;
|
||||
if (!eat(',')) goto ERROR_MISSING_COMMA;
|
||||
}
|
||||
|
||||
SUCCESS_EMPTY_OBJECT:
|
||||
SUCCESS_NON_EMPTY_OBJECT:
|
||||
return object;
|
||||
|
||||
ERROR_INVALID_KEY:
|
||||
ERROR_INVALID_VALUE:
|
||||
ERROR_MISSING_BRACE:
|
||||
ERROR_MISSING_COLON:
|
||||
ERROR_MISSING_COMMA:
|
||||
ERROR_NO_MEMORY:
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObjectTo(
|
||||
JsonVariant *destination) {
|
||||
JsonObject &object = parseObject();
|
||||
if (!object.success()) return false;
|
||||
|
||||
*destination = object;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline const char *
|
||||
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
|
||||
typename TypeTraits::RemoveReference<TWriter>::type::String str =
|
||||
_writer.startString();
|
||||
|
||||
char c = _reader.current();
|
||||
|
||||
if (isQuote(c)) { // quotes
|
||||
_reader.move();
|
||||
char stopChar = c;
|
||||
for (;;) {
|
||||
c = _reader.current();
|
||||
if (c == '\0') break;
|
||||
_reader.move();
|
||||
|
||||
if (c == stopChar) break;
|
||||
|
||||
if (c == '\\') {
|
||||
// replace char
|
||||
c = Encoding::unescapeChar(_reader.current());
|
||||
if (c == '\0') break;
|
||||
_reader.move();
|
||||
}
|
||||
|
||||
str.append(c);
|
||||
}
|
||||
} else { // no quotes
|
||||
for (;;) {
|
||||
if (!isLetterOrNumber(c)) break;
|
||||
_reader.move();
|
||||
str.append(c);
|
||||
c = _reader.current();
|
||||
}
|
||||
}
|
||||
|
||||
return str.c_str();
|
||||
}
|
||||
|
||||
template <typename TReader, typename TWriter>
|
||||
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseStringTo(
|
||||
JsonVariant *destination) {
|
||||
bool hasQuotes = isQuote(_reader.current());
|
||||
const char *value = parseString();
|
||||
if (value == NULL) return false;
|
||||
if (hasQuotes) {
|
||||
*destination = value;
|
||||
} else {
|
||||
*destination = RawJson(value);
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// 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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
class StringWriter {
|
||||
public:
|
||||
class String {
|
||||
public:
|
||||
String(char** ptr) : _writePtr(ptr), _startPtr(*ptr) {}
|
||||
|
||||
void append(char c) {
|
||||
*(*_writePtr)++ = c;
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
*(*_writePtr)++ = 0;
|
||||
return _startPtr;
|
||||
}
|
||||
|
||||
private:
|
||||
char** _writePtr;
|
||||
char* _startPtr;
|
||||
};
|
||||
|
||||
StringWriter(char* buffer) : _ptr(buffer) {}
|
||||
|
||||
String startString() {
|
||||
return String(&_ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
char* _ptr;
|
||||
};
|
||||
}
|
||||
}
|
@ -7,153 +7,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonBufferBase.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
#include "Internals/BlockJsonBuffer.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
class DefaultAllocator {
|
||||
public:
|
||||
void* allocate(size_t size) {
|
||||
return malloc(size);
|
||||
}
|
||||
void deallocate(void* pointer) {
|
||||
free(pointer);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TAllocator>
|
||||
class DynamicJsonBufferBase
|
||||
: public JsonBufferBase<DynamicJsonBufferBase<TAllocator> > {
|
||||
struct Block;
|
||||
struct EmptyBlock {
|
||||
Block* next;
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
};
|
||||
struct Block : EmptyBlock {
|
||||
uint8_t data[1];
|
||||
};
|
||||
|
||||
public:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
size_t total = 0;
|
||||
for (const Block* b = _head; b; b = b->next) total += b->size;
|
||||
return total;
|
||||
}
|
||||
|
||||
virtual void* alloc(size_t bytes) {
|
||||
alignNextAlloc();
|
||||
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
|
||||
}
|
||||
|
||||
class String {
|
||||
public:
|
||||
String(DynamicJsonBufferBase* parent)
|
||||
: _parent(parent), _start(NULL), _length(0) {}
|
||||
|
||||
void append(char c) {
|
||||
if (_parent->canAllocInHead(1)) {
|
||||
char* end = static_cast<char*>(_parent->allocInHead(1));
|
||||
*end = c;
|
||||
if (_length == 0) _start = end;
|
||||
} else {
|
||||
char* newStart =
|
||||
static_cast<char*>(_parent->allocInNewBlock(_length + 1));
|
||||
if (_start && newStart) memcpy(newStart, _start, _length);
|
||||
newStart[_length] = c;
|
||||
_start = newStart;
|
||||
}
|
||||
_length++;
|
||||
}
|
||||
|
||||
const char* c_str() {
|
||||
append(0);
|
||||
return _start;
|
||||
}
|
||||
|
||||
private:
|
||||
DynamicJsonBufferBase* _parent;
|
||||
char* _start;
|
||||
int _length;
|
||||
};
|
||||
|
||||
String startString() {
|
||||
return String(this);
|
||||
}
|
||||
|
||||
private:
|
||||
void alignNextAlloc() {
|
||||
if (_head) _head->size = this->round_size_up(_head->size);
|
||||
}
|
||||
|
||||
bool canAllocInHead(size_t bytes) const {
|
||||
return _head != NULL && _head->size + bytes <= _head->capacity;
|
||||
}
|
||||
|
||||
void* allocInHead(size_t bytes) {
|
||||
void* p = _head->data + _head->size;
|
||||
_head->size += bytes;
|
||||
return p;
|
||||
}
|
||||
|
||||
void* allocInNewBlock(size_t bytes) {
|
||||
size_t capacity = _nextBlockCapacity;
|
||||
if (bytes > capacity) capacity = bytes;
|
||||
if (!addNewBlock(capacity)) return NULL;
|
||||
_nextBlockCapacity *= 2;
|
||||
return allocInHead(bytes);
|
||||
}
|
||||
|
||||
bool addNewBlock(size_t capacity) {
|
||||
size_t bytes = sizeof(EmptyBlock) + capacity;
|
||||
Block* block = static_cast<Block*>(_allocator.allocate(bytes));
|
||||
if (block == NULL) return false;
|
||||
block->capacity = capacity;
|
||||
block->size = 0;
|
||||
block->next = _head;
|
||||
_head = block;
|
||||
return true;
|
||||
}
|
||||
|
||||
TAllocator _allocator;
|
||||
Block* _head;
|
||||
size_t _nextBlockCapacity;
|
||||
};
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Implements a JsonBuffer with dynamic memory allocation.
|
||||
// You are strongly encouraged to consider using StaticJsonBuffer which is much
|
||||
// more suitable for embedded systems.
|
||||
typedef DynamicJsonBufferBase<DefaultAllocator> DynamicJsonBuffer;
|
||||
typedef Internals::BlockJsonBuffer<Internals::DefaultAllocator>
|
||||
DynamicJsonBuffer;
|
||||
}
|
||||
|
94
include/ArduinoJson/Internals/BlockJsonBuffer.hpp
Normal file
94
include/ArduinoJson/Internals/BlockJsonBuffer.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
class DefaultAllocator {
|
||||
public:
|
||||
void* allocate(size_t size) { return malloc(size); }
|
||||
void deallocate(void* pointer) { free(pointer); }
|
||||
};
|
||||
|
||||
template <typename TAllocator>
|
||||
class BlockJsonBuffer : public JsonBuffer {
|
||||
struct Block;
|
||||
struct EmptyBlock {
|
||||
Block* next;
|
||||
size_t capacity;
|
||||
size_t size;
|
||||
};
|
||||
struct Block : EmptyBlock {
|
||||
uint8_t data[1];
|
||||
};
|
||||
|
||||
public:
|
||||
BlockJsonBuffer(size_t initialSize = 256)
|
||||
: _head(NULL), _nextBlockSize(initialSize) {}
|
||||
|
||||
~BlockJsonBuffer() {
|
||||
Block* currentBlock = _head;
|
||||
|
||||
while (currentBlock != NULL) {
|
||||
Block* nextBlock = currentBlock->next;
|
||||
_allocator.deallocate(currentBlock);
|
||||
currentBlock = nextBlock;
|
||||
}
|
||||
}
|
||||
|
||||
size_t size() const {
|
||||
size_t total = 0;
|
||||
for (const Block* b = _head; b; b = b->next) total += b->size;
|
||||
return total;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void* alloc(size_t bytes) {
|
||||
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
|
||||
}
|
||||
|
||||
private:
|
||||
bool canAllocInHead(size_t bytes) const {
|
||||
return _head != NULL && _head->size + bytes <= _head->capacity;
|
||||
}
|
||||
|
||||
void* allocInHead(size_t bytes) {
|
||||
void* p = _head->data + _head->size;
|
||||
_head->size += round_size_up(bytes);
|
||||
return p;
|
||||
}
|
||||
|
||||
void* allocInNewBlock(size_t bytes) {
|
||||
size_t capacity = _nextBlockSize;
|
||||
if (bytes > capacity) capacity = bytes;
|
||||
if (!addNewBlock(capacity)) return NULL;
|
||||
_nextBlockSize *= 2;
|
||||
return allocInHead(bytes);
|
||||
}
|
||||
|
||||
bool addNewBlock(size_t capacity) {
|
||||
size_t bytes = sizeof(EmptyBlock) + capacity;
|
||||
Block* block = static_cast<Block*>(_allocator.allocate(bytes));
|
||||
if (block == NULL) return false;
|
||||
block->capacity = capacity;
|
||||
block->size = 0;
|
||||
block->next = _head;
|
||||
_head = block;
|
||||
return true;
|
||||
}
|
||||
|
||||
TAllocator _allocator;
|
||||
Block* _head;
|
||||
size_t _nextBlockSize;
|
||||
};
|
||||
}
|
||||
}
|
14
include/ArduinoJson/Internals/Comments.hpp
Normal file
14
include/ArduinoJson/Internals/Comments.hpp
Normal file
@ -0,0 +1,14 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
const char *skipSpacesAndComments(const char *ptr);
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
#include "../Arduino/Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
@ -7,27 +7,27 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
#include "../StringTraits/StringTraits.hpp"
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "../Arduino/String.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A Print implementation that allows to write in a String
|
||||
template <typename TString>
|
||||
class DynamicStringBuilder : public Print {
|
||||
public:
|
||||
DynamicStringBuilder(TString &str) : _str(str) {}
|
||||
DynamicStringBuilder(String &str) : _str(str) {}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
StringFuncs<TString>::append(_str, static_cast<char>(c));
|
||||
// Need to cast to char, otherwise String will print a number (issue #120)
|
||||
_str += static_cast<char>(c);
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
DynamicStringBuilder &operator=(const DynamicStringBuilder &);
|
||||
|
||||
TString &_str;
|
||||
String &_str;
|
||||
};
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
#include "../Arduino/Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
@ -16,7 +16,7 @@ class Encoding {
|
||||
public:
|
||||
// Optimized for code size on a 8-bit AVR
|
||||
static char escapeChar(char c) {
|
||||
const char *p = escapeTable(false);
|
||||
const char *p = _escapeTable;
|
||||
while (p[0] && p[1] != c) {
|
||||
p += 2;
|
||||
}
|
||||
@ -25,7 +25,7 @@ class Encoding {
|
||||
|
||||
// Optimized for code size on a 8-bit AVR
|
||||
static char unescapeChar(char c) {
|
||||
const char *p = escapeTable(true);
|
||||
const char *p = _escapeTable + 4;
|
||||
for (;;) {
|
||||
if (p[0] == '\0') return c;
|
||||
if (p[0] == c) return p[1];
|
||||
@ -34,9 +34,7 @@ class Encoding {
|
||||
}
|
||||
|
||||
private:
|
||||
static const char *escapeTable(bool excludeIdenticals) {
|
||||
return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0];
|
||||
}
|
||||
static const char _escapeTable[];
|
||||
};
|
||||
}
|
||||
}
|
@ -9,8 +9,6 @@
|
||||
|
||||
#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
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
#include "../Arduino/Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
@ -23,13 +23,7 @@ class IndentedPrint : public Print {
|
||||
isNewLine = true;
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
size_t n = 0;
|
||||
if (isNewLine) n += writeTabs();
|
||||
n += sink->write(c);
|
||||
isNewLine = c == '\n';
|
||||
return n;
|
||||
}
|
||||
virtual size_t write(uint8_t);
|
||||
|
||||
// Adds one level of indentation
|
||||
void indent() {
|
||||
@ -52,11 +46,7 @@ class IndentedPrint : public Print {
|
||||
uint8_t tabSize : 3;
|
||||
bool isNewLine : 1;
|
||||
|
||||
size_t writeTabs() {
|
||||
size_t n = 0;
|
||||
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
|
||||
return n;
|
||||
}
|
||||
size_t writeTabs();
|
||||
|
||||
static const int MAX_LEVEL = 15; // because it's only 4 bits
|
||||
static const int MAX_TAB_SIZE = 7; // because it's only 3 bits
|
@ -14,13 +14,10 @@ namespace Internals {
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
typedef long long JsonInteger;
|
||||
typedef unsigned long long JsonUInt;
|
||||
#elif ARDUINOJSON_USE_INT64
|
||||
typedef __int64 JsonInteger;
|
||||
typedef unsigned _int64 JsonUInt;
|
||||
#else
|
||||
typedef long JsonInteger;
|
||||
typedef unsigned long JsonUInt;
|
||||
#endif
|
||||
}
|
||||
}
|
47
include/ArduinoJson/Internals/JsonParser.hpp
Normal file
47
include/ArduinoJson/Internals/JsonParser.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Parse JSON string to create JsonArrays and JsonObjects
|
||||
// This internal class is not indended to be used directly.
|
||||
// Instead, use JsonBuffer.parseArray() or .parseObject()
|
||||
class JsonParser {
|
||||
public:
|
||||
JsonParser(JsonBuffer *buffer, char *json, uint8_t nestingLimit)
|
||||
: _buffer(buffer),
|
||||
_readPtr(json ? json : ""),
|
||||
_writePtr(json),
|
||||
_nestingLimit(nestingLimit) {}
|
||||
|
||||
JsonArray &parseArray();
|
||||
JsonObject &parseObject();
|
||||
|
||||
private:
|
||||
bool skip(char charToSkip);
|
||||
|
||||
const char *parseString();
|
||||
bool parseAnythingTo(JsonVariant *destination);
|
||||
FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
|
||||
|
||||
inline bool parseArrayTo(JsonVariant *destination);
|
||||
inline bool parseObjectTo(JsonVariant *destination);
|
||||
inline bool parseStringTo(JsonVariant *destination);
|
||||
|
||||
JsonBuffer *_buffer;
|
||||
const char *_readPtr;
|
||||
char *_writePtr;
|
||||
uint8_t _nestingLimit;
|
||||
};
|
||||
}
|
||||
}
|
@ -8,14 +8,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "../TypeTraits/EnableIf.hpp"
|
||||
#include "DummyPrint.hpp"
|
||||
#include "DynamicStringBuilder.hpp"
|
||||
#include "IndentedPrint.hpp"
|
||||
#include "JsonSerializer.hpp"
|
||||
#include "JsonWriter.hpp"
|
||||
#include "Prettyfier.hpp"
|
||||
#include "StaticStringBuilder.hpp"
|
||||
#include "DynamicStringBuilder.hpp"
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include "StreamPrintAdapter.hpp"
|
||||
@ -33,7 +31,7 @@ class JsonPrintable {
|
||||
public:
|
||||
size_t printTo(Print &print) const {
|
||||
JsonWriter writer(print);
|
||||
JsonSerializer::serialize(downcast(), writer);
|
||||
downcast().writeTo(writer);
|
||||
return writer.bytesWritten();
|
||||
}
|
||||
|
||||
@ -50,15 +48,8 @@ class JsonPrintable {
|
||||
return printTo(sb);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
size_t printTo(char (&buffer)[N]) const {
|
||||
return printTo(buffer, N);
|
||||
}
|
||||
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<StringFuncs<TString>::has_append, size_t>::type
|
||||
printTo(TString &str) const {
|
||||
DynamicStringBuilder<TString> sb(str);
|
||||
size_t printTo(String &str) const {
|
||||
DynamicStringBuilder sb(str);
|
||||
return printTo(sb);
|
||||
}
|
||||
|
||||
@ -72,20 +63,13 @@ class JsonPrintable {
|
||||
return prettyPrintTo(sb);
|
||||
}
|
||||
|
||||
template <size_t N>
|
||||
size_t prettyPrintTo(char (&buffer)[N]) const {
|
||||
return prettyPrintTo(buffer, N);
|
||||
}
|
||||
|
||||
size_t prettyPrintTo(Print &print) const {
|
||||
IndentedPrint indentedPrint = IndentedPrint(print);
|
||||
return prettyPrintTo(indentedPrint);
|
||||
}
|
||||
|
||||
template <typename TString>
|
||||
typename TypeTraits::EnableIf<StringFuncs<TString>::has_append, size_t>::type
|
||||
prettyPrintTo(TString &str) const {
|
||||
DynamicStringBuilder<TString> sb(str);
|
||||
size_t prettyPrintTo(String &str) const {
|
||||
DynamicStringBuilder sb(str);
|
||||
return prettyPrintTo(sb);
|
||||
}
|
||||
|
||||
@ -100,9 +84,7 @@ class JsonPrintable {
|
||||
}
|
||||
|
||||
private:
|
||||
const T &downcast() const {
|
||||
return *static_cast<const T *>(this);
|
||||
}
|
||||
const T &downcast() const { return *static_cast<const T *>(this); }
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
@ -20,11 +20,11 @@ namespace Internals {
|
||||
// A union that defines the actual content of a JsonVariant.
|
||||
// The enum JsonVariantType determines which member is in use.
|
||||
union JsonVariantContent {
|
||||
JsonFloat asFloat; // used for double and float
|
||||
JsonUInt asInteger; // used for bool, char, short, int and longs
|
||||
const char* asString; // asString can be null
|
||||
JsonArray* asArray; // asArray cannot be null
|
||||
JsonObject* asObject; // asObject cannot be null
|
||||
JsonFloat asFloat; // used for double and float
|
||||
JsonInteger asInteger; // used for bool, char, short, int and longs
|
||||
const char* asString; // asString can be null
|
||||
JsonArray* asArray; // asArray cannot be null
|
||||
JsonObject* asObject; // asObject cannot be null
|
||||
};
|
||||
}
|
||||
}
|
@ -16,15 +16,13 @@ namespace Internals {
|
||||
// Enumerated type to know the current type of a JsonVariant.
|
||||
// The value determines which member of JsonVariantContent is used.
|
||||
enum JsonVariantType {
|
||||
JSON_UNDEFINED, // JsonVariant has not been initialized
|
||||
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_ARRAY, // JsonVariant stores a pointer to a JsonArray
|
||||
JSON_OBJECT, // JsonVariant stores a pointer to a JsonObject
|
||||
JSON_UNDEFINED, // the JsonVariant has not been initialized
|
||||
JSON_UNPARSED, // the JsonVariant contains an unparsed string
|
||||
JSON_STRING, // the JsonVariant stores a const char*
|
||||
JSON_BOOLEAN, // the JsonVariant stores a bool
|
||||
JSON_INTEGER, // the JsonVariant stores an integer
|
||||
JSON_ARRAY, // the JsonVariant stores a pointer to a JsonArray
|
||||
JSON_OBJECT, // the 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
|
85
include/ArduinoJson/Internals/JsonWriter.hpp
Normal file
85
include/ArduinoJson/Internals/JsonWriter.hpp
Normal file
@ -0,0 +1,85 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "Encoding.hpp"
|
||||
#include "ForceInline.hpp"
|
||||
#include "JsonFloat.hpp"
|
||||
#include "JsonInteger.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Writes the JSON tokens to a Print implementation
|
||||
// This class is used by:
|
||||
// - JsonArray::writeTo()
|
||||
// - JsonObject::writeTo()
|
||||
// - JsonVariant::writeTo()
|
||||
// Its derived by PrettyJsonWriter that overrides some members to add
|
||||
// indentation.
|
||||
class JsonWriter {
|
||||
public:
|
||||
explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
|
||||
|
||||
// Returns the number of bytes sent to the Print implementation.
|
||||
// This is very handy for implementations of printTo() that must return the
|
||||
// number of bytes written.
|
||||
size_t bytesWritten() const { return _length; }
|
||||
|
||||
void beginArray() { write('['); }
|
||||
void endArray() { write(']'); }
|
||||
|
||||
void beginObject() { write('{'); }
|
||||
void endObject() { write('}'); }
|
||||
|
||||
void writeColon() { write(':'); }
|
||||
void writeComma() { write(','); }
|
||||
|
||||
void writeBoolean(bool value) { write(value ? "true" : "false"); }
|
||||
|
||||
void writeString(const char *value) {
|
||||
if (!value) {
|
||||
write("null");
|
||||
} else {
|
||||
write('\"');
|
||||
while (*value) writeChar(*value++);
|
||||
write('\"');
|
||||
}
|
||||
}
|
||||
|
||||
void writeChar(char c) {
|
||||
char specialChar = Encoding::escapeChar(c);
|
||||
if (specialChar) {
|
||||
write('\\');
|
||||
write(specialChar);
|
||||
} else {
|
||||
write(c);
|
||||
}
|
||||
}
|
||||
|
||||
void writeInteger(JsonInteger value) { _length += _sink.print(value); }
|
||||
|
||||
void writeFloat(JsonFloat value, uint8_t decimals) {
|
||||
_length += _sink.print(value, decimals);
|
||||
}
|
||||
|
||||
void writeRaw(const char *s) { return write(s); }
|
||||
|
||||
protected:
|
||||
void write(char c) { _length += _sink.write(c); }
|
||||
FORCE_INLINE void write(const char *s) { _length += _sink.print(s); }
|
||||
|
||||
Print &_sink;
|
||||
size_t _length;
|
||||
|
||||
private:
|
||||
JsonWriter &operator=(const JsonWriter &); // cannot be assigned
|
||||
};
|
||||
}
|
||||
}
|
@ -36,56 +36,21 @@ class List {
|
||||
// Would return false in the following situation:
|
||||
// - the memory allocation failed (StaticJsonBuffer was too small)
|
||||
// - the JSON parsing failed
|
||||
bool success() const {
|
||||
return _buffer != NULL;
|
||||
}
|
||||
bool success() const { return _buffer != NULL; }
|
||||
|
||||
// Returns the numbers of elements in the list.
|
||||
// For a JsonObject, it would return the number of key-value pairs
|
||||
size_t size() const {
|
||||
size_t nodeCount = 0;
|
||||
for (node_type *node = _firstNode; node; node = node->next) nodeCount++;
|
||||
return nodeCount;
|
||||
}
|
||||
size_t size() const;
|
||||
|
||||
iterator begin() {
|
||||
return iterator(_firstNode);
|
||||
}
|
||||
iterator end() {
|
||||
return iterator(NULL);
|
||||
}
|
||||
iterator begin() { return iterator(_firstNode); }
|
||||
iterator end() { return iterator(NULL); }
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator(_firstNode);
|
||||
}
|
||||
const_iterator end() const {
|
||||
return const_iterator(NULL);
|
||||
}
|
||||
const_iterator begin() const { return const_iterator(_firstNode); }
|
||||
const_iterator end() const { 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) {
|
||||
if (!nodeToRemove) return;
|
||||
if (nodeToRemove == _firstNode) {
|
||||
_firstNode = nodeToRemove->next;
|
||||
} else {
|
||||
for (node_type *node = _firstNode; node; node = node->next)
|
||||
if (node->next == nodeToRemove) node->next = nodeToRemove->next;
|
||||
}
|
||||
}
|
||||
node_type *addNewNode();
|
||||
void removeNode(node_type *nodeToRemove);
|
||||
|
||||
JsonBuffer *_buffer;
|
||||
node_type *_firstNode;
|
@ -29,11 +29,6 @@ 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);
|
||||
@ -44,11 +39,6 @@ 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
|
||||
@ -56,11 +46,6 @@ 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
|
||||
}
|
||||
}
|
47
include/ArduinoJson/Internals/Prettyfier.hpp
Normal file
47
include/ArduinoJson/Internals/Prettyfier.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IndentedPrint.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Converts a compact JSON string into an indented one.
|
||||
class Prettyfier : public Print {
|
||||
public:
|
||||
explicit Prettyfier(IndentedPrint& p) : _sink(p) {
|
||||
_previousChar = 0;
|
||||
_inString = false;
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t);
|
||||
|
||||
private:
|
||||
Prettyfier& operator=(const Prettyfier&); // cannot be assigned
|
||||
|
||||
bool inEmptyBlock() { return _previousChar == '{' || _previousChar == '['; }
|
||||
|
||||
size_t handleStringChar(uint8_t);
|
||||
size_t handleMarkupChar(uint8_t);
|
||||
|
||||
size_t handleBlockClose(uint8_t);
|
||||
size_t handleBlockOpen(uint8_t);
|
||||
size_t handleColon();
|
||||
size_t handleComma();
|
||||
size_t handleQuoteOpen();
|
||||
size_t handleNormalChar(uint8_t);
|
||||
size_t indentIfNeeded();
|
||||
size_t unindentIfNeeded();
|
||||
|
||||
uint8_t _previousChar;
|
||||
IndentedPrint& _sink;
|
||||
bool _inString;
|
||||
};
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Print.hpp"
|
||||
#include "../Arduino/Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
@ -20,13 +20,7 @@ class StaticStringBuilder : public Print {
|
||||
buffer[0] = '\0';
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
if (length >= capacity) return 0;
|
||||
|
||||
buffer[length++] = c;
|
||||
buffer[length] = '\0';
|
||||
return 1;
|
||||
}
|
||||
virtual size_t write(uint8_t c);
|
||||
|
||||
private:
|
||||
char *buffer;
|
@ -11,7 +11,7 @@
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
|
||||
#include "../Print.hpp"
|
||||
#include "../Arduino/Print.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
@ -8,16 +8,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// A special type of data that can be used to insert pregenerated JSON portions.
|
||||
class RawJson {
|
||||
namespace Internals {
|
||||
class Unparsed {
|
||||
public:
|
||||
explicit RawJson(const char* str) : _str(str) {}
|
||||
operator const char*() const {
|
||||
return _str;
|
||||
}
|
||||
explicit Unparsed(const char* str) : _str(str) {}
|
||||
operator const char*() const { return _str; }
|
||||
|
||||
private:
|
||||
const char* _str;
|
||||
};
|
||||
}
|
||||
}
|
@ -7,17 +7,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Data/JsonBufferAllocated.hpp"
|
||||
#include "Data/List.hpp"
|
||||
#include "Data/ReferenceType.hpp"
|
||||
#include "Data/ValueSetter.hpp"
|
||||
#include "Internals/JsonBufferAllocated.hpp"
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/List.hpp"
|
||||
#include "Internals/ReferenceType.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
#include "Serialization/JsonPrintable.hpp"
|
||||
#include "StringTraits/StringTraits.hpp"
|
||||
#include "TypeTraits/ConstRefOrConstPtr.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||
#include "TypeTraits/IsSame.hpp"
|
||||
|
||||
// Returns the size (in bytes) of an array with n elements.
|
||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||
@ -42,6 +36,15 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
public Internals::List<JsonVariant>,
|
||||
public Internals::JsonBufferAllocated {
|
||||
public:
|
||||
// A meta-function that returns true if type T can be used in
|
||||
// JsonArray::set()
|
||||
template <typename T>
|
||||
struct CanSet {
|
||||
static const bool value = JsonVariant::IsConstructibleFrom<T>::value ||
|
||||
TypeTraits::IsSame<T, String &>::value ||
|
||||
TypeTraits::IsSame<T, const String &>::value;
|
||||
};
|
||||
|
||||
// Create an empty JsonArray attached to the specified JsonBuffer.
|
||||
// You should not call this constructor directly.
|
||||
// Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
|
||||
@ -49,12 +52,10 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
: Internals::List<JsonVariant>(buffer) {}
|
||||
|
||||
// Gets the value at the specified index
|
||||
JsonVariant operator[](size_t index) const {
|
||||
return get<JsonVariant>(index);
|
||||
}
|
||||
FORCE_INLINE JsonVariant operator[](size_t index) const;
|
||||
|
||||
// Gets or sets the value at specified index
|
||||
JsonArraySubscript operator[](size_t index);
|
||||
FORCE_INLINE JsonArraySubscript operator[](size_t index);
|
||||
|
||||
// Adds the specified value at the end of the array.
|
||||
//
|
||||
@ -66,24 +67,30 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
// bool add(float value);
|
||||
// bool add(double value);
|
||||
// bool add(const char*);
|
||||
// bool add(const char[]);
|
||||
// bool add(const char[N]);
|
||||
// bool add(RawJson);
|
||||
// bool add(const std::string&)
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(
|
||||
T value,
|
||||
typename TypeTraits::EnableIf<CanSet<T>::value, void>::type * = 0) {
|
||||
return addNode<T>(value);
|
||||
}
|
||||
// bool add(const String&)
|
||||
// bool add(const JsonVariant&);
|
||||
// bool add(JsonArray&);
|
||||
// bool add(JsonObject&);
|
||||
template <typename T>
|
||||
bool add(const T &value) {
|
||||
// reduce the number of template function instanciation to reduce code size
|
||||
return addNodeImpl<typename TypeTraits::ConstRefOrConstPtr<T>::type>(value);
|
||||
FORCE_INLINE bool add(
|
||||
const T &value,
|
||||
typename TypeTraits::EnableIf<CanSet<T &>::value, T>::type * = 0) {
|
||||
return addNode<T &>(const_cast<T &>(value));
|
||||
}
|
||||
// bool add(float value, uint8_t decimals);
|
||||
// bool add(double value, uint8_t decimals);
|
||||
template <typename T>
|
||||
bool add(T value, uint8_t decimals) {
|
||||
return add(JsonVariant(value, decimals));
|
||||
FORCE_INLINE bool add(
|
||||
T value,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
|
||||
uint8_t>::type decimals) {
|
||||
return addNode<JsonVariant>(JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
// Sets the value at specified index.
|
||||
@ -92,41 +99,42 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
// bool set(size_t index, long value);
|
||||
// bool set(size_t index, int value);
|
||||
// bool set(size_t index, short value);
|
||||
// bool set(size_t index, const std::string&)
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
size_t index, T value,
|
||||
typename TypeTraits::EnableIf<CanSet<T>::value, void>::type * = 0) {
|
||||
return setNodeAt<T>(index, value);
|
||||
}
|
||||
// bool set(size_t index, const String&)
|
||||
// bool set(size_t index, const JsonVariant&);
|
||||
// bool set(size_t index, JsonArray&);
|
||||
// bool set(size_t index, JsonObject&);
|
||||
template <typename T>
|
||||
bool set(size_t index, const T &value) {
|
||||
// reduce the number of template function instanciation to reduce code size
|
||||
return setNodeAt<typename TypeTraits::ConstRefOrConstPtr<T>::type>(index,
|
||||
value);
|
||||
FORCE_INLINE bool set(
|
||||
size_t index, const T &value,
|
||||
typename TypeTraits::EnableIf<CanSet<T &>::value, T>::type * = 0) {
|
||||
return setNodeAt<T &>(index, const_cast<T &>(value));
|
||||
}
|
||||
// bool set(size_t index, float value, uint8_t decimals = 2);
|
||||
// bool set(size_t index, double value, uint8_t decimals = 2);
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
|
||||
bool>::type
|
||||
set(size_t index, T value, uint8_t decimals) {
|
||||
return set(index, JsonVariant(value, decimals));
|
||||
FORCE_INLINE bool set(
|
||||
size_t index, T value,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
|
||||
uint8_t>::type decimals) {
|
||||
return setNodeAt<const JsonVariant &>(index, JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
// Gets the value at the specified index.
|
||||
FORCE_INLINE JsonVariant get(size_t index) const;
|
||||
|
||||
// Gets the value at the specified index.
|
||||
template <typename T>
|
||||
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
|
||||
node_type *node = getNodeAt(index);
|
||||
return node ? node->content.as<T>()
|
||||
: Internals::JsonVariantDefault<T>::get();
|
||||
;
|
||||
}
|
||||
FORCE_INLINE T get(size_t index) const;
|
||||
|
||||
// Check the type of the value at specified index.
|
||||
template <typename T>
|
||||
bool is(size_t index) const {
|
||||
node_type *node = getNodeAt(index);
|
||||
return node ? node->content.is<T>() : false;
|
||||
}
|
||||
FORCE_INLINE bool is(size_t index) const;
|
||||
|
||||
// Creates a JsonArray and adds a reference at the end of the array.
|
||||
// It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
|
||||
@ -137,103 +145,31 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
JsonObject &createNestedObject();
|
||||
|
||||
// Removes element at specified index.
|
||||
void removeAt(size_t index) {
|
||||
removeNode(getNodeAt(index));
|
||||
}
|
||||
void removeAt(size_t index);
|
||||
|
||||
// Returns a reference an invalid JsonArray.
|
||||
// This object is meant to replace a NULL pointer.
|
||||
// This is used when memory allocation or JSON parsing fail.
|
||||
static JsonArray &invalid() {
|
||||
static JsonArray instance(NULL);
|
||||
return instance;
|
||||
}
|
||||
static JsonArray &invalid() { return _invalid; }
|
||||
|
||||
// Imports a 1D array
|
||||
template <typename T, size_t N>
|
||||
bool copyFrom(T (&array)[N]) {
|
||||
return copyFrom(array, N);
|
||||
}
|
||||
|
||||
// Imports a 1D array
|
||||
template <typename T>
|
||||
bool copyFrom(T *array, size_t len) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ok &= add(array[i]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Imports a 2D array
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
bool copyFrom(T (&array)[N1][N2]) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < N1; i++) {
|
||||
JsonArray &nestedArray = createNestedArray();
|
||||
for (size_t j = 0; j < N2; j++) {
|
||||
ok &= nestedArray.add(array[i][j]);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Exports a 1D array
|
||||
template <typename T, size_t N>
|
||||
size_t copyTo(T (&array)[N]) const {
|
||||
return copyTo(array, N);
|
||||
}
|
||||
|
||||
// Exports a 1D array
|
||||
template <typename T>
|
||||
size_t copyTo(T *array, size_t len) const {
|
||||
size_t i = 0;
|
||||
for (const_iterator it = begin(); it != end() && i < len; ++it)
|
||||
array[i++] = *it;
|
||||
return i;
|
||||
}
|
||||
|
||||
// Exports a 2D array
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
void copyTo(T (&array)[N1][N2]) const {
|
||||
size_t i = 0;
|
||||
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
|
||||
it->asArray().copyTo(array[i++]);
|
||||
}
|
||||
}
|
||||
// Serialize the array to the specified JsonWriter.
|
||||
void writeTo(Internals::JsonWriter &writer) const;
|
||||
|
||||
private:
|
||||
node_type *getNodeAt(size_t index) const {
|
||||
node_type *node = _firstNode;
|
||||
while (node && index--) node = node->next;
|
||||
return node;
|
||||
}
|
||||
node_type *getNodeAt(size_t index) const;
|
||||
|
||||
template <typename TValueRef>
|
||||
bool setNodeAt(size_t index, TValueRef value) {
|
||||
node_type *node = getNodeAt(index);
|
||||
if (!node) return false;
|
||||
template <typename TValue>
|
||||
bool setNodeAt(size_t index, TValue value);
|
||||
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
|
||||
value);
|
||||
}
|
||||
template <typename TValue>
|
||||
bool addNode(TValue);
|
||||
|
||||
template <typename TValueRef>
|
||||
bool addNodeImpl(TValueRef value) {
|
||||
node_type *node = addNewNode();
|
||||
if (!node) return false;
|
||||
template <typename T>
|
||||
FORCE_INLINE bool setNodeValue(node_type *, T value);
|
||||
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
|
||||
value);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Internals {
|
||||
template <>
|
||||
struct JsonVariantDefault<JsonArray> {
|
||||
static JsonArray &get() {
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
// The instance returned by JsonArray::invalid()
|
||||
static JsonArray _invalid;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#include "JsonArray.ipp"
|
||||
|
101
include/ArduinoJson/JsonArray.ipp
Normal file
101
include/ArduinoJson/JsonArray.ipp
Normal file
@ -0,0 +1,101 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonArray.hpp"
|
||||
#include "JsonObject.hpp"
|
||||
#include "JsonArraySubscript.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
inline JsonArraySubscript JsonArray::operator[](size_t index) {
|
||||
return JsonArraySubscript(*this, index);
|
||||
}
|
||||
|
||||
inline JsonVariant JsonArray::operator[](size_t index) const {
|
||||
return get(index);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline bool JsonArray::addNode(TValue value) {
|
||||
node_type *node = addNewNode();
|
||||
return node != NULL && setNodeValue<TValue>(node, value);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline bool JsonArray::setNodeAt(size_t index, TValue value) {
|
||||
node_type *node = getNodeAt(index);
|
||||
return node != NULL && setNodeValue<TValue>(node, value);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline bool JsonArray::setNodeValue(node_type *node, TValue value) {
|
||||
node->content = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonArray::setNodeValue(node_type *node, String &value) {
|
||||
const char *copy = _buffer->strdup(value);
|
||||
if (!copy) return false;
|
||||
node->content = copy;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline JsonVariant JsonArray::get(size_t index) const {
|
||||
node_type *node = getNodeAt(index);
|
||||
return node ? node->content : JsonVariant();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T JsonArray::get(size_t index) const {
|
||||
node_type *node = getNodeAt(index);
|
||||
return node ? node->content.as<T>() : JsonVariant::invalid<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool JsonArray::is(size_t index) const {
|
||||
node_type *node = getNodeAt(index);
|
||||
return node ? node->content.is<T>() : false;
|
||||
}
|
||||
|
||||
template <typename TImplem>
|
||||
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
|
||||
int index) const {
|
||||
return asArray()[index];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonArray &JsonVariant::invalid<JsonArray &>() {
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonArray const &JsonVariant::invalid<JsonArray const &>() {
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
inline JsonArray &JsonVariant::asArray() const {
|
||||
if (_type == Internals::JSON_ARRAY) return *_content.asArray;
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
inline JsonArray &JsonArray::createNestedArray() {
|
||||
if (!_buffer) return JsonArray::invalid();
|
||||
JsonArray &array = _buffer->createArray();
|
||||
add(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
inline JsonArray &JsonObject::createNestedArray(JsonObjectKey key) {
|
||||
if (!_buffer) return JsonArray::invalid();
|
||||
JsonArray &array = _buffer->createArray();
|
||||
setNodeAt<const JsonVariant &>(key, array);
|
||||
return array;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonArray.hpp"
|
||||
#include "JsonArraySubscript.hpp"
|
||||
#include "JsonObject.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
inline JsonArray &JsonArray::createNestedArray() {
|
||||
if (!_buffer) return JsonArray::invalid();
|
||||
JsonArray &array = _buffer->createArray();
|
||||
add(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
inline JsonObject &JsonArray::createNestedObject() {
|
||||
if (!_buffer) return JsonObject::invalid();
|
||||
JsonObject &object = _buffer->createObject();
|
||||
add(object);
|
||||
return object;
|
||||
}
|
||||
}
|
@ -21,23 +21,33 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
||||
FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index)
|
||||
: _array(array), _index(index) {}
|
||||
|
||||
FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
|
||||
_array.set(_index, src);
|
||||
JsonArraySubscript& operator=(const JsonArraySubscript& src) {
|
||||
_array.set<const JsonVariant&>(_index, src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
|
||||
_array.set(_index, src);
|
||||
typename TypeTraits::EnableIf<JsonArray::CanSet<T&>::value,
|
||||
JsonArraySubscript>::type&
|
||||
operator=(const T& src) {
|
||||
_array.set<T&>(_index, const_cast<T&>(src));
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool success() const {
|
||||
return _index < _array.size();
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<JsonArray::CanSet<T>::value,
|
||||
JsonArraySubscript>::type&
|
||||
operator=(T src) {
|
||||
_array.set<T>(_index, src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool success() const { return _index < _array.size(); }
|
||||
|
||||
FORCE_INLINE operator JsonVariant() const { return _array.get(_index); }
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE typename Internals::JsonVariantAs<T>::type as() const {
|
||||
FORCE_INLINE T as() const {
|
||||
return _array.get<T>(_index);
|
||||
}
|
||||
|
||||
@ -46,8 +56,12 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
||||
return _array.is<T>(_index);
|
||||
}
|
||||
|
||||
void writeTo(Internals::JsonWriter& writer) const {
|
||||
_array.get(_index).writeTo(writer);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE void set(const TValue& value) {
|
||||
void set(TValue value) {
|
||||
_array.set(_index, value);
|
||||
}
|
||||
|
||||
@ -63,21 +77,6 @@ inline std::ostream& operator<<(std::ostream& os,
|
||||
}
|
||||
#endif
|
||||
|
||||
inline JsonArraySubscript JsonArray::operator[](size_t index) {
|
||||
return JsonArraySubscript(*this, index);
|
||||
}
|
||||
|
||||
template <typename TImplem>
|
||||
inline JsonArraySubscript JsonVariantBase<TImplem>::operator[](int index) {
|
||||
return asArray()[index];
|
||||
}
|
||||
|
||||
template <typename TImplem>
|
||||
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
|
||||
int index) const {
|
||||
return asArray()[index];
|
||||
}
|
||||
|
||||
} // namespace ArduinoJson
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -11,15 +11,12 @@
|
||||
#include <stdint.h> // for uint8_t
|
||||
#include <string.h>
|
||||
|
||||
#include "Arduino/String.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
|
||||
@ -51,18 +48,64 @@ class JsonBuffer {
|
||||
// allocation fails.
|
||||
JsonObject &createObject();
|
||||
|
||||
// Duplicate a string
|
||||
template <typename TString>
|
||||
char *strdup(const TString &src) {
|
||||
return Internals::StringFuncs<TString>::duplicate(src, this);
|
||||
// Allocates and populate a JsonArray from a JSON string.
|
||||
//
|
||||
// The First argument is a pointer to the JSON string, the memory must be
|
||||
// writable
|
||||
// because the parser will insert null-terminators and replace escaped chars.
|
||||
//
|
||||
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
|
||||
//
|
||||
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
|
||||
// allocation fails.
|
||||
JsonArray &parseArray(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
|
||||
|
||||
// Same with a const char*.
|
||||
// With this overload, the JsonBuffer will make a copy of the string
|
||||
JsonArray &parseArray(const char *json, uint8_t nesting = DEFAULT_LIMIT) {
|
||||
return parseArray(strdup(json), nesting);
|
||||
}
|
||||
|
||||
// Same as above with a String class
|
||||
JsonArray &parseArray(const String &json, uint8_t nesting = DEFAULT_LIMIT) {
|
||||
return parseArray(json.c_str(), nesting);
|
||||
}
|
||||
|
||||
// Allocates and populate a JsonObject from a JSON string.
|
||||
//
|
||||
// The First argument is a pointer to the JSON string, the memory must be
|
||||
// writable
|
||||
// because the parser will insert null-terminators and replace escaped chars.
|
||||
//
|
||||
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
|
||||
//
|
||||
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
|
||||
// allocation fails.
|
||||
JsonObject &parseObject(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
|
||||
|
||||
// Same with a const char*.
|
||||
// With this overload, the JsonBuffer will make a copy of the string
|
||||
JsonObject &parseObject(const char *json, uint8_t nesting = DEFAULT_LIMIT) {
|
||||
return parseObject(strdup(json), nesting);
|
||||
}
|
||||
|
||||
// Same as above with a String class
|
||||
JsonObject &parseObject(const String &json, uint8_t nesting = DEFAULT_LIMIT) {
|
||||
return parseObject(json.c_str(), nesting);
|
||||
}
|
||||
|
||||
// Duplicate a string
|
||||
char *strdup(const char *src) {
|
||||
return src ? strdup(src, strlen(src)) : NULL;
|
||||
}
|
||||
char *strdup(const String &src) { return strdup(src.c_str(), src.length()); }
|
||||
|
||||
// Allocates n bytes in the JsonBuffer.
|
||||
// Return a pointer to the allocated memory or NULL if allocation fails.
|
||||
virtual void *alloc(size_t size) = 0;
|
||||
|
||||
protected:
|
||||
// Preserve aligment if necessary
|
||||
// Preserve aligment if nessary
|
||||
static FORCE_INLINE size_t round_size_up(size_t bytes) {
|
||||
#if ARDUINOJSON_ENABLE_ALIGNMENT
|
||||
const size_t x = sizeof(void *) - 1;
|
||||
@ -71,13 +114,23 @@ class JsonBuffer {
|
||||
return bytes;
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
char *strdup(const char *, size_t);
|
||||
|
||||
// Default value of nesting limit of parseArray() and parseObject().
|
||||
//
|
||||
// The nesting limit is a contain on the level of nesting allowed in the
|
||||
// JSON
|
||||
// string.
|
||||
// If set to 0, only a flat array or objects can be parsed.
|
||||
// If set to 1, the object can contain nested arrays or objects but only 1
|
||||
// level deep.
|
||||
// And bigger values will allow more level of nesting.
|
||||
//
|
||||
// The purpose of this feature is to prevent stack overflow that could
|
||||
// lead to
|
||||
// a security risk.
|
||||
static const uint8_t DEFAULT_LIMIT = 10;
|
||||
};
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,97 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Deserialization/JsonParser.hpp"
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
template <typename TDerived>
|
||||
class JsonBufferBase : public JsonBuffer {
|
||||
public:
|
||||
// Allocates and populate a JsonArray from a JSON string.
|
||||
//
|
||||
// The First argument is a pointer to the JSON string, the memory must be
|
||||
// writable
|
||||
// because the parser will insert null-terminators and replace escaped chars.
|
||||
//
|
||||
// The second argument set the nesting limit
|
||||
//
|
||||
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
|
||||
// allocation fails.
|
||||
// With this overload, the JsonBuffer will make a copy of the string
|
||||
template <typename TString>
|
||||
JsonArray &parseArray(
|
||||
const TString &json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(that(), json, nestingLimit).parseArray();
|
||||
}
|
||||
template <typename TString>
|
||||
JsonArray &parseArray(
|
||||
TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(that(), json, nestingLimit).parseArray();
|
||||
}
|
||||
|
||||
// Allocates and populate a JsonObject from a JSON string.
|
||||
//
|
||||
// The First argument is a pointer to the JSON string, the memory must be
|
||||
// writable
|
||||
// because the parser will insert null-terminators and replace escaped chars.
|
||||
//
|
||||
// The second argument set the nesting limit
|
||||
//
|
||||
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
|
||||
// allocation fails.
|
||||
template <typename TString>
|
||||
JsonObject &parseObject(
|
||||
const TString &json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(that(), json, nestingLimit).parseObject();
|
||||
}
|
||||
template <typename TString>
|
||||
JsonObject &parseObject(
|
||||
TString &json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(that(), json, nestingLimit).parseObject();
|
||||
}
|
||||
|
||||
// Generalized version of parseArray() and parseObject(), also works for
|
||||
// integral types.
|
||||
template <typename TString>
|
||||
JsonVariant parse(const TString &json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
|
||||
}
|
||||
template <typename TString>
|
||||
JsonVariant parse(TString &json,
|
||||
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||
return Internals::makeParser(that(), json, nestingLimit).parseVariant();
|
||||
}
|
||||
|
||||
private:
|
||||
TDerived *that() {
|
||||
return static_cast<TDerived *>(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
@ -1,20 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Deserialization/JsonParser.hpp"
|
||||
|
||||
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() {
|
||||
JsonArray *ptr = new (this) JsonArray(this);
|
||||
return ptr ? *ptr : JsonArray::invalid();
|
||||
}
|
||||
|
||||
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() {
|
||||
JsonObject *ptr = new (this) JsonObject(this);
|
||||
return ptr ? *ptr : JsonObject::invalid();
|
||||
}
|
@ -7,17 +7,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Data/JsonBufferAllocated.hpp"
|
||||
#include "Data/List.hpp"
|
||||
#include "Data/ReferenceType.hpp"
|
||||
#include "Data/ValueSetter.hpp"
|
||||
#include "Arduino/String.hpp"
|
||||
#include "Internals/JsonBufferAllocated.hpp"
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/List.hpp"
|
||||
#include "Internals/ReferenceType.hpp"
|
||||
#include "JsonPair.hpp"
|
||||
#include "Serialization/JsonPrintable.hpp"
|
||||
#include "StringTraits/StringTraits.hpp"
|
||||
#include "TypeTraits/ConstRefOrConstPtr.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||
#include "TypeTraits/IsSame.hpp"
|
||||
|
||||
// Returns the size (in bytes) of an object with n elements.
|
||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||
@ -41,20 +36,27 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
public Internals::List<JsonPair>,
|
||||
public Internals::JsonBufferAllocated {
|
||||
public:
|
||||
// A meta-function that returns true if type T can be used in
|
||||
// JsonObject::set()
|
||||
template <typename T>
|
||||
struct CanSet {
|
||||
static const bool value = JsonVariant::IsConstructibleFrom<T>::value ||
|
||||
TypeTraits::IsSame<T, String&>::value ||
|
||||
TypeTraits::IsSame<T, const String&>::value;
|
||||
};
|
||||
|
||||
// Create an empty JsonArray attached to the specified JsonBuffer.
|
||||
// You should not use this constructor directly.
|
||||
// Instead, use JsonBuffer::createObject() or JsonBuffer.parseObject().
|
||||
explicit JsonObject(JsonBuffer* buffer) : Internals::List<JsonPair>(buffer) {}
|
||||
FORCE_INLINE explicit JsonObject(JsonBuffer* buffer)
|
||||
: Internals::List<JsonPair>(buffer) {}
|
||||
|
||||
// Gets or sets the value associated with the specified key.
|
||||
template <typename TString>
|
||||
JsonObjectSubscript<TString> operator[](const TString& key);
|
||||
FORCE_INLINE JsonObjectSubscript<const char*> operator[](const char* key);
|
||||
FORCE_INLINE JsonObjectSubscript<const String&> operator[](const String& key);
|
||||
|
||||
// Gets the value associated with the specified key.
|
||||
template <typename TString>
|
||||
JsonVariant operator[](const TString& key) const {
|
||||
return get<JsonVariant>(key);
|
||||
}
|
||||
FORCE_INLINE JsonVariant operator[](JsonObjectKey key) const;
|
||||
|
||||
// Sets the specified key with the specified value.
|
||||
// bool set(TKey key, bool value);
|
||||
@ -65,113 +67,82 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
// bool set(TKey key, float value);
|
||||
// bool set(TKey key, double value);
|
||||
// bool set(TKey key, const char* value);
|
||||
// bool set(TKey key, RawJson value);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
JsonObjectKey key, T value,
|
||||
typename TypeTraits::EnableIf<CanSet<T>::value, void>::type* = 0) {
|
||||
return setNodeAt<T>(key, value);
|
||||
}
|
||||
// bool set(Key, String&);
|
||||
// bool set(Key, JsonArray&);
|
||||
// bool set(Key, JsonObject&);
|
||||
// bool set(Key, JsonVariant&);
|
||||
template <typename TValue, typename TString>
|
||||
bool set(const TString& key, const TValue& value) {
|
||||
// reduce the number of template function instanciation to reduce code size
|
||||
return setNodeAt<typename TypeTraits::ConstRefOrConstPtr<TString>::type,
|
||||
typename TypeTraits::ConstRefOrConstPtr<TValue>::type>(
|
||||
key, value);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
JsonObjectKey key, const T& value,
|
||||
typename TypeTraits::EnableIf<CanSet<T&>::value, T>::type* = 0) {
|
||||
return setNodeAt<T&>(key, const_cast<T&>(value));
|
||||
}
|
||||
// bool set(Key, float value, uint8_t decimals);
|
||||
// bool set(Key, double value, uint8_t decimals);
|
||||
template <typename TValue, typename TString>
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value,
|
||||
bool>::type
|
||||
set(const TString& key, TValue value, uint8_t decimals) {
|
||||
return set(key, JsonVariant(value, decimals));
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(
|
||||
JsonObjectKey key, TValue value,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value,
|
||||
uint8_t>::type decimals) {
|
||||
return setNodeAt<const JsonVariant&>(key, JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
// Gets the value associated with the specified key.
|
||||
template <typename TValue, typename TString>
|
||||
typename Internals::JsonVariantAs<TValue>::type get(
|
||||
const TString& key) const {
|
||||
node_type* node = getNodeAt(key);
|
||||
return node ? node->content.value.as<TValue>()
|
||||
: Internals::JsonVariantDefault<TValue>::get();
|
||||
}
|
||||
FORCE_INLINE JsonVariant get(JsonObjectKey) const;
|
||||
|
||||
// Gets the value associated with the specified key.
|
||||
template <typename T>
|
||||
FORCE_INLINE T get(JsonObjectKey) const;
|
||||
|
||||
// Checks the type of the value associated with the specified key.
|
||||
template <typename TValue, typename TString>
|
||||
bool is(const TString& key) const {
|
||||
node_type* node = getNodeAt(key);
|
||||
return node ? node->content.value.is<TValue>() : false;
|
||||
}
|
||||
template <typename T>
|
||||
FORCE_INLINE bool is(JsonObjectKey) const;
|
||||
|
||||
// Creates and adds a JsonArray.
|
||||
// This is a shortcut for JsonBuffer::createArray() and JsonObject::add().
|
||||
template <typename TString>
|
||||
JsonArray& createNestedArray(const TString& key);
|
||||
FORCE_INLINE JsonArray& createNestedArray(JsonObjectKey key);
|
||||
|
||||
// Creates and adds a JsonObject.
|
||||
// This is a shortcut for JsonBuffer::createObject() and JsonObject::add().
|
||||
template <typename TString>
|
||||
JsonObject& createNestedObject(const TString& key);
|
||||
FORCE_INLINE JsonObject& createNestedObject(JsonObjectKey key);
|
||||
|
||||
// Tells weither the specified key is present and associated with a value.
|
||||
template <typename TString>
|
||||
bool containsKey(const TString& key) const {
|
||||
return getNodeAt(key) != NULL;
|
||||
}
|
||||
FORCE_INLINE bool containsKey(JsonObjectKey key) const;
|
||||
|
||||
// Removes the specified key and the associated value.
|
||||
template <typename TString>
|
||||
void remove(const TString& key) {
|
||||
removeNode(getNodeAt(key));
|
||||
}
|
||||
void remove(JsonObjectKey key);
|
||||
|
||||
// Returns a reference an invalid JsonObject.
|
||||
// This object is meant to replace a NULL pointer.
|
||||
// This is used when memory allocation or JSON parsing fail.
|
||||
static JsonObject& invalid() {
|
||||
static JsonObject instance(NULL);
|
||||
return instance;
|
||||
}
|
||||
static JsonObject& invalid() { return _invalid; }
|
||||
|
||||
// Serialize the object to the specified JsonWriter
|
||||
void writeTo(Internals::JsonWriter& writer) const;
|
||||
|
||||
private:
|
||||
// Returns the list node that matches the specified key.
|
||||
template <typename TString>
|
||||
node_type* getNodeAt(const TString& key) const {
|
||||
// reduce the number of template function instanciation to reduce code size
|
||||
return getNodeAtImpl<
|
||||
typename TypeTraits::ConstRefOrConstPtr<TString>::type>(key);
|
||||
}
|
||||
node_type* getNodeAt(const char* key) const;
|
||||
|
||||
template <typename TStringRef>
|
||||
node_type* getNodeAtImpl(TStringRef key) const {
|
||||
for (node_type* node = _firstNode; node; node = node->next) {
|
||||
if (Internals::StringFuncs<TStringRef>::equals(key, node->content.key))
|
||||
return node;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
node_type* getOrCreateNodeAt(const char* key);
|
||||
|
||||
template <typename TStringRef, typename TValueRef>
|
||||
bool setNodeAt(TStringRef key, TValueRef value) {
|
||||
node_type* node = getNodeAtImpl<TStringRef>(key);
|
||||
if (!node) {
|
||||
node = addNewNode();
|
||||
if (!node) return false;
|
||||
template <typename T>
|
||||
FORCE_INLINE bool setNodeAt(JsonObjectKey key, T value);
|
||||
|
||||
bool key_ok = Internals::ValueSetter<TStringRef>::set(
|
||||
_buffer, node->content.key, key);
|
||||
if (!key_ok) return false;
|
||||
}
|
||||
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content.value,
|
||||
value);
|
||||
}
|
||||
};
|
||||
FORCE_INLINE bool setNodeKey(node_type*, JsonObjectKey key);
|
||||
|
||||
namespace Internals {
|
||||
template <>
|
||||
struct JsonVariantDefault<JsonObject> {
|
||||
static JsonObject& get() {
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
template <typename T>
|
||||
FORCE_INLINE bool setNodeValue(node_type*, T value);
|
||||
|
||||
// The instance returned by JsonObject::invalid()
|
||||
static JsonObject _invalid;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#include "JsonObject.ipp"
|
||||
|
130
include/ArduinoJson/JsonObject.ipp
Normal file
130
include/ArduinoJson/JsonObject.ipp
Normal file
@ -0,0 +1,130 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonArray.hpp"
|
||||
#include "JsonObject.hpp"
|
||||
#include "JsonObjectSubscript.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
inline JsonVariant JsonObject::get(JsonObjectKey key) const {
|
||||
node_type *node = getNodeAt(key.c_str());
|
||||
return node ? node->content.value : JsonVariant();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T JsonObject::get(JsonObjectKey key) const {
|
||||
node_type *node = getNodeAt(key.c_str());
|
||||
return node ? node->content.value.as<T>() : JsonVariant::invalid<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool JsonObject::is(JsonObjectKey key) const {
|
||||
node_type *node = getNodeAt(key.c_str());
|
||||
return node ? node->content.value.is<T>() : false;
|
||||
}
|
||||
|
||||
inline JsonObjectSubscript<const char *> JsonObject::operator[](
|
||||
const char *key) {
|
||||
return JsonObjectSubscript<const char *>(*this, key);
|
||||
}
|
||||
|
||||
inline JsonObjectSubscript<const String &> JsonObject::operator[](
|
||||
const String &key) {
|
||||
return JsonObjectSubscript<const String &>(*this, key);
|
||||
}
|
||||
|
||||
inline JsonVariant JsonObject::operator[](JsonObjectKey key) const {
|
||||
return get(key);
|
||||
}
|
||||
|
||||
inline bool JsonObject::containsKey(JsonObjectKey key) const {
|
||||
return getNodeAt(key.c_str()) != NULL;
|
||||
}
|
||||
|
||||
inline void JsonObject::remove(JsonObjectKey key) {
|
||||
removeNode(getNodeAt(key.c_str()));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool JsonObject::setNodeAt(JsonObjectKey key, T value) {
|
||||
node_type *node = getNodeAt(key.c_str());
|
||||
if (!node) node = addNewNode();
|
||||
return node && setNodeKey(node, key) && setNodeValue<T>(node, value);
|
||||
}
|
||||
|
||||
inline bool JsonObject::setNodeKey(node_type *node, JsonObjectKey key) {
|
||||
if (key.needs_copy()) {
|
||||
node->content.key = _buffer->strdup(key.c_str());
|
||||
if (node->content.key == NULL) return false;
|
||||
} else {
|
||||
node->content.key = key.c_str();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline bool JsonObject::setNodeValue(node_type *node, TValue value) {
|
||||
node->content.value = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonObject::setNodeValue(node_type *node, String &value) {
|
||||
node->content.value = _buffer->strdup(value);
|
||||
return node->content.value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonObject::setNodeValue(node_type *node, const String &value) {
|
||||
node->content.value = _buffer->strdup(value);
|
||||
return node->content.value;
|
||||
}
|
||||
|
||||
template <typename TImplem>
|
||||
inline const JsonObjectSubscript<const char *> JsonVariantBase<TImplem>::
|
||||
operator[](const char *key) const {
|
||||
return asObject()[key];
|
||||
}
|
||||
|
||||
template <typename TImplem>
|
||||
inline const JsonObjectSubscript<const String &> JsonVariantBase<TImplem>::
|
||||
operator[](const String &key) const {
|
||||
return asObject()[key];
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonObject const &JsonVariant::invalid<JsonObject const &>() {
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonObject &JsonVariant::invalid<JsonObject &>() {
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
inline JsonObject &JsonVariant::asObject() const {
|
||||
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
inline JsonObject &JsonObject::createNestedObject(JsonObjectKey key) {
|
||||
if (!_buffer) return JsonObject::invalid();
|
||||
JsonObject &array = _buffer->createObject();
|
||||
setNodeAt<const JsonVariant &>(key, array);
|
||||
return array;
|
||||
}
|
||||
|
||||
inline JsonObject &JsonArray::createNestedObject() {
|
||||
if (!_buffer) return JsonObject::invalid();
|
||||
JsonObject &object = _buffer->createObject();
|
||||
add(object);
|
||||
return object;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonArray.hpp"
|
||||
#include "JsonObject.hpp"
|
||||
#include "JsonObjectSubscript.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
template <typename TString>
|
||||
inline JsonObject &JsonObject::createNestedObject(const TString &key) {
|
||||
if (!_buffer) return JsonObject::invalid();
|
||||
JsonObject &object = _buffer->createObject();
|
||||
set(key, object);
|
||||
return object;
|
||||
}
|
||||
|
||||
template <typename TString>
|
||||
inline JsonArray &JsonObject::createNestedArray(const TString &key) {
|
||||
if (!_buffer) return JsonArray::invalid();
|
||||
JsonArray &array = _buffer->createArray();
|
||||
set(key, array);
|
||||
return array;
|
||||
}
|
||||
}
|
27
include/ArduinoJson/JsonObjectKey.hpp
Normal file
27
include/ArduinoJson/JsonObjectKey.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino/String.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// Represents a key in a JsonObject
|
||||
class JsonObjectKey {
|
||||
public:
|
||||
JsonObjectKey(const char* key) : _value(key), _needs_copy(false) {}
|
||||
JsonObjectKey(const String& key) : _value(key.c_str()), _needs_copy(true) {}
|
||||
|
||||
const char* c_str() const { return _value; }
|
||||
bool needs_copy() const { return _needs_copy; }
|
||||
|
||||
private:
|
||||
const char* _value;
|
||||
bool _needs_copy;
|
||||
};
|
||||
}
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Configuration.hpp"
|
||||
#include "JsonVariantBase.hpp"
|
||||
#include "TypeTraits/ConstRefOrConstPtr.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
@ -19,37 +18,40 @@
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
template <typename TString>
|
||||
class JsonObjectSubscript
|
||||
: public JsonVariantBase<JsonObjectSubscript<TString> > {
|
||||
// const String&
|
||||
// const std::string&
|
||||
// const char*
|
||||
typedef typename TypeTraits::ConstRefOrConstPtr<TString>::type TStringRef;
|
||||
|
||||
template <typename TKey>
|
||||
class JsonObjectSubscript : public JsonVariantBase<JsonObjectSubscript<TKey> > {
|
||||
public:
|
||||
FORCE_INLINE JsonObjectSubscript(JsonObject& object, TStringRef key)
|
||||
FORCE_INLINE JsonObjectSubscript(JsonObject& object, TKey key)
|
||||
: _object(object), _key(key) {}
|
||||
|
||||
FORCE_INLINE JsonObjectSubscript<TString>& operator=(
|
||||
const JsonObjectSubscript<TString>& src) {
|
||||
_object.set(_key, src);
|
||||
JsonObjectSubscript<TKey>& operator=(const JsonObjectSubscript<TKey>& src) {
|
||||
_object.set<const JsonVariant&>(_key, src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE JsonObjectSubscript<TString>& operator=(const T& src) {
|
||||
_object.set(_key, src);
|
||||
typename TypeTraits::EnableIf<JsonObject::CanSet<T&>::value,
|
||||
JsonObjectSubscript<TKey> >::type&
|
||||
operator=(const T& src) {
|
||||
_object.set<T&>(_key, const_cast<T&>(src));
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool success() const {
|
||||
return _object.containsKey(_key);
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<JsonObject::CanSet<T>::value,
|
||||
JsonObjectSubscript<TKey> >::type&
|
||||
operator=(T src) {
|
||||
_object.set<T>(_key, src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool success() const { return _object.containsKey(_key); }
|
||||
|
||||
FORCE_INLINE operator JsonVariant() const { return _object.get(_key); }
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type as() const {
|
||||
return _object.get<TValue, TStringRef>(_key);
|
||||
FORCE_INLINE TValue as() const {
|
||||
return _object.get<TValue>(_key);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
@ -58,32 +60,38 @@ class JsonObjectSubscript
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue& value) {
|
||||
return _object.set(_key, value);
|
||||
FORCE_INLINE bool set(TValue value) {
|
||||
return _object.set<TValue>(_key, value);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(const TValue& value, uint8_t decimals) {
|
||||
FORCE_INLINE bool set(TValue value, uint8_t decimals) {
|
||||
return _object.set(_key, value, decimals);
|
||||
}
|
||||
|
||||
FORCE_INLINE JsonVariant get() { return _object.get(_key); }
|
||||
|
||||
void writeTo(Internals::JsonWriter& writer) const {
|
||||
_object.get(_key).writeTo(writer);
|
||||
}
|
||||
|
||||
private:
|
||||
JsonObject& _object;
|
||||
TStringRef _key;
|
||||
TKey _key;
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
template <typename TString>
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
const JsonObjectSubscript<TString>& source) {
|
||||
inline std::ostream& operator<<(
|
||||
std::ostream& os, const JsonObjectSubscript<const String&>& source) {
|
||||
return source.printTo(os);
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(
|
||||
std::ostream& os, const JsonObjectSubscript<const char*>& source) {
|
||||
return source.printTo(os);
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename TString>
|
||||
inline JsonObjectSubscript<TString> JsonObject::operator[](const TString& key) {
|
||||
return JsonObjectSubscript<TString>(*this, key);
|
||||
}
|
||||
} // namespace ArduinoJson
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonObjectKey.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
@ -10,18 +10,15 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h> // for uint8_t
|
||||
|
||||
#include "Data/JsonVariantContent.hpp"
|
||||
#include "Data/JsonVariantDefault.hpp"
|
||||
#include "Data/JsonVariantType.hpp"
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/JsonVariantContent.hpp"
|
||||
#include "Internals/JsonVariantType.hpp"
|
||||
#include "Internals/Unparsed.hpp"
|
||||
#include "JsonVariantBase.hpp"
|
||||
#include "RawJson.hpp"
|
||||
#include "Serialization/JsonPrintable.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||
#include "TypeTraits/IsIntegral.hpp"
|
||||
#include "TypeTraits/IsSame.hpp"
|
||||
#include "TypeTraits/IsSignedIntegral.hpp"
|
||||
#include "TypeTraits/IsUnsignedIntegral.hpp"
|
||||
#include "TypeTraits/RemoveConst.hpp"
|
||||
#include "TypeTraits/RemoveReference.hpp"
|
||||
|
||||
@ -39,20 +36,16 @@ 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 &);
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
struct IsConstructibleFrom;
|
||||
|
||||
// Creates an uninitialized JsonVariant
|
||||
JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
|
||||
FORCE_INLINE JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
|
||||
|
||||
// Create a JsonVariant containing a boolean value.
|
||||
// It will be serialized as "true" or "false" in JSON.
|
||||
JsonVariant(bool value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_BOOLEAN;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
FORCE_INLINE JsonVariant(bool value);
|
||||
|
||||
// Create a JsonVariant containing a floating point value.
|
||||
// The second argument specifies the number of decimal digits to write in
|
||||
@ -60,87 +53,49 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
||||
// JsonVariant(double value, uint8_t decimals);
|
||||
// JsonVariant(float value, uint8_t decimals);
|
||||
template <typename T>
|
||||
JsonVariant(T value, uint8_t decimals = 2,
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
|
||||
FORCE_INLINE JsonVariant(
|
||||
T value, uint8_t decimals = 2,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
|
||||
T>::type * = 0) {
|
||||
using namespace Internals;
|
||||
_type = static_cast<JsonVariantType>(JSON_FLOAT_0_DECIMALS + decimals);
|
||||
_content.asFloat = static_cast<JsonFloat>(value);
|
||||
}
|
||||
|
||||
// Create a JsonVariant containing an integer value.
|
||||
// JsonVariant(signed short)
|
||||
// JsonVariant(signed int)
|
||||
// JsonVariant(signed long)
|
||||
// JsonVariant(short)
|
||||
// JsonVariant(int)
|
||||
// JsonVariant(long)
|
||||
template <typename T>
|
||||
JsonVariant(T value,
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSignedIntegral<T>::value>::type * = 0) {
|
||||
FORCE_INLINE JsonVariant(
|
||||
T value, typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value,
|
||||
T>::type * = 0) {
|
||||
using namespace Internals;
|
||||
if (value >= 0) {
|
||||
_type = JSON_POSITIVE_INTEGER;
|
||||
_content.asInteger = static_cast<JsonUInt>(value);
|
||||
} else {
|
||||
_type = JSON_NEGATIVE_INTEGER;
|
||||
_content.asInteger = static_cast<JsonUInt>(-value);
|
||||
}
|
||||
}
|
||||
// JsonVariant(unsigned short)
|
||||
// JsonVariant(unsigned int)
|
||||
// JsonVariant(unsigned long)
|
||||
template <typename T>
|
||||
JsonVariant(T value,
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsUnsignedIntegral<T>::value>::type * = 0) {
|
||||
using namespace Internals;
|
||||
_type = JSON_POSITIVE_INTEGER;
|
||||
_content.asInteger = static_cast<JsonUInt>(value);
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
// Create a JsonVariant containing a string.
|
||||
JsonVariant(const char *value) {
|
||||
_type = Internals::JSON_STRING;
|
||||
_content.asString = value;
|
||||
}
|
||||
FORCE_INLINE JsonVariant(const char *value);
|
||||
|
||||
// Create a JsonVariant containing an unparsed string
|
||||
JsonVariant(RawJson value) {
|
||||
_type = Internals::JSON_UNPARSED;
|
||||
_content.asString = value;
|
||||
}
|
||||
FORCE_INLINE JsonVariant(Internals::Unparsed value);
|
||||
|
||||
// Create a JsonVariant containing a reference to an array.
|
||||
// CAUTION: we are lying about constness, because the array can be modified if
|
||||
// the variant is converted back to a JsonArray&
|
||||
JsonVariant(const JsonArray &array);
|
||||
FORCE_INLINE JsonVariant(JsonArray &array);
|
||||
|
||||
// Create a JsonVariant containing a reference to an object.
|
||||
// CAUTION: we are lying about constness, because the object can be modified
|
||||
// if the variant is converted back to a JsonObject&
|
||||
JsonVariant(const JsonObject &object);
|
||||
FORCE_INLINE JsonVariant(JsonObject &object);
|
||||
|
||||
// Get the variant as the specified type.
|
||||
//
|
||||
// short as<signed short>() const;
|
||||
// int as<signed int>() const;
|
||||
// long as<signed long>() const;
|
||||
// short as<short>() const;
|
||||
// int as<int>() const;
|
||||
// long as<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());
|
||||
}
|
||||
//
|
||||
// short as<unsigned short>() const;
|
||||
// int as<unsigned int>() const;
|
||||
// long as<unsigned long>() const;
|
||||
template <typename T>
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsUnsignedIntegral<T>::value,
|
||||
T>::type
|
||||
as() const {
|
||||
return static_cast<T>(asUnsignedInteger());
|
||||
}
|
||||
//
|
||||
// double as<double>() const;
|
||||
// float as<float>() const;
|
||||
template <typename T>
|
||||
@ -149,29 +104,21 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
||||
as() const {
|
||||
return static_cast<T>(asFloat());
|
||||
}
|
||||
//
|
||||
// const String as<String>() const;
|
||||
template <typename T>
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, String>::value,
|
||||
T>::type
|
||||
as() const {
|
||||
return toString();
|
||||
}
|
||||
// const char* as<const char*>() const;
|
||||
// const char* as<char*>() const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
|
||||
TypeTraits::IsSame<T, char *>::value,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value,
|
||||
const char *>::type
|
||||
as() const {
|
||||
return asString();
|
||||
}
|
||||
//
|
||||
// std::string as<std::string>() const;
|
||||
// String as<String>() const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<Internals::StringFuncs<T>::has_append, T>::type
|
||||
as() const {
|
||||
const char *cstr = asString();
|
||||
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,
|
||||
@ -179,164 +126,53 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
||||
as() const {
|
||||
return asInteger() != 0;
|
||||
}
|
||||
//
|
||||
// JsonArray& as<JsonArray> const;
|
||||
// JsonArray& as<JsonArray&> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
|
||||
JsonArray>::value,
|
||||
JsonArray &>::type
|
||||
as() const {
|
||||
return asArray();
|
||||
}
|
||||
//
|
||||
// const JsonArray& as<const JsonArray&> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
|
||||
const JsonArray>::value,
|
||||
const JsonArray &>::type
|
||||
as() const {
|
||||
return asArray();
|
||||
}
|
||||
//
|
||||
// JsonObject& as<JsonObject> const;
|
||||
// JsonObject& as<JsonObject&> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
|
||||
JsonObject>::value,
|
||||
JsonObject &>::type
|
||||
as() const {
|
||||
return asObject();
|
||||
}
|
||||
//
|
||||
// JsonObject& as<const JsonObject> const;
|
||||
// JsonObject& as<const JsonObject&> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
|
||||
const JsonObject>::value,
|
||||
const JsonObject &>::type
|
||||
as() const {
|
||||
return asObject();
|
||||
}
|
||||
//
|
||||
// JsonVariant as<JsonVariant> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, JsonVariant>::value,
|
||||
T>::type
|
||||
as() const {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// 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;
|
||||
template <typename T>
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value &&
|
||||
!TypeTraits::IsSame<T, bool>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return isInteger();
|
||||
}
|
||||
//
|
||||
// double is<double>() const;
|
||||
// float is<float>() const;
|
||||
template <typename T>
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return isFloat();
|
||||
}
|
||||
//
|
||||
// const bool is<bool>() const
|
||||
template <typename T>
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return isBoolean();
|
||||
}
|
||||
//
|
||||
// bool is<const char*>() const;
|
||||
// bool is<char*>() const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
|
||||
TypeTraits::IsSame<T, char *>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return isString();
|
||||
}
|
||||
//
|
||||
// bool is<JsonArray> const;
|
||||
// bool is<JsonArray&> const;
|
||||
// bool is<const JsonArray&> const;
|
||||
// JsonArray& as<const JsonArray&> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<
|
||||
typename TypeTraits::RemoveConst<
|
||||
typename TypeTraits::RemoveReference<T>::type>::type,
|
||||
JsonArray>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return isArray();
|
||||
JsonArray &>::type
|
||||
as() const {
|
||||
return asArray();
|
||||
}
|
||||
//
|
||||
// bool is<JsonObject> const;
|
||||
// bool is<JsonObject&> const;
|
||||
// bool is<const JsonObject&> const;
|
||||
// JsonObject& as<JsonObject> const;
|
||||
// JsonObject& as<JsonObject&> const;
|
||||
// JsonObject& as<const JsonObject&> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<
|
||||
typename TypeTraits::RemoveConst<
|
||||
typename TypeTraits::RemoveReference<T>::type>::type,
|
||||
JsonObject>::value,
|
||||
bool>::type
|
||||
is() const {
|
||||
return isObject();
|
||||
JsonObject &>::type
|
||||
as() const {
|
||||
return asObject();
|
||||
}
|
||||
|
||||
// Returns true if the variant has a value
|
||||
bool success() const {
|
||||
return _type != Internals::JSON_UNDEFINED;
|
||||
}
|
||||
// Tells weither the variant has the specified type.
|
||||
// Returns true if the variant has type type T, false otherwise.
|
||||
template <typename T>
|
||||
bool is() const;
|
||||
|
||||
// Serialize the variant to a JsonWriter
|
||||
void writeTo(Internals::JsonWriter &writer) const;
|
||||
|
||||
// TODO: rename
|
||||
template <typename T>
|
||||
static T invalid();
|
||||
|
||||
// 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
|
||||
template <typename T>
|
||||
JsonVariant(T value, typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<T, char>::value>::type * = 0);
|
||||
|
||||
String toString() const;
|
||||
Internals::JsonFloat asFloat() const;
|
||||
Internals::JsonInteger asInteger() const;
|
||||
Internals::JsonUInt asUnsignedInteger() const;
|
||||
bool isBoolean() const;
|
||||
bool isFloat() const;
|
||||
bool isInteger() const;
|
||||
bool isArray() const {
|
||||
return _type == Internals::JSON_ARRAY;
|
||||
}
|
||||
bool isObject() const {
|
||||
return _type == Internals::JSON_OBJECT;
|
||||
}
|
||||
bool isString() const {
|
||||
return _type == Internals::JSON_STRING ||
|
||||
(_type == Internals::JSON_UNPARSED && _content.asString &&
|
||||
!strcmp("null", _content.asString));
|
||||
}
|
||||
|
||||
// The current type of the variant
|
||||
Internals::JsonVariantType _type;
|
||||
@ -352,4 +188,29 @@ inline JsonVariant float_with_n_digits(float value, uint8_t digits) {
|
||||
inline JsonVariant double_with_n_digits(double value, uint8_t digits) {
|
||||
return JsonVariant(value, digits);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct JsonVariant::IsConstructibleFrom {
|
||||
static const bool value =
|
||||
TypeTraits::IsIntegral<T>::value ||
|
||||
TypeTraits::IsFloatingPoint<T>::value ||
|
||||
TypeTraits::IsSame<T, bool>::value ||
|
||||
TypeTraits::IsSame<T, char *>::value ||
|
||||
TypeTraits::IsSame<T, const char *>::value ||
|
||||
TypeTraits::IsSame<T, JsonArray &>::value ||
|
||||
TypeTraits::IsSame<T, const JsonArray &>::value ||
|
||||
TypeTraits::IsSame<T, JsonArraySubscript &>::value ||
|
||||
TypeTraits::IsSame<T, const JsonArraySubscript &>::value ||
|
||||
TypeTraits::IsSame<T, JsonObject &>::value ||
|
||||
TypeTraits::IsSame<T, const JsonObject &>::value ||
|
||||
TypeTraits::IsSame<T, JsonObjectSubscript<const char *> &>::value ||
|
||||
TypeTraits::IsSame<T, const JsonObjectSubscript<const char *> &>::value ||
|
||||
TypeTraits::IsSame<T, JsonObjectSubscript<String> &>::value ||
|
||||
TypeTraits::IsSame<T, const JsonObjectSubscript<String> &>::value ||
|
||||
TypeTraits::IsSame<T, JsonVariant &>::value ||
|
||||
TypeTraits::IsSame<T, const JsonVariant &>::value;
|
||||
};
|
||||
}
|
||||
|
||||
// Include inline implementations
|
||||
#include "JsonVariant.ipp"
|
||||
|
150
include/ArduinoJson/JsonVariant.ipp
Normal file
150
include/ArduinoJson/JsonVariant.ipp
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Configuration.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
#include "Internals/Parse.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
inline JsonVariant::JsonVariant(bool value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_BOOLEAN;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(const char *value) {
|
||||
_type = Internals::JSON_STRING;
|
||||
_content.asString = value;
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(Internals::Unparsed value) {
|
||||
_type = Internals::JSON_UNPARSED;
|
||||
_content.asString = value;
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(JsonArray &array) {
|
||||
_type = Internals::JSON_ARRAY;
|
||||
_content.asArray = &array;
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(JsonObject &object) {
|
||||
_type = Internals::JSON_OBJECT;
|
||||
_content.asObject = &object;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T JsonVariant::invalid() {
|
||||
return T();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool JsonVariant::is() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> // in .cpp
|
||||
bool JsonVariant::is<signed long>() const;
|
||||
|
||||
template <> // in .cpp
|
||||
bool JsonVariant::is<double>() const;
|
||||
|
||||
template <> // int .cpp
|
||||
bool JsonVariant::is<bool>() const;
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<char const *>() const {
|
||||
return _type == Internals::JSON_STRING;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<float>() const {
|
||||
return is<double>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<JsonArray &>() const {
|
||||
return _type == Internals::JSON_ARRAY;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<JsonArray const &>() const {
|
||||
return _type == Internals::JSON_ARRAY;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<JsonObject &>() const {
|
||||
return _type == Internals::JSON_OBJECT;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<JsonObject const &>() const {
|
||||
return _type == Internals::JSON_OBJECT;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<signed char>() const {
|
||||
return is<signed long>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<signed int>() const {
|
||||
return is<signed long>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<signed short>() const {
|
||||
return is<signed long>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<unsigned char>() const {
|
||||
return is<signed long>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<unsigned int>() const {
|
||||
return is<signed long>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<unsigned long>() const {
|
||||
return is<signed long>();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::is<unsigned short>() const {
|
||||
return is<signed long>();
|
||||
}
|
||||
|
||||
inline Internals::JsonInteger JsonVariant::asInteger() const {
|
||||
if (_type == Internals::JSON_INTEGER || _type == Internals::JSON_BOOLEAN)
|
||||
return _content.asInteger;
|
||||
|
||||
if (_type >= Internals::JSON_FLOAT_0_DECIMALS)
|
||||
return static_cast<Internals::JsonInteger>(_content.asFloat);
|
||||
|
||||
if ((_type == Internals::JSON_STRING || _type == Internals::JSON_UNPARSED) &&
|
||||
_content.asString) {
|
||||
if (!strcmp("true", _content.asString)) return 1;
|
||||
return Internals::parse<Internals::JsonInteger>(_content.asString);
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
|
||||
return source.printTo(os);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ArduinoJson
|
@ -7,9 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Data/JsonVariantAs.hpp"
|
||||
#include "Polyfills/attributes.hpp"
|
||||
#include "Serialization/JsonPrintable.hpp"
|
||||
#include "Internals/ForceInline.hpp"
|
||||
#include "JsonObjectKey.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
@ -21,35 +20,20 @@ class JsonObjectSubscript;
|
||||
template <typename TImpl>
|
||||
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
|
||||
public:
|
||||
// DEPRECATED: use as<char*>() instead
|
||||
FORCE_INLINE const char *asString() const {
|
||||
return as<const char *>();
|
||||
}
|
||||
FORCE_INLINE const char *asString() const { return as<const char *>(); }
|
||||
|
||||
// Gets the variant as an array.
|
||||
// Returns a reference to the JsonArray or JsonArray::invalid() if the
|
||||
// variant
|
||||
// is not an array.
|
||||
FORCE_INLINE operator JsonArray &() const {
|
||||
return as<JsonArray &>();
|
||||
}
|
||||
|
||||
// DEPRECATED: use as<JsonArray>() instead
|
||||
FORCE_INLINE JsonArray &asArray() const {
|
||||
return as<JsonArray &>();
|
||||
}
|
||||
FORCE_INLINE operator JsonArray &() const { return as<JsonArray &>(); }
|
||||
FORCE_INLINE JsonArray &asArray() const { return as<JsonArray &>(); }
|
||||
|
||||
// Gets the variant as an object.
|
||||
// Returns a reference to the JsonObject or JsonObject::invalid() if the
|
||||
// variant is not an object.
|
||||
FORCE_INLINE operator JsonObject &() const {
|
||||
return as<JsonObject &>();
|
||||
}
|
||||
|
||||
// DEPRECATED: use as<JsonObject>() instead
|
||||
FORCE_INLINE JsonObject &asObject() const {
|
||||
return as<JsonObject &>();
|
||||
}
|
||||
FORCE_INLINE operator JsonObject &() const { return as<JsonObject &>(); }
|
||||
FORCE_INLINE JsonObject &asObject() const { return as<JsonObject &>(); }
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE operator T() const {
|
||||
@ -57,45 +41,93 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE const typename Internals::JsonVariantAs<T>::type as() const {
|
||||
FORCE_INLINE const T as() const {
|
||||
return impl()->template as<T>();
|
||||
}
|
||||
|
||||
// Mimics an array or an object.
|
||||
// Returns the size of the array or object if the variant has that type.
|
||||
// Returns 0 if the variant is neither an array nor an object
|
||||
size_t size() const {
|
||||
return asArray().size() + asObject().size();
|
||||
}
|
||||
size_t size() const { return asArray().size() + asObject().size(); }
|
||||
|
||||
// Mimics an array.
|
||||
// Returns the element at specified index if the variant is an array.
|
||||
// Returns JsonVariant::invalid() if the variant is not an array.
|
||||
FORCE_INLINE const JsonArraySubscript operator[](int index) const;
|
||||
FORCE_INLINE JsonArraySubscript operator[](int index);
|
||||
|
||||
// Mimics an object.
|
||||
// Returns the value associated with the specified key if the variant is
|
||||
// an object.
|
||||
// Return JsonVariant::invalid() if the variant is not an object.
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename TypeTraits::EnableIf<Internals::StringFuncs<TString>::has_equals,
|
||||
const JsonObjectSubscript<TString> >::type
|
||||
operator[](const TString &key) const {
|
||||
return asObject()[key];
|
||||
}
|
||||
template <typename TString>
|
||||
FORCE_INLINE
|
||||
typename TypeTraits::EnableIf<Internals::StringFuncs<TString>::has_equals,
|
||||
JsonObjectSubscript<TString> >::type
|
||||
operator[](const TString &key) {
|
||||
return asObject()[key];
|
||||
}
|
||||
FORCE_INLINE const JsonObjectSubscript<const char *> operator[](
|
||||
const char *key) const;
|
||||
FORCE_INLINE const JsonObjectSubscript<const String &> operator[](
|
||||
const String &key) const;
|
||||
|
||||
// Serialize the variant to a JsonWriter
|
||||
void writeTo(Internals::JsonWriter &writer) const;
|
||||
|
||||
private:
|
||||
const TImpl *impl() const {
|
||||
return static_cast<const TImpl *>(this);
|
||||
}
|
||||
const TImpl *impl() const { return static_cast<const TImpl *>(this); }
|
||||
};
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator==(const JsonVariantBase<TImpl> &left, TComparand right) {
|
||||
return left.template as<TComparand>() == right;
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator==(TComparand left, const JsonVariantBase<TImpl> &right) {
|
||||
return left == right.template as<TComparand>();
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator!=(const JsonVariantBase<TImpl> &left, TComparand right) {
|
||||
return left.template as<TComparand>() != right;
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator!=(TComparand left, const JsonVariantBase<TImpl> &right) {
|
||||
return left != right.template as<TComparand>();
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator<=(const JsonVariantBase<TImpl> &left, TComparand right) {
|
||||
return left.template as<TComparand>() <= right;
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator<=(TComparand left, const JsonVariantBase<TImpl> &right) {
|
||||
return left <= right.template as<TComparand>();
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator>=(const JsonVariantBase<TImpl> &left, TComparand right) {
|
||||
return left.template as<TComparand>() >= right;
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator>=(TComparand left, const JsonVariantBase<TImpl> &right) {
|
||||
return left >= right.template as<TComparand>();
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator<(const JsonVariantBase<TImpl> &left, TComparand right) {
|
||||
return left.template as<TComparand>() < right;
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator<(TComparand left, const JsonVariantBase<TImpl> &right) {
|
||||
return left < right.template as<TComparand>();
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator>(const JsonVariantBase<TImpl> &left, TComparand right) {
|
||||
return left.template as<TComparand>() > right;
|
||||
}
|
||||
|
||||
template <typename TImpl, typename TComparand>
|
||||
inline bool operator>(TComparand left, const JsonVariantBase<TImpl> &right) {
|
||||
return left > right.template as<TComparand>();
|
||||
}
|
||||
}
|
||||
|
@ -1,106 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "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::StringFuncs<TString>::has_equals>::type> {
|
||||
static bool equals(const TVariant &variant, const TString &comparand) {
|
||||
const char *value = variant.template as<const char *>();
|
||||
return Internals::StringFuncs<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>();
|
||||
}
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Configuration.hpp"
|
||||
#include "Data/Parse.hpp"
|
||||
#include "JsonArray.hpp"
|
||||
#include "JsonObject.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
|
||||
#include <errno.h> // for errno
|
||||
#include <stdlib.h> // for strtol, strtod
|
||||
#include <string.h> // for strcmp
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
inline JsonVariant::JsonVariant(const JsonArray &array) {
|
||||
if (array.success()) {
|
||||
_type = Internals::JSON_ARRAY;
|
||||
_content.asArray = const_cast<JsonArray *>(&array);
|
||||
} else {
|
||||
_type = Internals::JSON_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(const JsonObject &object) {
|
||||
if (object.success()) {
|
||||
_type = Internals::JSON_OBJECT;
|
||||
_content.asObject = const_cast<JsonObject *>(&object);
|
||||
} else {
|
||||
_type = Internals::JSON_UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
inline JsonArray &JsonVariant::asArray() const {
|
||||
if (_type == Internals::JSON_ARRAY) return *_content.asArray;
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
inline JsonObject &JsonVariant::asObject() const {
|
||||
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
inline Internals::JsonInteger JsonVariant::asInteger() const {
|
||||
using namespace Internals;
|
||||
switch (_type) {
|
||||
case JSON_UNDEFINED:
|
||||
return 0;
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_BOOLEAN:
|
||||
return _content.asInteger;
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return -static_cast<Internals::JsonInteger>(_content.asInteger);
|
||||
case JSON_STRING:
|
||||
case JSON_UNPARSED:
|
||||
if (!_content.asString) return 0;
|
||||
if (!strcmp("true", _content.asString)) return 1;
|
||||
return parse<Internals::JsonInteger>(_content.asString);
|
||||
default:
|
||||
return static_cast<Internals::JsonInteger>(_content.asFloat);
|
||||
}
|
||||
}
|
||||
|
||||
inline Internals::JsonUInt JsonVariant::asUnsignedInteger() const {
|
||||
using namespace Internals;
|
||||
switch (_type) {
|
||||
case JSON_UNDEFINED:
|
||||
return 0;
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_BOOLEAN:
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return _content.asInteger;
|
||||
case JSON_STRING:
|
||||
case JSON_UNPARSED:
|
||||
if (!_content.asString) return 0;
|
||||
if (!strcmp("true", _content.asString)) return 1;
|
||||
return parse<Internals::JsonUInt>(_content.asString);
|
||||
default:
|
||||
return static_cast<Internals::JsonUInt>(_content.asFloat);
|
||||
}
|
||||
}
|
||||
|
||||
inline const char *JsonVariant::asString() const {
|
||||
using namespace Internals;
|
||||
if (_type == JSON_UNPARSED && _content.asString &&
|
||||
!strcmp("null", _content.asString))
|
||||
return NULL;
|
||||
if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline Internals::JsonFloat JsonVariant::asFloat() const {
|
||||
using namespace Internals;
|
||||
switch (_type) {
|
||||
case JSON_UNDEFINED:
|
||||
return 0;
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
case JSON_BOOLEAN:
|
||||
return static_cast<JsonFloat>(_content.asInteger);
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
return -static_cast<JsonFloat>(_content.asInteger);
|
||||
case JSON_STRING:
|
||||
case JSON_UNPARSED:
|
||||
return _content.asString ? parse<JsonFloat>(_content.asString) : 0;
|
||||
default:
|
||||
return _content.asFloat;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool JsonVariant::isBoolean() const {
|
||||
using namespace Internals;
|
||||
if (_type == JSON_BOOLEAN) return true;
|
||||
|
||||
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
|
||||
|
||||
return !strcmp(_content.asString, "true") ||
|
||||
!strcmp(_content.asString, "false");
|
||||
}
|
||||
|
||||
inline bool JsonVariant::isInteger() const {
|
||||
using namespace Internals;
|
||||
if (_type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER)
|
||||
return true;
|
||||
|
||||
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
|
||||
|
||||
char *end;
|
||||
errno = 0;
|
||||
strtol(_content.asString, &end, 10);
|
||||
|
||||
return *end == '\0' && errno == 0;
|
||||
}
|
||||
|
||||
inline bool JsonVariant::isFloat() const {
|
||||
using namespace Internals;
|
||||
if (_type >= JSON_FLOAT_0_DECIMALS) return true;
|
||||
|
||||
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
|
||||
|
||||
char *end;
|
||||
errno = 0;
|
||||
strtod(_content.asString, &end);
|
||||
|
||||
return *end == '\0' && errno == 0 && !is<long>();
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
|
||||
return source.printTo(os);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ArduinoJson
|
@ -1,111 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
// If Visual Studo <= 2012
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
|
||||
#include <float.h>
|
||||
|
||||
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
|
@ -1,47 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Polyfills {
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
// on embedded platform, favor code size over speed
|
||||
|
||||
template <typename T>
|
||||
short normalize(T& value) {
|
||||
short powersOf10 = 0;
|
||||
while (value && value < 1) {
|
||||
powersOf10--;
|
||||
value *= 10;
|
||||
}
|
||||
while (value > 10) {
|
||||
powersOf10++;
|
||||
value /= 10;
|
||||
}
|
||||
return powersOf10;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// on non-embedded platform, favor speed over code size
|
||||
|
||||
template <typename T>
|
||||
short normalize(T& value) {
|
||||
if (value == 0.0) return 0;
|
||||
|
||||
short powersOf10 = static_cast<short>(floor(log10(value)));
|
||||
value /= pow(T(10), powersOf10);
|
||||
|
||||
return powersOf10;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
// This class reproduces Arduino's Print class
|
||||
class Print {
|
||||
public:
|
||||
virtual ~Print() {}
|
||||
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
|
||||
size_t print(const char* s) {
|
||||
size_t n = 0;
|
||||
while (*s) {
|
||||
n += write(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
|
@ -1,33 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonWriter.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
class JsonArray;
|
||||
class JsonArraySubscript;
|
||||
class JsonObject;
|
||||
template <typename TKey>
|
||||
class JsonObjectSubscript;
|
||||
class JsonVariant;
|
||||
|
||||
namespace Internals {
|
||||
|
||||
class JsonSerializer {
|
||||
public:
|
||||
static void serialize(const JsonArray &, JsonWriter &);
|
||||
static void serialize(const JsonArraySubscript &, JsonWriter &);
|
||||
static void serialize(const JsonObject &, JsonWriter &);
|
||||
template <typename TKey>
|
||||
static void serialize(const JsonObjectSubscript<TKey> &, JsonWriter &);
|
||||
static void serialize(const JsonVariant &, JsonWriter &);
|
||||
};
|
||||
}
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonArray.hpp"
|
||||
#include "../JsonArraySubscript.hpp"
|
||||
#include "../JsonObject.hpp"
|
||||
#include "../JsonObjectSubscript.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "JsonSerializer.hpp"
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonArray& array, JsonWriter& writer) {
|
||||
writer.beginArray();
|
||||
|
||||
JsonArray::const_iterator it = array.begin();
|
||||
while (it != array.end()) {
|
||||
serialize(*it, writer);
|
||||
|
||||
++it;
|
||||
if (it == array.end()) break;
|
||||
|
||||
writer.writeComma();
|
||||
}
|
||||
|
||||
writer.endArray();
|
||||
}
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonArraySubscript& arraySubscript, JsonWriter& writer) {
|
||||
serialize(arraySubscript.as<JsonVariant>(), writer);
|
||||
}
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonObject& object, JsonWriter& writer) {
|
||||
writer.beginObject();
|
||||
|
||||
JsonObject::const_iterator it = object.begin();
|
||||
while (it != object.end()) {
|
||||
writer.writeString(it->key);
|
||||
writer.writeColon();
|
||||
serialize(it->value, writer);
|
||||
|
||||
++it;
|
||||
if (it == object.end()) break;
|
||||
|
||||
writer.writeComma();
|
||||
}
|
||||
|
||||
writer.endObject();
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonObjectSubscript<TKey>& objectSubscript, JsonWriter& writer) {
|
||||
serialize(objectSubscript.template as<JsonVariant>(), writer);
|
||||
}
|
||||
|
||||
inline void ArduinoJson::Internals::JsonSerializer::serialize(
|
||||
const JsonVariant& variant, JsonWriter& writer) {
|
||||
switch (variant._type) {
|
||||
case JSON_UNDEFINED:
|
||||
return;
|
||||
|
||||
case JSON_ARRAY:
|
||||
serialize(*variant._content.asArray, writer);
|
||||
return;
|
||||
|
||||
case JSON_OBJECT:
|
||||
serialize(*variant._content.asObject, writer);
|
||||
return;
|
||||
|
||||
case JSON_STRING:
|
||||
writer.writeString(variant._content.asString);
|
||||
return;
|
||||
|
||||
case JSON_UNPARSED:
|
||||
writer.writeRaw(variant._content.asString);
|
||||
return;
|
||||
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
writer.writeRaw('-');
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
writer.writeInteger(variant._content.asInteger);
|
||||
return;
|
||||
|
||||
case JSON_BOOLEAN:
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Data/Encoding.hpp"
|
||||
#include "../Data/JsonFloat.hpp"
|
||||
#include "../Data/JsonInteger.hpp"
|
||||
#include "../Polyfills/attributes.hpp"
|
||||
#include "../Polyfills/math.hpp"
|
||||
#include "../Polyfills/normalize.hpp"
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Writes the JSON tokens to a Print implementation
|
||||
// This class is used by:
|
||||
// - JsonArray::writeTo()
|
||||
// - JsonObject::writeTo()
|
||||
// - JsonVariant::writeTo()
|
||||
// Its derived by PrettyJsonWriter that overrides some members to add
|
||||
// indentation.
|
||||
class JsonWriter {
|
||||
public:
|
||||
explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
|
||||
|
||||
// Returns the number of bytes sent to the Print implementation.
|
||||
// This is very handy for implementations of printTo() that must return the
|
||||
// number of bytes written.
|
||||
size_t bytesWritten() const {
|
||||
return _length;
|
||||
}
|
||||
|
||||
void beginArray() {
|
||||
writeRaw('[');
|
||||
}
|
||||
void endArray() {
|
||||
writeRaw(']');
|
||||
}
|
||||
|
||||
void beginObject() {
|
||||
writeRaw('{');
|
||||
}
|
||||
void endObject() {
|
||||
writeRaw('}');
|
||||
}
|
||||
|
||||
void writeColon() {
|
||||
writeRaw(':');
|
||||
}
|
||||
void writeComma() {
|
||||
writeRaw(',');
|
||||
}
|
||||
|
||||
void writeBoolean(bool value) {
|
||||
writeRaw(value ? "true" : "false");
|
||||
}
|
||||
|
||||
void writeString(const char *value) {
|
||||
if (!value) {
|
||||
writeRaw("null");
|
||||
} else {
|
||||
writeRaw('\"');
|
||||
while (*value) writeChar(*value++);
|
||||
writeRaw('\"');
|
||||
}
|
||||
}
|
||||
|
||||
void writeChar(char c) {
|
||||
char specialChar = Encoding::escapeChar(c);
|
||||
if (specialChar) {
|
||||
writeRaw('\\');
|
||||
writeRaw(specialChar);
|
||||
} else {
|
||||
writeRaw(c);
|
||||
}
|
||||
}
|
||||
|
||||
void writeFloat(JsonFloat value, uint8_t digits = 2) {
|
||||
if (Polyfills::isNaN(value)) return writeRaw("NaN");
|
||||
|
||||
if (value < 0.0) {
|
||||
writeRaw('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
|
||||
|
||||
short powersOf10;
|
||||
if (value > 1000 || value < 0.001) {
|
||||
powersOf10 = Polyfills::normalize(value);
|
||||
} else {
|
||||
powersOf10 = 0;
|
||||
}
|
||||
|
||||
// Round up last digit (so that print(1.999, 2) prints as "2.00")
|
||||
value += getRoundingBias(digits);
|
||||
|
||||
// Extract the integer part of the value and print it
|
||||
JsonUInt int_part = static_cast<JsonUInt>(value);
|
||||
JsonFloat remainder = value - static_cast<JsonFloat>(int_part);
|
||||
writeInteger(int_part);
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if (digits > 0) {
|
||||
writeRaw('.');
|
||||
}
|
||||
|
||||
// Extract digits from the remainder one at a time
|
||||
while (digits-- > 0) {
|
||||
// Extract digit
|
||||
remainder *= 10.0;
|
||||
char currentDigit = char(remainder);
|
||||
remainder -= static_cast<JsonFloat>(currentDigit);
|
||||
|
||||
// Print
|
||||
writeRaw(char('0' + currentDigit));
|
||||
}
|
||||
|
||||
if (powersOf10 < 0) {
|
||||
writeRaw("e-");
|
||||
writeInteger(-powersOf10);
|
||||
}
|
||||
|
||||
if (powersOf10 > 0) {
|
||||
writeRaw('e');
|
||||
writeInteger(powersOf10);
|
||||
}
|
||||
}
|
||||
|
||||
void writeInteger(JsonUInt value) {
|
||||
char buffer[22];
|
||||
char *ptr = buffer + sizeof(buffer) - 1;
|
||||
|
||||
*ptr = 0;
|
||||
do {
|
||||
*--ptr = static_cast<char>(value % 10 + '0');
|
||||
value /= 10;
|
||||
} while (value);
|
||||
|
||||
writeRaw(ptr);
|
||||
}
|
||||
|
||||
void writeRaw(const char *s) {
|
||||
_length += _sink.print(s);
|
||||
}
|
||||
void writeRaw(char c) {
|
||||
_length += _sink.write(c);
|
||||
}
|
||||
|
||||
protected:
|
||||
Print &_sink;
|
||||
size_t _length;
|
||||
|
||||
private:
|
||||
JsonWriter &operator=(const JsonWriter &); // cannot be assigned
|
||||
|
||||
static JsonFloat getLastDigit(uint8_t digits) {
|
||||
// Designed as a compromise between code size and speed
|
||||
switch (digits) {
|
||||
case 0:
|
||||
return 1e-0;
|
||||
case 1:
|
||||
return 1e-1;
|
||||
case 2:
|
||||
return 1e-2;
|
||||
case 3:
|
||||
return 1e-3;
|
||||
default:
|
||||
return getLastDigit(uint8_t(digits - 4)) * 1e-4;
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE static JsonFloat getRoundingBias(uint8_t digits) {
|
||||
return 0.5 * getLastDigit(digits);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,130 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IndentedPrint.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Converts a compact JSON string into an indented one.
|
||||
class Prettyfier : public Print {
|
||||
public:
|
||||
explicit Prettyfier(IndentedPrint& p) : _sink(p) {
|
||||
_previousChar = 0;
|
||||
_inString = false;
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t c) {
|
||||
size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
|
||||
_previousChar = c;
|
||||
return n;
|
||||
}
|
||||
|
||||
private:
|
||||
Prettyfier& operator=(const Prettyfier&); // cannot be assigned
|
||||
|
||||
bool inEmptyBlock() {
|
||||
return _previousChar == '{' || _previousChar == '[';
|
||||
}
|
||||
|
||||
size_t handleStringChar(uint8_t c) {
|
||||
bool isQuote = c == '"' && _previousChar != '\\';
|
||||
|
||||
if (isQuote) _inString = false;
|
||||
|
||||
return _sink.write(c);
|
||||
}
|
||||
|
||||
size_t handleMarkupChar(uint8_t c) {
|
||||
switch (c) {
|
||||
case '{':
|
||||
case '[':
|
||||
return writeBlockOpen(c);
|
||||
|
||||
case '}':
|
||||
case ']':
|
||||
return writeBlockClose(c);
|
||||
|
||||
case ':':
|
||||
return writeColon();
|
||||
|
||||
case ',':
|
||||
return writeComma();
|
||||
|
||||
case '"':
|
||||
return writeQuoteOpen();
|
||||
|
||||
default:
|
||||
return writeNormalChar(c);
|
||||
}
|
||||
}
|
||||
|
||||
size_t writeBlockClose(uint8_t c) {
|
||||
size_t n = 0;
|
||||
n += unindentIfNeeded();
|
||||
n += _sink.write(c);
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeBlockOpen(uint8_t c) {
|
||||
size_t n = 0;
|
||||
n += indentIfNeeded();
|
||||
n += _sink.write(c);
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeColon() {
|
||||
size_t n = 0;
|
||||
n += _sink.write(':');
|
||||
n += _sink.write(' ');
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeComma() {
|
||||
size_t n = 0;
|
||||
n += _sink.write(',');
|
||||
n += _sink.println();
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeQuoteOpen() {
|
||||
_inString = true;
|
||||
size_t n = 0;
|
||||
n += indentIfNeeded();
|
||||
n += _sink.write('"');
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t writeNormalChar(uint8_t c) {
|
||||
size_t n = 0;
|
||||
n += indentIfNeeded();
|
||||
n += _sink.write(c);
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t indentIfNeeded() {
|
||||
if (!inEmptyBlock()) return 0;
|
||||
|
||||
_sink.indent();
|
||||
return _sink.println();
|
||||
}
|
||||
|
||||
size_t unindentIfNeeded() {
|
||||
if (inEmptyBlock()) return 0;
|
||||
|
||||
_sink.unindent();
|
||||
return _sink.println();
|
||||
}
|
||||
|
||||
uint8_t _previousChar;
|
||||
IndentedPrint& _sink;
|
||||
bool _inString;
|
||||
};
|
||||
}
|
||||
}
|
@ -7,107 +7,30 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonBufferBase.hpp"
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
#include "JsonBuffer.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
class StaticJsonBufferBase : public JsonBufferBase<StaticJsonBufferBase> {
|
||||
public:
|
||||
class String {
|
||||
public:
|
||||
String(StaticJsonBufferBase* parent) : _parent(parent) {
|
||||
_start = parent->_buffer + parent->_size;
|
||||
}
|
||||
|
||||
void append(char c) {
|
||||
if (_parent->canAlloc(1)) {
|
||||
char* last = static_cast<char*>(_parent->doAlloc(1));
|
||||
*last = c;
|
||||
}
|
||||
}
|
||||
|
||||
const char* c_str() const {
|
||||
if (_parent->canAlloc(1)) {
|
||||
char* last = static_cast<char*>(_parent->doAlloc(1));
|
||||
*last = '\0';
|
||||
return _start;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
StaticJsonBufferBase* _parent;
|
||||
char* _start;
|
||||
};
|
||||
|
||||
StaticJsonBufferBase(char* buffer, size_t capa)
|
||||
: _buffer(buffer), _capacity(capa), _size(0) {}
|
||||
|
||||
size_t capacity() const {
|
||||
return _capacity;
|
||||
}
|
||||
size_t size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
virtual void* alloc(size_t bytes) {
|
||||
alignNextAlloc();
|
||||
if (!canAlloc(bytes)) return NULL;
|
||||
return doAlloc(bytes);
|
||||
}
|
||||
|
||||
String startString() {
|
||||
return String(this);
|
||||
}
|
||||
|
||||
private:
|
||||
void alignNextAlloc() {
|
||||
_size = round_size_up(_size);
|
||||
}
|
||||
|
||||
bool canAlloc(size_t bytes) const {
|
||||
return _size + bytes <= _capacity;
|
||||
}
|
||||
|
||||
void* doAlloc(size_t bytes) {
|
||||
void* p = &_buffer[_size];
|
||||
_size += bytes;
|
||||
return p;
|
||||
}
|
||||
|
||||
char* _buffer;
|
||||
size_t _capacity;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
// Implements a JsonBuffer with fixed memory allocation.
|
||||
// The template paramenter CAPACITY specifies the capacity of the buffer in
|
||||
// bytes.
|
||||
template <size_t CAPACITY>
|
||||
class StaticJsonBuffer : public StaticJsonBufferBase {
|
||||
class StaticJsonBuffer : public JsonBuffer {
|
||||
public:
|
||||
explicit StaticJsonBuffer() : StaticJsonBufferBase(_buffer, CAPACITY) {}
|
||||
explicit StaticJsonBuffer() : _size(0) {}
|
||||
|
||||
size_t capacity() const { return CAPACITY; }
|
||||
size_t size() const { return _size; }
|
||||
|
||||
virtual void* alloc(size_t bytes) {
|
||||
if (_size + bytes > CAPACITY) return NULL;
|
||||
void* p = &_buffer[_size];
|
||||
_size += round_size_up(bytes);
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
char _buffer[CAPACITY];
|
||||
uint8_t _buffer[CAPACITY];
|
||||
size_t _size;
|
||||
};
|
||||
}
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,39 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../TypeTraits/EnableIf.hpp"
|
||||
#include "../TypeTraits/IsBaseOf.hpp"
|
||||
#include "../TypeTraits/RemoveReference.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
struct StdStreamFuncs {
|
||||
class Iterator {
|
||||
Stream& _stream;
|
||||
|
||||
public:
|
||||
Iterator(Stream& stream) : _stream(stream) {}
|
||||
|
||||
char next() {
|
||||
int n = _stream.read();
|
||||
return n >= 0 ? static_cast<char>(n) : '\0';
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <typename TStream>
|
||||
struct StringFuncs<TStream,
|
||||
// match any type that is derived from std::istream:
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<
|
||||
Stream, typename TypeTraits::RemoveReference<
|
||||
TStream>::type>::value>::type>
|
||||
: StdStreamFuncs {};
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
struct CharPtrFuncs {
|
||||
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 StringFuncs<const char*, void> : CharPtrFuncs {};
|
||||
|
||||
template <>
|
||||
struct StringFuncs<char*, void> : CharPtrFuncs {};
|
||||
|
||||
template <size_t N>
|
||||
struct StringFuncs<char[N], void> : CharPtrFuncs {};
|
||||
|
||||
template <size_t N>
|
||||
struct StringFuncs<const char[N], void> : CharPtrFuncs {};
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
template <>
|
||||
struct StringFuncs<const __FlashStringHelper*, void> {
|
||||
class Iterator {
|
||||
const char* _ptr;
|
||||
|
||||
public:
|
||||
Iterator(const __FlashStringHelper* ptr)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
||||
|
||||
char next() {
|
||||
return pgm_read_byte_near(_ptr++);
|
||||
}
|
||||
};
|
||||
|
||||
static bool equals(const __FlashStringHelper* str, const char* expected) {
|
||||
return strcmp_P(expected, (PGM_P)str) == 0;
|
||||
}
|
||||
|
||||
template <typename Buffer>
|
||||
static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) {
|
||||
if (!str) return NULL;
|
||||
size_t size = strlen_P((PGM_P)str) + 1;
|
||||
void* dup = buffer->alloc(size);
|
||||
if (dup != NULL) memcpy_P(dup, (PGM_P)str, size);
|
||||
return static_cast<char*>(dup);
|
||||
}
|
||||
|
||||
static const bool has_append = false;
|
||||
static const bool has_equals = true;
|
||||
static const bool should_duplicate = true;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <istream>
|
||||
#include "../TypeTraits/EnableIf.hpp"
|
||||
#include "../TypeTraits/IsBaseOf.hpp"
|
||||
#include "../TypeTraits/RemoveReference.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
struct StdStreamFuncs {
|
||||
class Iterator {
|
||||
std::istream& _stream;
|
||||
|
||||
public:
|
||||
Iterator(std::istream& stream) : _stream(stream) {}
|
||||
|
||||
char next() {
|
||||
return _stream.eof() ? '\0' : static_cast<char>(_stream.get());
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator& operator=(const Iterator&); // Visual Studio C4512
|
||||
};
|
||||
};
|
||||
|
||||
template <typename TStream>
|
||||
struct StringFuncs<TStream,
|
||||
// match any type that is derived from std::istream:
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsBaseOf<
|
||||
std::istream, typename TypeTraits::RemoveReference<
|
||||
TStream>::type>::value>::type>
|
||||
: StdStreamFuncs {};
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#include <WString.h>
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STRING
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename TString>
|
||||
struct StdStringFuncs {
|
||||
template <typename Buffer>
|
||||
static char* duplicate(const TString& str, Buffer* buffer) {
|
||||
if (!str.c_str()) return NULL; // <- Arduino string can return NULL
|
||||
size_t size = str.length() + 1;
|
||||
void* dup = buffer->alloc(size);
|
||||
if (dup != NULL) memcpy(dup, str.c_str(), size);
|
||||
return static_cast<char*>(dup);
|
||||
}
|
||||
|
||||
struct Iterator : CharPtrFuncs::Iterator {
|
||||
Iterator(const TString& str) : CharPtrFuncs::Iterator(str.c_str()) {}
|
||||
};
|
||||
|
||||
static bool equals(const TString& str, const char* expected) {
|
||||
return str == expected;
|
||||
}
|
||||
|
||||
static void append(TString& str, char c) {
|
||||
str += c;
|
||||
}
|
||||
|
||||
static const bool has_append = true;
|
||||
static const bool has_equals = true;
|
||||
static const bool should_duplicate = true;
|
||||
};
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
template <>
|
||||
struct StringFuncs<String, void> : StdStringFuncs<String> {};
|
||||
template <>
|
||||
struct StringFuncs<StringSumHelper, void> : StdStringFuncs<StringSumHelper> {};
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STRING
|
||||
template <>
|
||||
struct StringFuncs<std::string, void> : StdStringFuncs<std::string> {};
|
||||
#endif
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename TString, typename Enable = void>
|
||||
struct StringFuncs {};
|
||||
|
||||
template <typename TString>
|
||||
struct StringFuncs<const TString, void> : StringFuncs<TString> {};
|
||||
|
||||
template <typename TString>
|
||||
struct StringFuncs<TString&, void> : StringFuncs<TString> {};
|
||||
}
|
||||
}
|
||||
|
||||
#include "CharPointer.hpp"
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STRING || ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
#include "StdString.hpp"
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include "StdStream.hpp"
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
#include "ArduinoStream.hpp"
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||
#include "FlashString.hpp"
|
||||
#endif
|
@ -1,31 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace TypeTraits {
|
||||
|
||||
// A meta-function that return the type T without the const modifier
|
||||
template <typename T>
|
||||
struct ConstRefOrConstPtr {
|
||||
typedef const T& type;
|
||||
};
|
||||
template <typename T>
|
||||
struct ConstRefOrConstPtr<T*> {
|
||||
typedef const T* type;
|
||||
};
|
||||
template <typename T>
|
||||
struct ConstRefOrConstPtr<T[]> {
|
||||
typedef const T* type;
|
||||
};
|
||||
template <typename T, size_t N>
|
||||
struct ConstRefOrConstPtr<T[N]> {
|
||||
typedef const T* type;
|
||||
};
|
||||
}
|
||||
}
|
@ -11,7 +11,7 @@ namespace ArduinoJson {
|
||||
namespace TypeTraits {
|
||||
|
||||
// A meta-function that return the type T if Condition is true.
|
||||
template <bool Condition, typename T = void>
|
||||
template <bool Condition, typename T>
|
||||
struct EnableIf {};
|
||||
|
||||
template <typename T>
|
||||
|
@ -1,30 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace TypeTraits {
|
||||
|
||||
// A meta-function that returns true if Derived inherits from TBase is an
|
||||
// integral type.
|
||||
template <typename TBase, typename TDerived>
|
||||
class IsBaseOf {
|
||||
protected: // <- to avoid GCC's "all member functions in class are private"
|
||||
typedef char Yes[1];
|
||||
typedef char No[2];
|
||||
|
||||
static Yes &probe(const TBase *);
|
||||
static No &probe(const void *);
|
||||
|
||||
public:
|
||||
enum {
|
||||
value = sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes)
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
@ -7,9 +7,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "IsSame.hpp"
|
||||
#include "IsSignedIntegral.hpp"
|
||||
#include "IsUnsignedIntegral.hpp"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace TypeTraits {
|
||||
@ -17,13 +18,24 @@ namespace TypeTraits {
|
||||
// A meta-function that returns true if T is an integral type.
|
||||
template <typename T>
|
||||
struct IsIntegral {
|
||||
static const bool value = TypeTraits::IsSignedIntegral<T>::value ||
|
||||
TypeTraits::IsUnsignedIntegral<T>::value ||
|
||||
TypeTraits::IsSame<T, char>::value ||
|
||||
TypeTraits::IsSame<T, bool>::value;
|
||||
};
|
||||
static const bool value = TypeTraits::IsSame<T, signed char>::value ||
|
||||
TypeTraits::IsSame<T, unsigned char>::value ||
|
||||
TypeTraits::IsSame<T, signed short>::value ||
|
||||
TypeTraits::IsSame<T, unsigned short>::value ||
|
||||
TypeTraits::IsSame<T, signed int>::value ||
|
||||
TypeTraits::IsSame<T, unsigned int>::value ||
|
||||
TypeTraits::IsSame<T, signed long>::value ||
|
||||
TypeTraits::IsSame<T, unsigned long>::value ||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
TypeTraits::IsSame<T, long long>::value ||
|
||||
TypeTraits::IsSame<T, unsigned long long>::value ||
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
struct IsIntegral<const T> : IsIntegral<T> {};
|
||||
#if ARDUINOJSON_USE_INT64
|
||||
TypeTraits::IsSame<T, __int64>::value ||
|
||||
TypeTraits::IsSame<T, unsigned __int64>::value ||
|
||||
#endif
|
||||
TypeTraits::IsSame<T, char>::value;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "IsSame.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace TypeTraits {
|
||||
|
||||
// A meta-function that returns true if T is an integral type.
|
||||
template <typename T>
|
||||
struct IsSignedIntegral {
|
||||
static const bool value = TypeTraits::IsSame<T, signed char>::value ||
|
||||
TypeTraits::IsSame<T, signed short>::value ||
|
||||
TypeTraits::IsSame<T, signed int>::value ||
|
||||
TypeTraits::IsSame<T, signed long>::value ||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
TypeTraits::IsSame<T, signed long long>::value ||
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_USE_INT64
|
||||
TypeTraits::IsSame<T, signed __int64>::value ||
|
||||
#endif
|
||||
false;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "IsSame.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace TypeTraits {
|
||||
|
||||
// A meta-function that returns true if T is an integral type.
|
||||
template <typename T>
|
||||
struct IsUnsignedIntegral {
|
||||
static const bool value = TypeTraits::IsSame<T, unsigned char>::value ||
|
||||
TypeTraits::IsSame<T, unsigned short>::value ||
|
||||
TypeTraits::IsSame<T, unsigned int>::value ||
|
||||
TypeTraits::IsSame<T, unsigned long>::value ||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
TypeTraits::IsSame<T, unsigned long long>::value ||
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_USE_INT64
|
||||
TypeTraits::IsSame<T, unsigned __int64>::value ||
|
||||
#endif
|
||||
false;
|
||||
};
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ JsonArray KEYWORD1
|
||||
JsonObject KEYWORD1
|
||||
JsonVariant KEYWORD1
|
||||
StaticJsonBuffer KEYWORD1
|
||||
DynamicJsonBuffer KEYWORD1
|
||||
add KEYWORD2
|
||||
createArray KEYWORD2
|
||||
createNestedArray KEYWORD2
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "ArduinoJson",
|
||||
"name": "Json",
|
||||
"keywords": "json, rest, http, web",
|
||||
"description": "An elegant and efficient JSON library for embedded systems",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "5.8.0",
|
||||
"version": "5.1.0-beta.2",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "http://blog.benoitblanchon.fr"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=5.8.0
|
||||
version=5.1.0-beta.2
|
||||
author=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
sentence=An efficient and elegant JSON library for Arduino.
|
||||
|
@ -17,4 +17,5 @@ rm -f $OUTPUT
|
||||
ArduinoJson/library.properties \
|
||||
ArduinoJson/LICENSE.md \
|
||||
ArduinoJson/README.md \
|
||||
ArduinoJson/ArduinoJson.h
|
||||
ArduinoJson/src \
|
||||
-x!ArduinoJson/src/CMakeLists.txt
|
||||
|
52
scripts/build-old-arduino-package.sh
Executable file
52
scripts/build-old-arduino-package.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/bash
|
||||
|
||||
TAG=$(git describe)
|
||||
OUTPUT="ArduinoJson-$TAG-old-layout.zip"
|
||||
|
||||
cd $(dirname $0)/..
|
||||
|
||||
cat > ArduinoJson.h <<END
|
||||
// WARNING:
|
||||
// --------
|
||||
// This file is a workaround for old version of the Arduino IDE.
|
||||
// If you are using Arduino IDE 1.0.6 or above, then you installed the wrong
|
||||
// package of ArduinoJson.
|
||||
// In that case, just delete the current installation and install the package.
|
||||
|
||||
END
|
||||
cp ArduinoJson.h ArduinoJson.cpp
|
||||
|
||||
cat "include/ArduinoJson.h" | sed 's!include "!include "include/!g' >> ArduinoJson.h
|
||||
|
||||
find src -name "*.cpp" |
|
||||
while read FILE; do
|
||||
echo >> ArduinoJson.cpp
|
||||
echo "// $FILE" >> ArduinoJson.cpp
|
||||
echo "//" >> ArduinoJson.cpp
|
||||
cat "$FILE" | sed 's!\.\./!!g' >> ArduinoJson.cpp
|
||||
done
|
||||
|
||||
unix2dos ArduinoJson.cpp
|
||||
unix2dos ArduinoJson.h
|
||||
|
||||
pushd ..
|
||||
|
||||
# remove existing file
|
||||
rm -f $OUTPUT
|
||||
|
||||
# create zipman dos2
|
||||
7z a $OUTPUT \
|
||||
ArduinoJson/CHANGELOG.md \
|
||||
ArduinoJson/examples \
|
||||
ArduinoJson/include/ArduinoJson \
|
||||
ArduinoJson/keywords.txt \
|
||||
ArduinoJson/LICENSE.md \
|
||||
ArduinoJson/README.md \
|
||||
ArduinoJson/ArduinoJson.h \
|
||||
ArduinoJson/ArduinoJson.cpp \
|
||||
-x!ArduinoJson/src/CMakeLists.txt
|
||||
|
||||
popd
|
||||
|
||||
rm ArduinoJson.h
|
||||
rm ArduinoJson.cpp
|
@ -21,9 +21,9 @@ if [[ $(uname) == MINGW* ]]
|
||||
then
|
||||
build-env "Make" "MinGW Makefiles"
|
||||
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
||||
build-env "VisualStudio" "Visual Studio 14 2015"
|
||||
build-env "VisualStudio" "Visual Studio 12 2013"
|
||||
else
|
||||
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
||||
build-env "Make" "Unix Makefiles"
|
||||
build-env "Xcode" "Xcode"
|
||||
fi
|
||||
fi
|
@ -11,6 +11,5 @@ export PATH=$PATH:/tmp/arduino/
|
||||
|
||||
ln -s $PWD /tmp/arduino/libraries/ArduinoJson
|
||||
|
||||
for EXAMPLE in $PWD/examples/*/*.ino; do
|
||||
arduino --verify --board $BOARD $EXAMPLE
|
||||
done
|
||||
arduino --verify --board $BOARD $PWD/examples/JsonParserExample/JsonParserExample.ino
|
||||
arduino --verify --board $BOARD $PWD/examples/JsonGeneratorExample/JsonGeneratorExample.ino
|
||||
|
10
scripts/travis/clang.sh
Executable file
10
scripts/travis/clang.sh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
export CC=clang
|
||||
export CXX=clang++
|
||||
|
||||
curl -sS https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1
|
||||
|
||||
/tmp/bin/cmake .
|
||||
make
|
||||
make test
|
@ -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
|
@ -1,9 +0,0 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Linux-x86_64.tar.gz
|
||||
|
||||
curl -sS $URL | tar xz -C /tmp --strip 1
|
||||
|
||||
/tmp/bin/cmake -DCMAKE_CXX_COMPILER=$CMAKE_CXX_COMPILER .
|
||||
make
|
||||
make test
|
@ -1,10 +1,13 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
export CC=gcc
|
||||
export CXX=g++
|
||||
|
||||
curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1
|
||||
|
||||
/tmp/bin/cmake -DCOVERAGE=true .
|
||||
make
|
||||
make test
|
||||
|
||||
pip install --user cpp-coveralls 'requests[security]'
|
||||
pip install --user cpp-coveralls
|
||||
coveralls --exclude third-party --gcov-options '\-lp'; fi
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user