Compare commits

..

4 Commits

156 changed files with 2482 additions and 5055 deletions

View File

@ -1,5 +1,4 @@
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Google
Standard: Cpp03
AllowShortFunctionsOnASingleLine: Empty
Standard: Cpp03

View File

@ -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!
-->

View File

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

View File

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

View File

@ -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"

View File

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

View File

@ -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)

View File

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

View File

@ -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 .

View File

@ -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);
}

View File

@ -1,56 +0,0 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
// About
// -----
// This example shows the different ways you can use PROGMEM with ArduinoJson.
// Please don't see this as an invitation to use PROGMEM.
// On the contrary, you should always use char[] when possible, it's much more
// efficient in term of code size, speed and memory usage.
void setup() {
#ifdef PROGMEM
DynamicJsonBuffer jsonBuffer;
// You can use a Flash String as your JSON input.
// WARNING: the content of the Flash String will be duplicated in the
// JsonBuffer.
JsonObject& root =
jsonBuffer.parseObject(F("{\"sensor\":\"gps\",\"time\":1351824120,"
"\"data\":[48.756080,2.302038]}"));
// You can use a Flash String to get an element of a JsonObject
// No duplication is done.
long time = root[F("time")];
// You can use a Flash String to set an element of a JsonObject
// WARNING: the content of the Flash String will be duplicated in the
// JsonBuffer.
root[F("time")] = time;
// You can set a Flash String to a JsonObject or JsonArray:
// WARNING: the content of the Flash String will be duplicated in the
// JsonBuffer.
root["sensor"] = F("gps");
// You can compare the content of a JsonVariant to a Flash String
if (root["sensor"] == F("gps")) {
// ...
}
#else
#warning PROGMEM is not supported on this platform
#endif
}
void loop() {
// not used in this example
}

View File

@ -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
}

View File

@ -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;

View File

@ -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;

View 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

View 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

View File

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

View File

@ -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;
};
}
}

View File

@ -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> {};
}
}

View File

@ -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;
}
};
}
}

View File

@ -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;
}
}
}
}
}

View File

@ -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);
}
}
}

View File

@ -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;
}

View File

@ -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;
}
};
}
}

View File

@ -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;
};
}
}

View File

@ -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;
}

View 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;
};
}
}

View 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);
}
}

View File

@ -7,7 +7,7 @@
#pragma once
#include "../Print.hpp"
#include "../Arduino/Print.hpp"
namespace ArduinoJson {
namespace Internals {

View File

@ -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;
};
}
}

View File

@ -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[];
};
}
}

View File

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

View File

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

View File

@ -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
}
}

View 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;
};
}
}

View File

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

View File

@ -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
};
}
}

View File

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

View 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
};
}
}

View File

@ -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;

View File

@ -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
}
}

View 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;
};
}
}

View File

@ -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;

View File

@ -11,7 +11,7 @@
#if ARDUINOJSON_ENABLE_STD_STREAM
#include "../Print.hpp"
#include "../Arduino/Print.hpp"
#include <ostream>

View File

@ -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;
};
}
}

View File

@ -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"

View 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;
}
}

View File

@ -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;
}
}

View File

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

View File

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

View File

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

View File

@ -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();
}

View File

@ -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"

View 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;
}
}

View File

@ -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;
}
}

View 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;
};
}

View File

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

View File

@ -7,6 +7,7 @@
#pragma once
#include "JsonObjectKey.hpp"
#include "JsonVariant.hpp"
namespace ArduinoJson {

View File

@ -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"

View 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

View File

@ -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>();
}
}

View File

@ -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>();
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,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);
}
}

View File

@ -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);
}
};
}
}

View File

@ -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;
};
}
}

View File

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

View File

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

View File

@ -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 {};
}
}

View File

@ -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;
};
}
}

View File

@ -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 {};
}
}

View File

@ -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
}
}

View File

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

View File

@ -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;
};
}
}

View File

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

View File

@ -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)
};
};
}
}

View File

@ -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;
};
}
}

View File

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

View File

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

View File

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

View File

@ -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"

View File

@ -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.

View File

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

View 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

View File

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

View File

@ -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
View 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

View File

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

View File

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

View File

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