forked from bblanchon/ArduinoJson
Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
0df2a365f5 | |||
c7d6d33e6c | |||
c705f3cfeb | |||
7fecb36aee | |||
657a2ea8d9 | |||
dd064f4c96 | |||
3bc05b97ea | |||
bbd515f6f6 | |||
9b3e3a3d9c | |||
a3a2ca4796 | |||
eab13dc565 | |||
bebd1c400c | |||
36d1bb2f52 | |||
ae32695c3e | |||
c5d19a4dbd | |||
78728c6547 | |||
a8032f81d9 | |||
a138791964 | |||
f9f002c8f7 | |||
f192d5c12e | |||
a6724bd03f | |||
c77c3f33ef | |||
623aeee9bf | |||
a241d53d28 | |||
11500d2ff5 | |||
85708bc94f | |||
ba6e8856f2 | |||
c8448b0abf | |||
e35248ffc4 | |||
b47a3b566a | |||
6ab23bd523 | |||
987afff0e9 | |||
564c62f3b3 | |||
8733f95e51 | |||
ce63e9c3c3 |
@ -1,3 +1,4 @@
|
||||
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||
|
||||
BasedOnStyle: Google
|
||||
BasedOnStyle: Google
|
||||
Standard: Cpp03
|
123
.travis.yml
123
.travis.yml
@ -1,15 +1,118 @@
|
||||
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: gcc
|
||||
env: SCRIPT=coverage
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.1
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.2
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: beta-xcode6.3
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode6.4
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7.1
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7.2
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- os: osx
|
||||
osx_image: xcode7.3
|
||||
compiler: clang
|
||||
env: SCRIPT=cmake-osx
|
||||
- env: SCRIPT=arduino VERSION=1.5.8 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.8 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=arduino VERSION=1.6.9 BOARD=arduino:avr:uno
|
||||
- env: SCRIPT=platformio BOARD=uno
|
||||
- env: SCRIPT=platformio BOARD=due
|
||||
- env: SCRIPT=platformio BOARD=esp01
|
||||
- env: SCRIPT=platformio BOARD=teensy31
|
||||
cache:
|
||||
directories:
|
||||
- "~/.platformio"
|
||||
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
|
||||
script: scripts/travis/$SCRIPT.sh
|
||||
|
46
CHANGELOG.md
46
CHANGELOG.md
@ -1,6 +1,52 @@
|
||||
ArduinoJson: change log
|
||||
=======================
|
||||
|
||||
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
|
||||
------
|
||||
|
||||
* Added support of `long long` (issue #171)
|
||||
* Moved all build settings to `ArduinoJson/Configuration.hpp`
|
||||
|
||||
**BREAKING CHANGE**:
|
||||
If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
|
||||
|
||||
v5.0.8
|
||||
------
|
||||
|
||||
|
34
README.md
34
README.md
@ -15,7 +15,8 @@ Features
|
||||
* JSON decoding (comments are supported)
|
||||
* JSON encoding (with optional indentation)
|
||||
* Elegant API, very easy to use
|
||||
* Efficient (no malloc, nor copy)
|
||||
* Fixed memory allocation (zero malloc)
|
||||
* No data duplication (zero copy)
|
||||
* Portable (written in C++98)
|
||||
* Self-contained (no external dependency)
|
||||
* Small footprint
|
||||
@ -24,12 +25,13 @@ Features
|
||||
Works on
|
||||
--------
|
||||
|
||||
* All Arduino boards
|
||||
* All Arduino boards (Uno, Due, Mini, Micro, Yun...)
|
||||
* ESP8266
|
||||
* Teensy
|
||||
* Intel Edison
|
||||
* Intel Edison and Galileo
|
||||
* PlatformIO
|
||||
* Energia
|
||||
* RedBearLab boards (BLE Nano...)
|
||||
* Computers (Windows, Linux, OSX...)
|
||||
|
||||
See [FAQ: Compatibility issues](https://github.com/bblanchon/ArduinoJson/wiki/Compatibility-issues)
|
||||
@ -90,31 +92,37 @@ From StackOverflow user `thegreendroid`:
|
||||
> It has a really elegant, simple API and it works like a charm on embedded and Windows/Linux platforms. We recently started using this on an embedded project and I can vouch for its quality.
|
||||
|
||||
From GitHub user `zacsketches`:
|
||||
|
||||
> Thanks for a great library!!!
|
||||
> I've been watching you consistently develop this library over the past six months, and I used it today for a publish and subscribe architecture designed to help hobbyists move into more advanced robotics. Your library allowed me to implement remote subscription in order to facilitate multi-processor robots.
|
||||
> ArduinoJson saved me a week's worth of time!!
|
||||
|
||||
[From Reddit user `erm_what_`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusjk8c):
|
||||
|
||||
> This is a great library and I wouldn't be able to do the project I'm doing without it. I completely recommend it.
|
||||
|
||||
[From Reddit user `makerhacks`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusqg7b):
|
||||
|
||||
> I am just starting an ESP8266 clock project and now I can output JSON from my server script and interpret it painlessly.
|
||||
|
||||
[From Twitter user `@hemalchevli`](https://twitter.com/hemalchevli/status/715788439397011456):
|
||||
> ArduinoJson library should be used as a benchmark/reference for making libraries. Truly elegant.
|
||||
|
||||
Donators
|
||||
--------
|
||||
|
||||
Special thanks to the following persons and companies who made generous donations to the library author:
|
||||
|
||||
* Robert Murphy
|
||||
* Surge Communications
|
||||
* Alex Scott
|
||||
* Firepick Services LLC
|
||||
* A B Doodkorte
|
||||
* Scott Smith
|
||||
* Johann Stieger
|
||||
* 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'>
|
||||
|
||||
---
|
||||
|
||||
|
16
appveyor.yml
Normal file
16
appveyor.yml
Normal file
@ -0,0 +1,16 @@
|
||||
version: 5.5.1.{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
|
||||
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
|
||||
- cmake -DCMAKE_BUILD_TYPE=%CONFIGURATION% -G "%CMAKE_GENERATOR%" .
|
||||
build_script:
|
||||
- cmake --build . --config %CONFIGURATION%
|
||||
test_script:
|
||||
- ctest -V .
|
@ -13,12 +13,36 @@ void setup() {
|
||||
// wait serial port initialization
|
||||
}
|
||||
|
||||
// Memory pool for JSON object tree.
|
||||
//
|
||||
// Inside the brackets, 200 is the size of the pool in bytes.
|
||||
// If the JSON object is more complex, you need to increase that value.
|
||||
StaticJsonBuffer<200> jsonBuffer;
|
||||
|
||||
// StaticJsonBuffer allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonBuffer which allocates in the heap.
|
||||
// It's simpler but less efficient.
|
||||
//
|
||||
// DynamicJsonBuffer jsonBuffer;
|
||||
|
||||
// Create the root of the object tree.
|
||||
//
|
||||
// It's a reference to the JsonObject, the actual bytes are inside the
|
||||
// JsonBuffer with all the other nodes of the object tree.
|
||||
// Memory is freed when jsonBuffer goes out of scope.
|
||||
JsonObject& root = jsonBuffer.createObject();
|
||||
|
||||
// Add values in the object
|
||||
//
|
||||
// Most of the time, you can rely on the implicit casts.
|
||||
// In other case, you can do root.set<long>("time", 1351824120);
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
|
||||
// Add a nested array.
|
||||
//
|
||||
// It's also possible to create the array separately and add it to the
|
||||
// JsonObject but it's less efficient.
|
||||
JsonArray& data = root.createNestedArray("data");
|
||||
data.add(double_with_n_digits(48.756080, 6));
|
||||
data.add(double_with_n_digits(2.302038, 6));
|
||||
|
195
examples/JsonHttpClient/JsonHttpClient.ino
Normal file
195
examples/JsonHttpClient/JsonHttpClient.ino
Normal file
@ -0,0 +1,195 @@
|
||||
// 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 <SPI.h>
|
||||
#include <Ethernet.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()) {
|
||||
char response[MAX_CONTENT_SIZE];
|
||||
readReponseContent(response, sizeof(response));
|
||||
|
||||
UserData userData;
|
||||
if (parseUserData(response, &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.1");
|
||||
client.print("Host: ");
|
||||
client.println(server);
|
||||
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;
|
||||
}
|
||||
|
||||
// Read the body of the response from the HTTP server
|
||||
void readReponseContent(char* content, size_t maxSize) {
|
||||
size_t length = client.readBytes(content, maxSize);
|
||||
content[length] = 0;
|
||||
Serial.println(content);
|
||||
}
|
||||
|
||||
// Parse the JSON from the input string and extract the interesting values
|
||||
// Here is the JSON we need to parse
|
||||
// {
|
||||
// "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 parseUserData(char* content, 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
|
||||
|
||||
// Allocate a temporary memory pool on the stack
|
||||
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
|
||||
// If the memory pool is too big for the stack, use this instead:
|
||||
// DynamicJsonBuffer jsonBuffer;
|
||||
|
||||
JsonObject& root = jsonBuffer.parseObject(content);
|
||||
|
||||
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);
|
||||
}
|
@ -13,23 +13,49 @@ void setup() {
|
||||
// wait serial port initialization
|
||||
}
|
||||
|
||||
// Memory pool for JSON object tree.
|
||||
//
|
||||
// Inside the brackets, 200 is the size of the pool in bytes,
|
||||
// If the JSON object is more complex, you need to increase that value.
|
||||
StaticJsonBuffer<200> jsonBuffer;
|
||||
|
||||
// StaticJsonBuffer allocates memory on the stack, it can be
|
||||
// replaced by DynamicJsonBuffer which allocates in the heap.
|
||||
// It's simpler but less efficient.
|
||||
//
|
||||
// DynamicJsonBuffer jsonBuffer;
|
||||
|
||||
// JSON input string.
|
||||
//
|
||||
// It's better to use a char[] as shown here.
|
||||
// If you use a const char* or a String, ArduinoJson will
|
||||
// have to make a copy of the input in the JsonBuffer.
|
||||
char json[] =
|
||||
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
|
||||
// Root of the object tree.
|
||||
//
|
||||
// It's a reference to the JsonObject, the actual bytes are inside the
|
||||
// JsonBuffer with all the other nodes of the object tree.
|
||||
// Memory is freed when jsonBuffer goes out of scope.
|
||||
JsonObject& root = jsonBuffer.parseObject(json);
|
||||
|
||||
// Test if parsing succeeds.
|
||||
if (!root.success()) {
|
||||
Serial.println("parseObject() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch values.
|
||||
//
|
||||
// Most of the time, you can rely on the implicit casts.
|
||||
// In other case, you can do root["time"].as<long>();
|
||||
const char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
// Print values.
|
||||
Serial.println(sensor);
|
||||
Serial.println(time);
|
||||
Serial.println(latitude, 6);
|
||||
|
89
include/ArduinoJson/Configuration.hpp
Normal file
89
include/ArduinoJson/Configuration.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ARDUINO // assume this is an embedded platform
|
||||
|
||||
// store using float instead of double to reduce the memory usage (issue #134)
|
||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||
#define ARDUINOJSON_USE_DOUBLE 0
|
||||
#endif
|
||||
|
||||
// store using a long because it usually match the size of a float.
|
||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#endif
|
||||
#ifndef ARDUINOJSON_USE_INT64
|
||||
#define ARDUINOJSON_USE_INT64 0
|
||||
#endif
|
||||
|
||||
// arduino has its own implementation of String to replace std::string
|
||||
#ifndef ARDUINOJSON_USE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_USE_ARDUINO_STRING 1
|
||||
#endif
|
||||
|
||||
// arduino doesn't support STL stream
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 0
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
|
||||
#ifdef ARDUINO_ARCH_AVR
|
||||
// alignment isn't needed for 8-bit AVR
|
||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
|
||||
#else
|
||||
// but must processor needs pointer to be align on word size
|
||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#else // assume this is a computer
|
||||
|
||||
// on a computer we have plenty of memory so we can use doubles
|
||||
#ifndef ARDUINOJSON_USE_DOUBLE
|
||||
#define ARDUINOJSON_USE_DOUBLE 1
|
||||
#endif
|
||||
|
||||
// use long long when available
|
||||
#ifndef ARDUINOJSON_USE_LONG_LONG
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
|
||||
#define ARDUINOJSON_USE_LONG_LONG 1
|
||||
#else
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// use _int64 on old versions of Visual Studio
|
||||
#ifndef ARDUINOJSON_USE_INT64
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#define ARDUINOJSON_USE_INT64 1
|
||||
#else
|
||||
#define ARDUINOJSON_USE_INT64 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// on a computer, we can use std::string
|
||||
#ifndef ARDUINOJSON_USE_ARDUINO_STRING
|
||||
#define ARDUINOJSON_USE_ARDUINO_STRING 0
|
||||
#endif
|
||||
|
||||
// on a computer, we can assume that the STL is there
|
||||
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM 1
|
||||
#endif
|
||||
|
||||
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
|
||||
// even if not required, most cpu's are faster with aligned pointers
|
||||
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
|
||||
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
|
||||
#endif
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
@ -7,8 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "../Arduino/String.hpp"
|
||||
#include "../Print.hpp"
|
||||
#include "../String.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
@ -7,15 +7,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
#ifdef ARDUINO
|
||||
// On embedded platform, we with use float instead of double to keep JsonVariant
|
||||
// small (issue #134)
|
||||
typedef float JsonFloat;
|
||||
#else
|
||||
#if ARDUINOJSON_USE_DOUBLE
|
||||
typedef double JsonFloat;
|
||||
#else
|
||||
typedef float JsonFloat;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,12 @@ class JsonParser {
|
||||
JsonArray &parseArray();
|
||||
JsonObject &parseObject();
|
||||
|
||||
JsonVariant parseVariant() {
|
||||
JsonVariant result;
|
||||
parseAnythingTo(&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
bool skip(char charToSkip);
|
||||
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Configuration.hpp"
|
||||
#include "DummyPrint.hpp"
|
||||
#include "IndentedPrint.hpp"
|
||||
#include "JsonWriter.hpp"
|
||||
@ -14,7 +15,7 @@
|
||||
#include "StaticStringBuilder.hpp"
|
||||
#include "DynamicStringBuilder.hpp"
|
||||
|
||||
#ifdef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include "StreamPrintAdapter.hpp"
|
||||
#endif
|
||||
|
||||
@ -34,7 +35,7 @@ class JsonPrintable {
|
||||
return writer.bytesWritten();
|
||||
}
|
||||
|
||||
#ifdef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
std::ostream &printTo(std::ostream &os) const {
|
||||
StreamPrintAdapter adapter(os);
|
||||
printTo(adapter);
|
||||
@ -86,7 +87,7 @@ class JsonPrintable {
|
||||
const T &downcast() const { return *static_cast<const T *>(this); }
|
||||
};
|
||||
|
||||
#ifdef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
template <typename T>
|
||||
inline std::ostream &operator<<(std::ostream &os, const JsonPrintable<T> &v) {
|
||||
return v.printTo(os);
|
||||
|
@ -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
|
||||
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
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -16,13 +16,15 @@ 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, // 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
|
||||
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
|
||||
|
||||
// The following values are reserved for float values
|
||||
// Multiple values are used for double, depending on the number of decimal
|
||||
|
@ -7,7 +7,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "../Polyfills/isInfinity.hpp"
|
||||
#include "../Polyfills/isNaN.hpp"
|
||||
#include "../Polyfills/normalize.hpp"
|
||||
#include "../Print.hpp"
|
||||
#include "Encoding.hpp"
|
||||
#include "ForceInline.hpp"
|
||||
#include "JsonFloat.hpp"
|
||||
@ -32,49 +35,107 @@ class JsonWriter {
|
||||
// number of bytes written.
|
||||
size_t bytesWritten() const { return _length; }
|
||||
|
||||
void beginArray() { write('['); }
|
||||
void endArray() { write(']'); }
|
||||
void beginArray() { writeRaw('['); }
|
||||
void endArray() { writeRaw(']'); }
|
||||
|
||||
void beginObject() { write('{'); }
|
||||
void endObject() { write('}'); }
|
||||
void beginObject() { writeRaw('{'); }
|
||||
void endObject() { writeRaw('}'); }
|
||||
|
||||
void writeColon() { write(':'); }
|
||||
void writeComma() { write(','); }
|
||||
void writeColon() { writeRaw(':'); }
|
||||
void writeComma() { writeRaw(','); }
|
||||
|
||||
void writeBoolean(bool value) { write(value ? "true" : "false"); }
|
||||
void writeBoolean(bool value) { writeRaw(value ? "true" : "false"); }
|
||||
|
||||
void writeString(const char *value) {
|
||||
if (!value) {
|
||||
write("null");
|
||||
writeRaw("null");
|
||||
} else {
|
||||
write('\"');
|
||||
writeRaw('\"');
|
||||
while (*value) writeChar(*value++);
|
||||
write('\"');
|
||||
writeRaw('\"');
|
||||
}
|
||||
}
|
||||
|
||||
void writeChar(char c) {
|
||||
char specialChar = Encoding::escapeChar(c);
|
||||
if (specialChar) {
|
||||
write('\\');
|
||||
write(specialChar);
|
||||
writeRaw('\\');
|
||||
writeRaw(specialChar);
|
||||
} else {
|
||||
write(c);
|
||||
writeRaw(c);
|
||||
}
|
||||
}
|
||||
|
||||
void writeInteger(JsonInteger value) { _length += _sink.print(value); }
|
||||
void writeFloat(JsonFloat value, int digits = 2) {
|
||||
if (Polyfills::isNaN(value)) return writeRaw("NaN");
|
||||
|
||||
void writeFloat(JsonFloat value, uint8_t decimals) {
|
||||
_length += _sink.print(value, decimals);
|
||||
if (value < 0.0) {
|
||||
writeRaw('-');
|
||||
value = -value;
|
||||
}
|
||||
|
||||
if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
|
||||
|
||||
short powersOf10;
|
||||
if (value > 1000 || value < 0.001) {
|
||||
powersOf10 = Polyfills::normalize(value);
|
||||
} else {
|
||||
powersOf10 = 0;
|
||||
}
|
||||
|
||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||
JsonFloat rounding = 0.5;
|
||||
for (uint8_t i = 0; i < digits; ++i) rounding /= 10.0;
|
||||
|
||||
value += rounding;
|
||||
|
||||
// Extract the integer part of the value and print it
|
||||
JsonUInt int_part = static_cast<JsonUInt>(value);
|
||||
JsonFloat remainder = value - static_cast<JsonFloat>(int_part);
|
||||
writeInteger(int_part);
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if (digits > 0) {
|
||||
writeRaw('.');
|
||||
}
|
||||
|
||||
// Extract digits from the remainder one at a time
|
||||
while (digits-- > 0) {
|
||||
remainder *= 10.0;
|
||||
JsonUInt toPrint = JsonUInt(remainder);
|
||||
writeInteger(JsonUInt(remainder));
|
||||
remainder -= static_cast<JsonFloat>(toPrint);
|
||||
}
|
||||
|
||||
if (powersOf10 < 0) {
|
||||
writeRaw("e-");
|
||||
writeInteger(-powersOf10);
|
||||
}
|
||||
|
||||
if (powersOf10 > 0) {
|
||||
writeRaw('e');
|
||||
writeInteger(powersOf10);
|
||||
}
|
||||
}
|
||||
|
||||
void writeRaw(const char *s) { return write(s); }
|
||||
void writeInteger(JsonUInt value) {
|
||||
char buffer[22];
|
||||
|
||||
uint8_t i = 0;
|
||||
do {
|
||||
buffer[i++] = static_cast<char>(value % 10 + '0');
|
||||
value /= 10;
|
||||
} while (value);
|
||||
|
||||
while (i > 0) {
|
||||
writeRaw(buffer[--i]);
|
||||
}
|
||||
}
|
||||
|
||||
void writeRaw(const char *s) { _length += _sink.print(s); }
|
||||
void writeRaw(char c) { _length += _sink.write(c); }
|
||||
|
||||
protected:
|
||||
void write(char c) { _length += _sink.write(c); }
|
||||
FORCE_INLINE void write(const char *s) { _length += _sink.print(s); }
|
||||
|
||||
Print &_sink;
|
||||
size_t _length;
|
||||
|
||||
|
66
include/ArduinoJson/Internals/Parse.hpp
Normal file
66
include/ArduinoJson/Internals/Parse.hpp
Normal file
@ -0,0 +1,66 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
template <typename TFloat>
|
||||
TFloat parse(const char *);
|
||||
|
||||
template <>
|
||||
inline float parse<float>(const char *s) {
|
||||
return static_cast<float>(strtod(s, NULL));
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double parse<double>(const char *s) {
|
||||
return strtod(s, NULL);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline long parse<long>(const char *s) {
|
||||
return strtol(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned long parse<unsigned long>(const char *s) {
|
||||
return strtoul(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline int parse<int>(const char *s) {
|
||||
return atoi(s);
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG
|
||||
template <>
|
||||
inline long long parse<long long>(const char *s) {
|
||||
return strtoll(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned long long parse<unsigned long long>(const char *s) {
|
||||
return strtoull(s, NULL, 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ARDUINOJSON_USE_INT64
|
||||
template <>
|
||||
inline __int64 parse<__int64>(const char *s) {
|
||||
return _strtoi64(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned __int64 parse<unsigned __int64>(const char *s) {
|
||||
return _strtoui64(s, NULL, 10);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "../Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
@ -7,9 +7,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include "../Configuration.hpp"
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
|
||||
#include "../Print.hpp"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
@ -12,6 +12,10 @@
|
||||
#include "Internals/List.hpp"
|
||||
#include "Internals/ReferenceType.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||
#include "TypeTraits/IsReference.hpp"
|
||||
#include "TypeTraits/IsSame.hpp"
|
||||
|
||||
// Returns the size (in bytes) of an array with n elements.
|
||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||
@ -36,6 +40,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,42 +62,74 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
FORCE_INLINE JsonArraySubscript operator[](size_t index);
|
||||
|
||||
// Adds the specified value at the end of the array.
|
||||
FORCE_INLINE bool add(bool value);
|
||||
FORCE_INLINE bool add(float value, uint8_t decimals = 2);
|
||||
FORCE_INLINE bool add(double value, uint8_t decimals = 2);
|
||||
FORCE_INLINE bool add(signed char value);
|
||||
FORCE_INLINE bool add(signed long value);
|
||||
FORCE_INLINE bool add(signed int value);
|
||||
FORCE_INLINE bool add(signed short value);
|
||||
FORCE_INLINE bool add(unsigned char value);
|
||||
FORCE_INLINE bool add(unsigned long value);
|
||||
FORCE_INLINE bool add(unsigned int value);
|
||||
FORCE_INLINE bool add(unsigned short value);
|
||||
FORCE_INLINE bool add(const char *value);
|
||||
FORCE_INLINE bool add(const String &value);
|
||||
FORCE_INLINE bool add(JsonArray &array);
|
||||
FORCE_INLINE bool add(JsonObject &object);
|
||||
//
|
||||
// bool add(bool);
|
||||
// bool add(char);
|
||||
// bool add(long);
|
||||
// bool add(int);
|
||||
// bool add(short);
|
||||
// bool add(float value);
|
||||
// bool add(double value);
|
||||
// bool add(const char*);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(const T &value);
|
||||
FORCE_INLINE bool add(
|
||||
T value,
|
||||
typename TypeTraits::EnableIf<
|
||||
CanSet<T>::value && !TypeTraits::IsReference<T>::value>::type * = 0) {
|
||||
return addNode<T>(value);
|
||||
}
|
||||
// bool add(const String&)
|
||||
// bool add(const JsonVariant&);
|
||||
// bool add(JsonArray&);
|
||||
// bool add(JsonObject&);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(
|
||||
const T &value,
|
||||
typename TypeTraits::EnableIf<CanSet<T &>::value>::type * = 0) {
|
||||
return addNode<T &>(const_cast<T &>(value));
|
||||
}
|
||||
// bool add(float value, uint8_t decimals);
|
||||
// bool add(double value, uint8_t decimals);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool add(
|
||||
T value, uint8_t decimals,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value>::type
|
||||
* = 0) {
|
||||
return addNode<JsonVariant>(JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
// Sets the value at specified index.
|
||||
FORCE_INLINE void set(size_t index, bool value);
|
||||
FORCE_INLINE void set(size_t index, float value, uint8_t decimals = 2);
|
||||
FORCE_INLINE void set(size_t index, double value, uint8_t decimals = 2);
|
||||
FORCE_INLINE void set(size_t index, signed char value);
|
||||
FORCE_INLINE void set(size_t index, signed long value);
|
||||
FORCE_INLINE void set(size_t index, signed int value);
|
||||
FORCE_INLINE void set(size_t index, signed short value);
|
||||
FORCE_INLINE void set(size_t index, unsigned char value);
|
||||
FORCE_INLINE void set(size_t index, unsigned long value);
|
||||
FORCE_INLINE void set(size_t index, unsigned int value);
|
||||
FORCE_INLINE void set(size_t index, unsigned short value);
|
||||
FORCE_INLINE void set(size_t index, const char *value);
|
||||
FORCE_INLINE void set(size_t index, const String &value);
|
||||
FORCE_INLINE void set(size_t index, JsonArray &array);
|
||||
FORCE_INLINE void set(size_t index, JsonObject &object);
|
||||
//
|
||||
// bool set(size_t index, bool value);
|
||||
// bool set(size_t index, long value);
|
||||
// bool set(size_t index, int value);
|
||||
// bool set(size_t index, short value);
|
||||
template <typename T>
|
||||
FORCE_INLINE void set(size_t index, const T &value);
|
||||
FORCE_INLINE bool set(
|
||||
size_t index, T value,
|
||||
typename TypeTraits::EnableIf<
|
||||
CanSet<T>::value && !TypeTraits::IsReference<T>::value>::type * = 0) {
|
||||
return setNodeAt<T>(index, value);
|
||||
}
|
||||
// bool set(size_t index, const String&)
|
||||
// bool set(size_t index, const JsonVariant&);
|
||||
// bool set(size_t index, JsonArray&);
|
||||
// bool set(size_t index, JsonObject&);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
size_t index, const T &value,
|
||||
typename TypeTraits::EnableIf<CanSet<T &>::value>::type * = 0) {
|
||||
return setNodeAt<T &>(index, const_cast<T &>(value));
|
||||
}
|
||||
// bool set(size_t index, float value, uint8_t decimals = 2);
|
||||
// bool set(size_t index, double value, uint8_t decimals = 2);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(
|
||||
size_t index, T value, uint8_t decimals,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value>::type
|
||||
* = 0) {
|
||||
return setNodeAt<const JsonVariant &>(index, JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
// Gets the value at the specified index.
|
||||
FORCE_INLINE JsonVariant get(size_t index) const;
|
||||
@ -116,17 +161,70 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
|
||||
// Serialize the array to the specified JsonWriter.
|
||||
void writeTo(Internals::JsonWriter &writer) const;
|
||||
|
||||
// Imports a 1D array
|
||||
template <typename T, size_t N>
|
||||
bool copyFrom(T(&array)[N]) {
|
||||
return copyFrom(array, N);
|
||||
}
|
||||
|
||||
// Imports a 1D array
|
||||
template <typename T>
|
||||
bool copyFrom(T *array, size_t len) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
ok &= add(array[i]);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Imports a 2D array
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
bool copyFrom(T(&array)[N1][N2]) {
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < N1; i++) {
|
||||
JsonArray &nestedArray = createNestedArray();
|
||||
for (size_t j = 0; j < N2; j++) {
|
||||
ok &= nestedArray.add(array[i][j]);
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
// Exports a 1D array
|
||||
template <typename T, size_t N>
|
||||
size_t copyTo(T(&array)[N]) const {
|
||||
return copyTo(array, N);
|
||||
}
|
||||
|
||||
// Exports a 1D array
|
||||
template <typename T>
|
||||
size_t copyTo(T *array, size_t len) const {
|
||||
size_t i = 0;
|
||||
for (const_iterator it = begin(); it != end() && i < len; ++it)
|
||||
array[i++] = *it;
|
||||
return i;
|
||||
}
|
||||
|
||||
// Exports a 2D array
|
||||
template <typename T, size_t N1, size_t N2>
|
||||
void copyTo(T(&array)[N1][N2]) const {
|
||||
size_t i = 0;
|
||||
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
|
||||
it->asArray().copyTo(array[i++]);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
node_type *getNodeAt(size_t index) const;
|
||||
|
||||
template <typename TValue>
|
||||
void setNodeAt(size_t index, TValue value);
|
||||
bool setNodeAt(size_t index, TValue value);
|
||||
|
||||
template <typename TValue>
|
||||
bool addNode(TValue);
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE void setNodeValue(node_type *, T value);
|
||||
FORCE_INLINE bool setNodeValue(node_type *, T value);
|
||||
|
||||
// The instance returned by JsonArray::invalid()
|
||||
static JsonArray _invalid;
|
||||
|
@ -8,6 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "JsonArray.hpp"
|
||||
#include "JsonObject.hpp"
|
||||
#include "JsonArraySubscript.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
@ -20,157 +21,30 @@ inline JsonVariant JsonArray::operator[](size_t index) const {
|
||||
return get(index);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(bool value) { return addNode<bool>(value); }
|
||||
|
||||
inline bool JsonArray::add(float value, uint8_t decimals) {
|
||||
return addNode<const JsonVariant &>(JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(double value, uint8_t decimals) {
|
||||
return addNode<const JsonVariant &>(JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(signed char value) {
|
||||
return addNode<signed char>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(signed long value) {
|
||||
return addNode<signed long>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(signed int value) {
|
||||
return addNode<signed int>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(signed short value) {
|
||||
return addNode<signed short>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(unsigned char value) {
|
||||
return addNode<unsigned char>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(unsigned long value) {
|
||||
return addNode<unsigned long>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(unsigned int value) {
|
||||
return addNode<unsigned int>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(unsigned short value) {
|
||||
return addNode<unsigned short>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(const char *value) {
|
||||
return addNode<const char *>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(const String &value) {
|
||||
return addNode<const String &>(value);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(JsonArray &array) {
|
||||
return addNode<JsonArray &>(array);
|
||||
}
|
||||
|
||||
inline bool JsonArray::add(JsonObject &object) {
|
||||
return addNode<JsonObject &>(object);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool JsonArray::add(const T &variant) {
|
||||
return addNode<const JsonVariant &>(variant);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline bool JsonArray::addNode(TValue value) {
|
||||
node_type *node = addNewNode();
|
||||
if (node == NULL) return false;
|
||||
setNodeValue<TValue>(node, value);
|
||||
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;
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, bool value) {
|
||||
return setNodeAt<bool>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, float value, uint8_t decimals) {
|
||||
return setNodeAt<const JsonVariant &>(index, JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, double value, uint8_t decimals) {
|
||||
return setNodeAt<const JsonVariant &>(index, JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, signed char value) {
|
||||
return setNodeAt<signed char>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, signed long value) {
|
||||
return setNodeAt<signed long>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, signed int value) {
|
||||
return setNodeAt<signed int>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, signed short value) {
|
||||
return setNodeAt<signed short>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, unsigned char value) {
|
||||
return setNodeAt<unsigned char>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, unsigned long value) {
|
||||
return setNodeAt<unsigned long>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, unsigned int value) {
|
||||
return setNodeAt<unsigned int>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, unsigned short value) {
|
||||
return setNodeAt<unsigned short>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, const char *value) {
|
||||
return setNodeAt<const char *>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, const String &value) {
|
||||
return setNodeAt<const String &>(index, value);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, JsonArray &array) {
|
||||
return setNodeAt<JsonArray &>(index, array);
|
||||
}
|
||||
|
||||
inline void JsonArray::set(size_t index, JsonObject &object) {
|
||||
return setNodeAt<JsonObject &>(index, object);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void JsonArray::set(size_t index, const T &variant) {
|
||||
return setNodeAt<const JsonVariant &>(index, variant);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline void JsonArray::setNodeAt(size_t index, TValue value) {
|
||||
node_type *node = getNodeAt(index);
|
||||
if (node == NULL) return;
|
||||
setNodeValue<TValue>(node, value);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline void JsonArray::setNodeValue(node_type *node, TValue value) {
|
||||
node->content = value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void JsonArray::setNodeValue(node_type *node, const String &value) {
|
||||
node->content = _buffer->strdup(value);
|
||||
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 {
|
||||
@ -181,7 +55,7 @@ inline JsonVariant JsonArray::get(size_t index) const {
|
||||
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>();
|
||||
return node ? node->content.as<T>() : JsonVariant::defaultValue<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
@ -197,24 +71,31 @@ inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonArray &JsonVariant::invalid<JsonArray &>() {
|
||||
inline JsonArray &JsonVariant::defaultValue<JsonArray &>() {
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonArray const &JsonVariant::invalid<JsonArray const &>() {
|
||||
inline JsonArray const &JsonVariant::defaultValue<JsonArray const &>() {
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonArray &JsonVariant::as<JsonArray &>() const {
|
||||
inline JsonArray &JsonVariant::asArray() const {
|
||||
if (_type == Internals::JSON_ARRAY) return *_content.asArray;
|
||||
return JsonArray::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const JsonArray &JsonVariant::as<const JsonArray &>() 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;
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonSubscriptBase.hpp"
|
||||
#include "Configuration.hpp"
|
||||
#include "JsonVariantBase.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
@ -15,20 +16,30 @@
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
class JsonArraySubscript : public JsonSubscriptBase<JsonArraySubscript> {
|
||||
class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
||||
public:
|
||||
FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index)
|
||||
: _array(array), _index(index) {}
|
||||
|
||||
using JsonSubscriptBase<JsonArraySubscript>::operator=;
|
||||
|
||||
JsonArraySubscript& operator=(const JsonArraySubscript& src) {
|
||||
return assign<const JsonVariant&>(src);
|
||||
_array.set<const JsonVariant&>(_index, src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
JsonArraySubscript& operator=(const T& src) {
|
||||
return assign<const JsonVariant&>(src);
|
||||
typename TypeTraits::EnableIf<JsonArray::CanSet<T&>::value,
|
||||
JsonArraySubscript>::type&
|
||||
operator=(const T& src) {
|
||||
_array.set<T&>(_index, const_cast<T&>(src));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<JsonArray::CanSet<T>::value,
|
||||
JsonArraySubscript>::type&
|
||||
operator=(T src) {
|
||||
_array.set<T>(_index, src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool success() const { return _index < _array.size(); }
|
||||
@ -59,7 +70,7 @@ class JsonArraySubscript : public JsonSubscriptBase<JsonArraySubscript> {
|
||||
const size_t _index;
|
||||
};
|
||||
|
||||
#ifdef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream& operator<<(std::ostream& os,
|
||||
const JsonArraySubscript& source) {
|
||||
return source.printTo(os);
|
||||
|
@ -11,12 +11,16 @@
|
||||
#include <stdint.h> // for uint8_t
|
||||
#include <string.h>
|
||||
|
||||
#include "Arduino/String.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
#include "String.hpp"
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#elif defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
|
||||
@ -94,6 +98,21 @@ class JsonBuffer {
|
||||
return parseObject(json.c_str(), nesting);
|
||||
}
|
||||
|
||||
// Generalized version of parseArray() and parseObject(), also works for
|
||||
// integral types.
|
||||
JsonVariant parse(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
|
||||
|
||||
// Same with a const char*.
|
||||
// With this overload, the JsonBuffer will make a copy of the string
|
||||
JsonVariant parse(const char *json, uint8_t nesting = DEFAULT_LIMIT) {
|
||||
return parse(strdup(json), nesting);
|
||||
}
|
||||
|
||||
// Same as above with a String class
|
||||
JsonVariant parse(const String &json, uint8_t nesting = DEFAULT_LIMIT) {
|
||||
return parse(json.c_str(), nesting);
|
||||
}
|
||||
|
||||
// Duplicate a string
|
||||
char *strdup(const char *src) {
|
||||
return src ? strdup(src, strlen(src)) : NULL;
|
||||
@ -107,12 +126,11 @@ class JsonBuffer {
|
||||
protected:
|
||||
// Preserve aligment if nessary
|
||||
static FORCE_INLINE size_t round_size_up(size_t bytes) {
|
||||
#if defined ARDUINO_ARCH_AVR
|
||||
// alignment isn't needed for 8-bit AVR
|
||||
return bytes;
|
||||
#else
|
||||
#if ARDUINOJSON_ENABLE_ALIGNMENT
|
||||
const size_t x = sizeof(void *) - 1;
|
||||
return (bytes + x) & ~x;
|
||||
#else
|
||||
return bytes;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -135,3 +153,11 @@ class JsonBuffer {
|
||||
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
|
||||
|
@ -7,12 +7,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino/String.hpp"
|
||||
#include "String.hpp"
|
||||
#include "Internals/JsonBufferAllocated.hpp"
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/List.hpp"
|
||||
#include "Internals/ReferenceType.hpp"
|
||||
#include "JsonPair.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||
#include "TypeTraits/IsReference.hpp"
|
||||
#include "TypeTraits/IsSame.hpp"
|
||||
|
||||
// Returns the size (in bytes) of an object with n elements.
|
||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||
@ -36,6 +40,15 @@ 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().
|
||||
@ -50,43 +63,41 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
FORCE_INLINE JsonVariant operator[](JsonObjectKey key) const;
|
||||
|
||||
// Sets the specified key with the specified value.
|
||||
FORCE_INLINE bool set(const char* key, bool value);
|
||||
FORCE_INLINE bool set(const char* key, float value, uint8_t decimals = 2);
|
||||
FORCE_INLINE bool set(const char* key, double value, uint8_t decimals = 2);
|
||||
FORCE_INLINE bool set(const char* key, signed char value);
|
||||
FORCE_INLINE bool set(const char* key, signed long value);
|
||||
FORCE_INLINE bool set(const char* key, signed int value);
|
||||
FORCE_INLINE bool set(const char* key, signed short value);
|
||||
FORCE_INLINE bool set(const char* key, unsigned char value);
|
||||
FORCE_INLINE bool set(const char* key, unsigned long value);
|
||||
FORCE_INLINE bool set(const char* key, unsigned int value);
|
||||
FORCE_INLINE bool set(const char* key, unsigned short value);
|
||||
FORCE_INLINE bool set(const char* key, const char* value);
|
||||
FORCE_INLINE bool set(const char* key, const String& value);
|
||||
FORCE_INLINE bool set(const char* key, JsonArray& array);
|
||||
FORCE_INLINE bool set(const char* key, JsonObject& object);
|
||||
FORCE_INLINE bool set(const char* key, const JsonVariant& value);
|
||||
// bool set(TKey key, bool value);
|
||||
// bool set(TKey key, char value);
|
||||
// bool set(TKey key, long value);
|
||||
// bool set(TKey key, int value);
|
||||
// bool set(TKey key, short value);
|
||||
// bool set(TKey key, float value);
|
||||
// bool set(TKey key, double value);
|
||||
// bool set(TKey key, const char* value);
|
||||
// bool set(TKey key, RawJson value);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(const char* key, const T& value);
|
||||
|
||||
FORCE_INLINE bool set(const String& key, bool value);
|
||||
FORCE_INLINE bool set(const String& key, float value, uint8_t decimals = 2);
|
||||
FORCE_INLINE bool set(const String& key, double value, uint8_t decimals = 2);
|
||||
FORCE_INLINE bool set(const String& key, signed char value);
|
||||
FORCE_INLINE bool set(const String& key, signed long value);
|
||||
FORCE_INLINE bool set(const String& key, signed int value);
|
||||
FORCE_INLINE bool set(const String& key, signed short value);
|
||||
FORCE_INLINE bool set(const String& key, unsigned char value);
|
||||
FORCE_INLINE bool set(const String& key, unsigned long value);
|
||||
FORCE_INLINE bool set(const String& key, unsigned int value);
|
||||
FORCE_INLINE bool set(const String& key, unsigned short value);
|
||||
FORCE_INLINE bool set(const String& key, const char* value);
|
||||
FORCE_INLINE bool set(const String& key, const String& value);
|
||||
FORCE_INLINE bool set(const String& key, JsonArray& array);
|
||||
FORCE_INLINE bool set(const String& key, JsonObject& object);
|
||||
FORCE_INLINE bool set(const String& key, const JsonVariant& value);
|
||||
FORCE_INLINE bool set(
|
||||
JsonObjectKey key, T value,
|
||||
typename TypeTraits::EnableIf<
|
||||
CanSet<T>::value && !TypeTraits::IsReference<T>::value>::type* = 0) {
|
||||
return setNodeAt<T>(key, value);
|
||||
}
|
||||
// bool set(Key, String&);
|
||||
// bool set(Key, JsonArray&);
|
||||
// bool set(Key, JsonObject&);
|
||||
// bool set(Key, JsonVariant&);
|
||||
template <typename T>
|
||||
FORCE_INLINE bool set(const String& key, const T& value);
|
||||
FORCE_INLINE bool set(
|
||||
JsonObjectKey key, const T& value,
|
||||
typename TypeTraits::EnableIf<CanSet<T&>::value>::type* = 0) {
|
||||
return setNodeAt<T&>(key, const_cast<T&>(value));
|
||||
}
|
||||
// bool set(Key, float value, uint8_t decimals);
|
||||
// bool set(Key, double value, uint8_t decimals);
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(
|
||||
JsonObjectKey key, TValue value, uint8_t decimals,
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsFloatingPoint<TValue>::value>::type* = 0) {
|
||||
return setNodeAt<const JsonVariant&>(key, JsonVariant(value, decimals));
|
||||
}
|
||||
|
||||
// Gets the value associated with the specified key.
|
||||
FORCE_INLINE JsonVariant get(JsonObjectKey) const;
|
||||
@ -101,13 +112,11 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
|
||||
// Creates and adds a JsonArray.
|
||||
// This is a shortcut for JsonBuffer::createArray() and JsonObject::add().
|
||||
FORCE_INLINE JsonArray& createNestedArray(const char* key);
|
||||
FORCE_INLINE JsonArray& createNestedArray(const String& key);
|
||||
FORCE_INLINE JsonArray& createNestedArray(JsonObjectKey key);
|
||||
|
||||
// Creates and adds a JsonObject.
|
||||
// This is a shortcut for JsonBuffer::createObject() and JsonObject::add().
|
||||
FORCE_INLINE JsonObject& createNestedObject(const char* key);
|
||||
FORCE_INLINE JsonObject& createNestedObject(const String& key);
|
||||
FORCE_INLINE JsonObject& createNestedObject(JsonObjectKey key);
|
||||
|
||||
// Tells weither the specified key is present and associated with a value.
|
||||
FORCE_INLINE bool containsKey(JsonObjectKey key) const;
|
||||
@ -125,24 +134,17 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
|
||||
|
||||
private:
|
||||
// Returns the list node that matches the specified key.
|
||||
node_type* getNodeAt(JsonObjectKey key) const;
|
||||
node_type* getNodeAt(const char* key) const;
|
||||
|
||||
node_type* getOrCreateNodeAt(JsonObjectKey key);
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
FORCE_INLINE bool setNodeAt(TKey key, TValue value);
|
||||
|
||||
template <typename TKey>
|
||||
JsonArray& createArrayAt(TKey key);
|
||||
|
||||
template <typename TKey>
|
||||
JsonObject& createObjectAt(TKey key);
|
||||
node_type* getOrCreateNodeAt(const char* key);
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE void setNodeKey(node_type*, T key);
|
||||
FORCE_INLINE bool setNodeAt(JsonObjectKey key, T value);
|
||||
|
||||
FORCE_INLINE bool setNodeKey(node_type*, JsonObjectKey key);
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE void setNodeValue(node_type*, T value);
|
||||
FORCE_INLINE bool setNodeValue(node_type*, T value);
|
||||
|
||||
// The instance returned by JsonObject::invalid()
|
||||
static JsonObject _invalid;
|
||||
|
@ -7,25 +7,26 @@
|
||||
|
||||
#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);
|
||||
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);
|
||||
return node ? node->content.value.as<T>() : JsonVariant::invalid<T>();
|
||||
node_type *node = getNodeAt(key.c_str());
|
||||
return node ? node->content.value.as<T>() : JsonVariant::defaultValue<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline bool JsonObject::is(JsonObjectKey key) const {
|
||||
node_type *node = getNodeAt(key);
|
||||
node_type *node = getNodeAt(key.c_str());
|
||||
return node ? node->content.value.is<T>() : false;
|
||||
}
|
||||
|
||||
@ -44,165 +45,49 @@ inline JsonVariant JsonObject::operator[](JsonObjectKey key) const {
|
||||
}
|
||||
|
||||
inline bool JsonObject::containsKey(JsonObjectKey key) const {
|
||||
return getNodeAt(key) != NULL;
|
||||
}
|
||||
|
||||
inline JsonArray &JsonObject::createNestedArray(const char *key) {
|
||||
return createArrayAt<const char *>(key);
|
||||
}
|
||||
|
||||
inline JsonArray &JsonObject::createNestedArray(const String &key) {
|
||||
return createArrayAt<const String &>(key);
|
||||
}
|
||||
|
||||
inline JsonObject &JsonObject::createNestedObject(const char *key) {
|
||||
return createObjectAt<const char *>(key);
|
||||
}
|
||||
|
||||
inline JsonObject &JsonObject::createNestedObject(const String &key) {
|
||||
return createObjectAt<const String &>(key);
|
||||
return getNodeAt(key.c_str()) != NULL;
|
||||
}
|
||||
|
||||
inline void JsonObject::remove(JsonObjectKey key) {
|
||||
removeNode(getNodeAt(key));
|
||||
removeNode(getNodeAt(key.c_str()));
|
||||
}
|
||||
|
||||
inline bool JsonObject::set(const char *key, bool value) {
|
||||
return setNodeAt<const char *, bool>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, float value, uint8_t decimals) {
|
||||
return setNodeAt<const char *, const JsonVariant &>(
|
||||
key, JsonVariant(value, decimals));
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, double value, uint8_t decimals) {
|
||||
return setNodeAt<const char *, const JsonVariant &>(
|
||||
key, JsonVariant(value, decimals));
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, signed char value) {
|
||||
return setNodeAt<const char *, signed char>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, signed long value) {
|
||||
return setNodeAt<const char *, signed long>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, signed int value) {
|
||||
return setNodeAt<const char *, signed int>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, signed short value) {
|
||||
return setNodeAt<const char *, signed short>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, unsigned char value) {
|
||||
return setNodeAt<const char *, unsigned char>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, unsigned long value) {
|
||||
return setNodeAt<const char *, unsigned long>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, unsigned int value) {
|
||||
return setNodeAt<const char *, unsigned int>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, unsigned short value) {
|
||||
return setNodeAt<const char *, unsigned short>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, const char *value) {
|
||||
return setNodeAt<const char *, const char *>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, const String &value) {
|
||||
return setNodeAt<const char *, const String &>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, JsonArray &array) {
|
||||
return setNodeAt<const char *, JsonArray &>(key, array);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, JsonObject &object) {
|
||||
return setNodeAt<const char *, JsonObject &>(key, object);
|
||||
}
|
||||
inline bool JsonObject::set(const char *key, const JsonVariant &value) {
|
||||
return setNodeAt<const char *, const JsonVariant &>(key, value);
|
||||
}
|
||||
template <typename T>
|
||||
inline bool JsonObject::set(const char *key, const T &value) {
|
||||
return setNodeAt<const char *, JsonVariant>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, bool value) {
|
||||
return setNodeAt<const String &, bool>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, float value, uint8_t decimals) {
|
||||
return setNodeAt<const String &, const JsonVariant &>(
|
||||
key, JsonVariant(value, decimals));
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, double value, uint8_t decimals) {
|
||||
return setNodeAt<const String &, const JsonVariant &>(
|
||||
key, JsonVariant(value, decimals));
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, signed char value) {
|
||||
return setNodeAt<const String &, signed char>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, signed long value) {
|
||||
return setNodeAt<const String &, signed long>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, signed int value) {
|
||||
return setNodeAt<const String &, signed int>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, signed short value) {
|
||||
return setNodeAt<const String &, signed short>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, unsigned char value) {
|
||||
return setNodeAt<const String &, unsigned char>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, unsigned long value) {
|
||||
return setNodeAt<const String &, unsigned long>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, unsigned int value) {
|
||||
return setNodeAt<const String &, unsigned int>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, unsigned short value) {
|
||||
return setNodeAt<const String &, unsigned short>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, const char *value) {
|
||||
return setNodeAt<const String &, const char *>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, const String &value) {
|
||||
return setNodeAt<const String &, const String &>(key, value);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, JsonArray &array) {
|
||||
return setNodeAt<const String &, JsonArray &>(key, array);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, JsonObject &object) {
|
||||
return setNodeAt<const String &, JsonObject &>(key, object);
|
||||
}
|
||||
inline bool JsonObject::set(const String &key, const JsonVariant &value) {
|
||||
return setNodeAt<const String &, const JsonVariant &>(key, value);
|
||||
}
|
||||
template <typename T>
|
||||
inline bool JsonObject::set(const String &key, const T &value) {
|
||||
return setNodeAt<const String &, JsonVariant>(key, value);
|
||||
inline bool JsonObject::setNodeAt(JsonObjectKey key, T value) {
|
||||
node_type *node = getNodeAt(key.c_str());
|
||||
if (!node) {
|
||||
node = addNewNode();
|
||||
if (!node || !setNodeKey(node, key)) return false;
|
||||
}
|
||||
return setNodeValue<T>(node, value);
|
||||
}
|
||||
|
||||
template <typename TKey, typename TValue>
|
||||
inline bool JsonObject::setNodeAt(TKey key, TValue value) {
|
||||
node_type *node = getOrCreateNodeAt(key);
|
||||
if (!node) return false;
|
||||
setNodeKey<TKey>(node, key);
|
||||
setNodeValue<TValue>(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 void JsonObject::setNodeKey(node_type *node, const char *key) {
|
||||
node->content.key = key;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void JsonObject::setNodeKey(node_type *node, const String &key) {
|
||||
node->content.key = _buffer->strdup(key);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
inline void JsonObject::setNodeValue(node_type *node, TValue value) {
|
||||
node->content.value = value;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline void JsonObject::setNodeValue(node_type *node, const String &value) {
|
||||
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>
|
||||
@ -218,24 +103,31 @@ operator[](const String &key) const {
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonObject const &JsonVariant::invalid<JsonObject const &>() {
|
||||
inline JsonObject const &JsonVariant::defaultValue<JsonObject const &>() {
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonObject &JsonVariant::invalid<JsonObject &>() {
|
||||
inline JsonObject &JsonVariant::defaultValue<JsonObject &>() {
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline JsonObject &JsonVariant::as<JsonObject &>() const {
|
||||
inline JsonObject &JsonVariant::asObject() const {
|
||||
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
|
||||
return JsonObject::invalid();
|
||||
}
|
||||
|
||||
template <>
|
||||
inline const JsonObject &JsonVariant::as<const JsonObject &>() 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;
|
||||
}
|
||||
}
|
||||
|
@ -7,19 +7,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Arduino/String.hpp"
|
||||
#include "String.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// Represents a key in a JsonObject
|
||||
class JsonObjectKey {
|
||||
public:
|
||||
JsonObjectKey() {}
|
||||
JsonObjectKey(const char* key) : _data(key) {}
|
||||
JsonObjectKey(const String& key) : _data(key.c_str()) {}
|
||||
JsonObjectKey(const char* key) : _value(key), _needs_copy(false) {}
|
||||
JsonObjectKey(const String& key) : _value(key.c_str()), _needs_copy(true) {}
|
||||
|
||||
operator const char*() const { return _data; }
|
||||
const char* c_str() const { return _value; }
|
||||
bool needs_copy() const { return _needs_copy; }
|
||||
|
||||
private:
|
||||
const char* _data;
|
||||
const char* _value;
|
||||
bool _needs_copy;
|
||||
};
|
||||
}
|
||||
|
@ -7,7 +7,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonSubscriptBase.hpp"
|
||||
#include "Configuration.hpp"
|
||||
#include "JsonVariantBase.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
@ -17,23 +19,30 @@
|
||||
namespace ArduinoJson {
|
||||
|
||||
template <typename TKey>
|
||||
class JsonObjectSubscript
|
||||
: public JsonSubscriptBase<JsonObjectSubscript<TKey> > {
|
||||
class JsonObjectSubscript : public JsonVariantBase<JsonObjectSubscript<TKey> > {
|
||||
public:
|
||||
FORCE_INLINE JsonObjectSubscript(JsonObject& object, TKey key)
|
||||
: _object(object), _key(key) {}
|
||||
|
||||
using JsonSubscriptBase<JsonObjectSubscript<TKey> >::operator=;
|
||||
|
||||
JsonObjectSubscript<TKey>& operator=(const JsonObjectSubscript<TKey>& src) {
|
||||
return JsonSubscriptBase<JsonObjectSubscript<TKey> >::template assign<
|
||||
JsonVariant>(src);
|
||||
_object.set<const JsonVariant&>(_key, src);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
JsonObjectSubscript<TKey>& operator=(const T& src) {
|
||||
return JsonSubscriptBase<JsonObjectSubscript<TKey> >::template assign<
|
||||
JsonVariant>(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;
|
||||
}
|
||||
|
||||
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); }
|
||||
@ -52,7 +61,7 @@ class JsonObjectSubscript
|
||||
|
||||
template <typename TValue>
|
||||
FORCE_INLINE bool set(TValue value) {
|
||||
return _object.set(_key, value);
|
||||
return _object.set<TValue>(_key, value);
|
||||
}
|
||||
|
||||
template <typename TValue>
|
||||
@ -71,7 +80,7 @@ class JsonObjectSubscript
|
||||
TKey _key;
|
||||
};
|
||||
|
||||
#ifdef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream& operator<<(
|
||||
std::ostream& os, const JsonObjectSubscript<const String&>& source) {
|
||||
return source.printTo(os);
|
||||
@ -82,6 +91,7 @@ inline std::ostream& operator<<(
|
||||
return source.printTo(os);
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace ArduinoJson
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -14,7 +14,7 @@ namespace ArduinoJson {
|
||||
|
||||
// A key value pair for JsonObject.
|
||||
struct JsonPair {
|
||||
JsonObjectKey key;
|
||||
const char* key;
|
||||
JsonVariant value;
|
||||
};
|
||||
}
|
||||
|
@ -1,83 +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"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
template <typename TImpl>
|
||||
class JsonSubscriptBase : public JsonVariantBase<TImpl> {
|
||||
public:
|
||||
FORCE_INLINE TImpl& operator=(bool value) { return assign<bool>(value); }
|
||||
|
||||
FORCE_INLINE TImpl& operator=(float value) { return assign<float>(value); }
|
||||
|
||||
FORCE_INLINE TImpl& operator=(double value) { return assign<double>(value); }
|
||||
|
||||
FORCE_INLINE TImpl& operator=(signed char value) {
|
||||
return assign<signed char>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(signed long value) {
|
||||
return assign<signed long>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(signed int value) {
|
||||
return assign<signed int>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(signed short value) {
|
||||
return assign<signed short>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(unsigned char value) {
|
||||
return assign<unsigned char>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(unsigned long value) {
|
||||
return assign<unsigned long>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(unsigned int value) {
|
||||
return assign<unsigned int>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(unsigned short value) {
|
||||
return assign<unsigned short>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(const char* value) {
|
||||
return assign<const char*>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(const String& value) {
|
||||
return assign<const String&>(value);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(JsonArray& array) {
|
||||
return assign<JsonArray&>(array);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(JsonObject& object) {
|
||||
return assign<JsonObject&>(object);
|
||||
}
|
||||
|
||||
FORCE_INLINE TImpl& operator=(JsonVariant value) {
|
||||
return assign<const JsonVariant&>(value);
|
||||
}
|
||||
|
||||
protected:
|
||||
template <typename TValue>
|
||||
FORCE_INLINE TImpl& assign(TValue value) {
|
||||
TImpl* that = static_cast<TImpl*>(this);
|
||||
that->template set<TValue>(value);
|
||||
return *that;
|
||||
}
|
||||
};
|
||||
}
|
@ -13,8 +13,14 @@
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/JsonVariantContent.hpp"
|
||||
#include "Internals/JsonVariantType.hpp"
|
||||
#include "Internals/Unparsed.hpp"
|
||||
#include "JsonVariantBase.hpp"
|
||||
#include "RawJson.hpp"
|
||||
#include "TypeTraits/EnableIf.hpp"
|
||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||
#include "TypeTraits/IsIntegral.hpp"
|
||||
#include "TypeTraits/IsSame.hpp"
|
||||
#include "TypeTraits/RemoveConst.hpp"
|
||||
#include "TypeTraits/RemoveReference.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
@ -31,6 +37,9 @@ class JsonObject;
|
||||
// - a reference to a JsonArray or JsonObject
|
||||
class JsonVariant : public JsonVariantBase<JsonVariant> {
|
||||
public:
|
||||
template <typename T>
|
||||
struct IsConstructibleFrom;
|
||||
|
||||
// Creates an uninitialized JsonVariant
|
||||
FORCE_INLINE JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
|
||||
|
||||
@ -41,24 +50,52 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
||||
// Create a JsonVariant containing a floating point value.
|
||||
// The second argument specifies the number of decimal digits to write in
|
||||
// the JSON string.
|
||||
FORCE_INLINE JsonVariant(float value, uint8_t decimals = 2);
|
||||
FORCE_INLINE JsonVariant(double value, uint8_t decimals = 2);
|
||||
// JsonVariant(double value, uint8_t decimals);
|
||||
// JsonVariant(float value, uint8_t decimals);
|
||||
template <typename T>
|
||||
FORCE_INLINE JsonVariant(
|
||||
T value, uint8_t decimals = 2,
|
||||
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value>::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.
|
||||
FORCE_INLINE JsonVariant(signed char value);
|
||||
FORCE_INLINE JsonVariant(signed long value);
|
||||
FORCE_INLINE JsonVariant(signed int value);
|
||||
FORCE_INLINE JsonVariant(signed short value);
|
||||
FORCE_INLINE JsonVariant(unsigned char value);
|
||||
FORCE_INLINE JsonVariant(unsigned long value);
|
||||
FORCE_INLINE JsonVariant(unsigned int value);
|
||||
FORCE_INLINE JsonVariant(unsigned short value);
|
||||
// JsonVariant(signed short)
|
||||
// JsonVariant(signed int)
|
||||
// JsonVariant(signed long)
|
||||
template <typename T>
|
||||
FORCE_INLINE JsonVariant(
|
||||
T value, typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSignedIntegral<T>::value>::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>
|
||||
FORCE_INLINE 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);
|
||||
}
|
||||
|
||||
// Create a JsonVariant containing a string.
|
||||
FORCE_INLINE JsonVariant(const char *value);
|
||||
|
||||
// Create a JsonVariant containing an unparsed string
|
||||
FORCE_INLINE JsonVariant(Internals::Unparsed value);
|
||||
FORCE_INLINE JsonVariant(RawJson value);
|
||||
|
||||
// Create a JsonVariant containing a reference to an array.
|
||||
FORCE_INLINE JsonVariant(JsonArray &array);
|
||||
@ -67,25 +104,191 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
|
||||
FORCE_INLINE JsonVariant(JsonObject &object);
|
||||
|
||||
// Get the variant as the specified type.
|
||||
// See cast operators for details.
|
||||
//
|
||||
// short as<signed short>() const;
|
||||
// int as<signed int>() const;
|
||||
// long as<signed long>() const;
|
||||
template <typename T>
|
||||
T as() const;
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsSignedIntegral<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>
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
|
||||
T>::type
|
||||
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,
|
||||
const char *>::type
|
||||
as() const {
|
||||
return asString();
|
||||
}
|
||||
//
|
||||
// const bool as<bool>() const
|
||||
template <typename T>
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
|
||||
T>::type
|
||||
as() const {
|
||||
return asInteger() != 0;
|
||||
}
|
||||
//
|
||||
// JsonArray& as<JsonArray> const;
|
||||
// JsonArray& as<JsonArray&> const;
|
||||
// JsonArray& as<const JsonArray&> const;
|
||||
template <typename T>
|
||||
typename TypeTraits::EnableIf<
|
||||
TypeTraits::IsSame<
|
||||
typename TypeTraits::RemoveConst<
|
||||
typename TypeTraits::RemoveReference<T>::type>::type,
|
||||
JsonArray>::value,
|
||||
JsonArray &>::type
|
||||
as() const {
|
||||
return asArray();
|
||||
}
|
||||
//
|
||||
// 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,
|
||||
JsonObject &>::type
|
||||
as() const {
|
||||
return asObject();
|
||||
}
|
||||
|
||||
// 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>
|
||||
bool is() const;
|
||||
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::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;
|
||||
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();
|
||||
}
|
||||
//
|
||||
// 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();
|
||||
}
|
||||
|
||||
// Returns true if the variant has a value
|
||||
bool success() const { return _type != Internals::JSON_UNDEFINED; }
|
||||
|
||||
// Serialize the variant to a JsonWriter
|
||||
void writeTo(Internals::JsonWriter &writer) const;
|
||||
|
||||
// TODO: rename
|
||||
// Value returned if the variant has an incompatible type
|
||||
template <typename T>
|
||||
static T invalid();
|
||||
static T defaultValue() {
|
||||
return T();
|
||||
}
|
||||
|
||||
const char *asString() const;
|
||||
JsonArray &asArray() const;
|
||||
JsonObject &asObject() const;
|
||||
|
||||
private:
|
||||
// It's not allowed to store a char
|
||||
template <typename T>
|
||||
FORCE_INLINE 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; }
|
||||
|
||||
// The current type of the variant
|
||||
Internals::JsonVariantType _type;
|
||||
@ -101,6 +304,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, RawJson>::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
|
||||
|
@ -7,7 +7,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Configuration.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
#include "Internals/Parse.hpp"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
@ -22,23 +26,11 @@ inline JsonVariant::JsonVariant(const char *value) {
|
||||
_content.asString = value;
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(Internals::Unparsed value) {
|
||||
inline JsonVariant::JsonVariant(RawJson value) {
|
||||
_type = Internals::JSON_UNPARSED;
|
||||
_content.asString = value;
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(double value, uint8_t decimals) {
|
||||
using namespace Internals;
|
||||
_type = static_cast<JsonVariantType>(JSON_FLOAT_0_DECIMALS + decimals);
|
||||
_content.asFloat = static_cast<JsonFloat>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(float value, uint8_t decimals) {
|
||||
using namespace Internals;
|
||||
_type = static_cast<JsonVariantType>(JSON_FLOAT_0_DECIMALS + decimals);
|
||||
_content.asFloat = static_cast<JsonFloat>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(JsonArray &array) {
|
||||
_type = Internals::JSON_ARRAY;
|
||||
_content.asArray = &array;
|
||||
@ -49,200 +41,46 @@ inline JsonVariant::JsonVariant(JsonObject &object) {
|
||||
_content.asObject = &object;
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(signed char value) {
|
||||
inline Internals::JsonInteger JsonVariant::asInteger() const {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
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 JsonVariant::JsonVariant(signed int value) {
|
||||
inline Internals::JsonUInt JsonVariant::asUnsignedInteger() const {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
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 JsonVariant::JsonVariant(signed long value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(signed short value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(unsigned char value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(unsigned int value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(unsigned long value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
inline JsonVariant::JsonVariant(unsigned short value) {
|
||||
using namespace Internals;
|
||||
_type = JSON_INTEGER;
|
||||
_content.asInteger = static_cast<JsonInteger>(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
String JsonVariant::as<String>() const;
|
||||
|
||||
template <>
|
||||
const char *JsonVariant::as<const char *>() const;
|
||||
|
||||
template <>
|
||||
inline bool JsonVariant::as<bool>() const {
|
||||
return asInteger() != 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline signed char JsonVariant::as<signed char>() const {
|
||||
return static_cast<signed char>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned char JsonVariant::as<unsigned char>() const {
|
||||
return static_cast<unsigned char>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline signed short JsonVariant::as<signed short>() const {
|
||||
return static_cast<signed short>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned short JsonVariant::as<unsigned short>() const {
|
||||
return static_cast<unsigned short>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline signed int JsonVariant::as<signed int>() const {
|
||||
return static_cast<signed int>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned int JsonVariant::as<unsigned int>() const {
|
||||
return static_cast<unsigned int>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline unsigned long JsonVariant::as<unsigned long>() const {
|
||||
return static_cast<unsigned long>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline signed long JsonVariant::as<signed long>() const {
|
||||
return static_cast<unsigned long>(asInteger());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline double JsonVariant::as<double>() const {
|
||||
return static_cast<double>(asFloat());
|
||||
}
|
||||
|
||||
template <>
|
||||
inline float JsonVariant::as<float>() const {
|
||||
return static_cast<float>(asFloat());
|
||||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
|
||||
#ifdef ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
|
||||
return source.printTo(os);
|
||||
}
|
||||
|
@ -20,31 +20,7 @@ class JsonObjectSubscript;
|
||||
template <typename TImpl>
|
||||
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
|
||||
public:
|
||||
// Gets the variant as a boolean value.
|
||||
// Returns false if the variant is not a boolean value.
|
||||
FORCE_INLINE operator bool() const { return as<bool>(); }
|
||||
|
||||
// Gets the variant as a floating-point value.
|
||||
// Returns 0.0 if the variant is not a floating-point value
|
||||
FORCE_INLINE operator double() const { return as<double>(); }
|
||||
FORCE_INLINE operator float() const { return as<float>(); }
|
||||
|
||||
// Gets the variant as an integer value.
|
||||
// Returns 0 if the variant is not an integer value.
|
||||
FORCE_INLINE operator signed long() const { return as<signed long>(); }
|
||||
FORCE_INLINE operator signed char() const { return as<signed char>(); }
|
||||
FORCE_INLINE operator signed int() const { return as<signed int>(); }
|
||||
FORCE_INLINE operator signed short() const { return as<signed short>(); }
|
||||
FORCE_INLINE operator unsigned char() const { return as<unsigned char>(); }
|
||||
FORCE_INLINE operator unsigned int() const { return as<unsigned int>(); }
|
||||
FORCE_INLINE operator unsigned long() const { return as<unsigned long>(); }
|
||||
FORCE_INLINE operator unsigned short() const { return as<unsigned short>(); }
|
||||
|
||||
// Gets the variant as a string.
|
||||
// Returns NULL if variant is not a string.
|
||||
FORCE_INLINE operator const char *() const { return as<const char *>(); }
|
||||
FORCE_INLINE const char *asString() const { return as<const char *>(); }
|
||||
FORCE_INLINE operator String() const { return as<String>(); }
|
||||
|
||||
// Gets the variant as an array.
|
||||
// Returns a reference to the JsonArray or JsonArray::invalid() if the
|
||||
@ -59,6 +35,11 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
|
||||
FORCE_INLINE operator JsonObject &() const { return as<JsonObject &>(); }
|
||||
FORCE_INLINE JsonObject &asObject() const { return as<JsonObject &>(); }
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE operator T() const {
|
||||
return as<T>();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
FORCE_INLINE const T as() const {
|
||||
return impl()->template as<T>();
|
||||
|
65
include/ArduinoJson/Polyfills/isInfinity.hpp
Normal file
65
include/ArduinoJson/Polyfills/isInfinity.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
// If Visual Studo <= 2012
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#include <float.h>
|
||||
#else
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
// GCC warning: "conversion to 'float' from 'double' may alter its value"
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
|
||||
#pragma GCC diagnostic ignored "-Wfloat-conversion"
|
||||
#else
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Polyfills {
|
||||
|
||||
// If Visual Studo <= 2012
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
template <typename T>
|
||||
bool isInfinity(T x) {
|
||||
return !_finite(x);
|
||||
}
|
||||
#else
|
||||
template <typename T>
|
||||
bool isInfinity(T x) {
|
||||
return isinf(x);
|
||||
}
|
||||
|
||||
#if defined(_GLIBCXX_HAVE_ISINFL) && _GLIBCXX_HAVE_ISINFL
|
||||
template <>
|
||||
inline bool isInfinity<double>(double x) {
|
||||
return isinfl(x);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_GLIBCXX_HAVE_ISINFF) && _GLIBCXX_HAVE_ISINFF
|
||||
template <>
|
||||
inline bool isInfinity<float>(float x) {
|
||||
return isinff(x);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
54
include/ArduinoJson/Polyfills/isNaN.hpp
Normal file
54
include/ArduinoJson/Polyfills/isNaN.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
// If Visual Studo <= 2012
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#include <float.h>
|
||||
#else
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
// GCC warning: "conversion to 'float' from 'double' may alter its value"
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic push
|
||||
#endif
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
|
||||
#pragma GCC diagnostic ignored "-Wfloat-conversion"
|
||||
#else
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Polyfills {
|
||||
|
||||
// If Visual Studo <= 2012
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
|
||||
template <typename T>
|
||||
bool isNaN(T x) {
|
||||
return _isnan(x) != 0;
|
||||
}
|
||||
#else
|
||||
|
||||
template <typename T>
|
||||
bool isNaN(T x) {
|
||||
return isnan(x);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
#endif
|
47
include/ArduinoJson/Polyfills/normalize.hpp
Normal file
47
include/ArduinoJson/Polyfills/normalize.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
// Copyright Benoit Blanchon 2014-2016
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#pragma once
|
||||
|
||||
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
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
// This class reproduces Arduino's Print class
|
||||
class Print {
|
||||
public:
|
||||
@ -19,12 +20,17 @@ class Print {
|
||||
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
|
||||
size_t print(const char[]);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(int);
|
||||
size_t print(long);
|
||||
size_t println();
|
||||
size_t print(const char* s) {
|
||||
size_t n = 0;
|
||||
while (*s) {
|
||||
n += write(*s++);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t println() { return write('\r') + write('\n'); }
|
||||
};
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -8,14 +8,14 @@
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
class Unparsed {
|
||||
|
||||
// A special type of data that can be used to insert pregenerated JSON portions.
|
||||
class RawJson {
|
||||
public:
|
||||
explicit Unparsed(const char* str) : _str(str) {}
|
||||
explicit RawJson(const char* str) : _str(str) {}
|
||||
operator const char*() const { return _str; }
|
||||
|
||||
private:
|
||||
const char* _str;
|
||||
};
|
||||
}
|
||||
}
|
@ -7,13 +7,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINO
|
||||
#include "Configuration.hpp"
|
||||
|
||||
#include <string>
|
||||
typedef std::string String;
|
||||
|
||||
#else
|
||||
#if ARDUINOJSON_USE_ARDUINO_STRING
|
||||
|
||||
#include <WString.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ArduinoJson {
|
||||
typedef std::string String;
|
||||
}
|
||||
|
||||
#endif
|
22
include/ArduinoJson/TypeTraits/EnableIf.hpp
Normal file
22
include/ArduinoJson/TypeTraits/EnableIf.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// 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 if Condition is true.
|
||||
template <bool Condition, typename T = void>
|
||||
struct EnableIf {};
|
||||
|
||||
template <typename T>
|
||||
struct EnableIf<true, T> {
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
}
|
21
include/ArduinoJson/TypeTraits/IsFloatingPoint.hpp
Normal file
21
include/ArduinoJson/TypeTraits/IsFloatingPoint.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
// 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 "IsSame.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace TypeTraits {
|
||||
|
||||
// A meta-function that returns true if T is a floating point type
|
||||
template <typename T>
|
||||
struct IsFloatingPoint {
|
||||
static const bool value = IsSame<T, float>::value || IsSame<T, double>::value;
|
||||
};
|
||||
}
|
||||
}
|
26
include/ArduinoJson/TypeTraits/IsIntegral.hpp
Normal file
26
include/ArduinoJson/TypeTraits/IsIntegral.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// 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"
|
||||
#include "IsSignedIntegral.hpp"
|
||||
#include "IsUnsignedIntegral.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
24
include/ArduinoJson/TypeTraits/IsReference.hpp
Normal file
24
include/ArduinoJson/TypeTraits/IsReference.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
// 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 T is a reference
|
||||
template <typename T>
|
||||
struct IsReference {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsReference<T&> {
|
||||
static const bool value = true;
|
||||
};
|
||||
}
|
||||
}
|
24
include/ArduinoJson/TypeTraits/IsSame.hpp
Normal file
24
include/ArduinoJson/TypeTraits/IsSame.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
// 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 types T and U are the same.
|
||||
template <typename T, typename U>
|
||||
struct IsSame {
|
||||
static const bool value = false;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct IsSame<T, T> {
|
||||
static const bool value = true;
|
||||
};
|
||||
}
|
||||
}
|
33
include/ArduinoJson/TypeTraits/IsSignedIntegral.hpp
Normal file
33
include/ArduinoJson/TypeTraits/IsSignedIntegral.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// 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;
|
||||
};
|
||||
}
|
||||
}
|
33
include/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp
Normal file
33
include/ArduinoJson/TypeTraits/IsUnsignedIntegral.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// 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;
|
||||
};
|
||||
}
|
||||
}
|
23
include/ArduinoJson/TypeTraits/RemoveConst.hpp
Normal file
23
include/ArduinoJson/TypeTraits/RemoveConst.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// 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 RemoveConst {
|
||||
typedef T type;
|
||||
};
|
||||
template <typename T>
|
||||
struct RemoveConst<const T> {
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
}
|
23
include/ArduinoJson/TypeTraits/RemoveReference.hpp
Normal file
23
include/ArduinoJson/TypeTraits/RemoveReference.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// 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 reference modifier.
|
||||
template <typename T>
|
||||
struct RemoveReference {
|
||||
typedef T type;
|
||||
};
|
||||
template <typename T>
|
||||
struct RemoveReference<T&> {
|
||||
typedef T type;
|
||||
};
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"version": "5.0.8",
|
||||
"version": "5.5.1",
|
||||
"authors": {
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "http://blog.benoitblanchon.fr"
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ArduinoJson
|
||||
version=5.0.8
|
||||
version=5.5.1
|
||||
author=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
|
||||
sentence=An efficient and elegant JSON library for Arduino.
|
||||
|
@ -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 12 2013"
|
||||
build-env "VisualStudio" "Visual Studio 14 2015"
|
||||
else
|
||||
build-env "SublimeText" "Sublime Text 2 - Ninja"
|
||||
build-env "Make" "Unix Makefiles"
|
||||
build-env "Xcode" "Xcode"
|
||||
fi
|
||||
fi
|
||||
|
@ -11,5 +11,6 @@ export PATH=$PATH:/tmp/arduino/
|
||||
|
||||
ln -s $PWD /tmp/arduino/libraries/ArduinoJson
|
||||
|
||||
arduino --verify --board $BOARD $PWD/examples/JsonParserExample/JsonParserExample.ino
|
||||
arduino --verify --board $BOARD $PWD/examples/JsonGeneratorExample/JsonGeneratorExample.ino
|
||||
for EXAMPLE in $PWD/examples/*/*.ino; do
|
||||
arduino --verify --board $BOARD $EXAMPLE
|
||||
done
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/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
|
9
scripts/travis/cmake-osx.sh
Executable file
9
scripts/travis/cmake-osx.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/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
|
9
scripts/travis/cmake.sh
Executable file
9
scripts/travis/cmake.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh -eux
|
||||
|
||||
URL=https://cmake.org/files/v3.4/cmake-3.4.3-Linux-x86_64.tar.gz
|
||||
|
||||
curl -sS $URL | tar xz -C /tmp --strip 1
|
||||
|
||||
/tmp/bin/cmake -DCMAKE_CXX_COMPILER=$CMAKE_CXX_COMPILER .
|
||||
make
|
||||
make test
|
@ -1,8 +1,5 @@
|
||||
#!/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 .
|
@ -1,72 +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!
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
#include "../../include/ArduinoJson/Arduino/Print.hpp"
|
||||
|
||||
#include <math.h> // for isnan() and isinf()
|
||||
#include <stdio.h> // for sprintf()
|
||||
|
||||
// only for GCC 4.9+
|
||||
#if defined(__GNUC__) && \
|
||||
(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
|
||||
#pragma GCC diagnostic ignored "-Wfloat-conversion"
|
||||
#endif
|
||||
|
||||
// Visual Studo 2012 didn't have isnan, nor isinf
|
||||
#if defined(_MSC_VER) && _MSC_VER <= 1700
|
||||
#include <float.h>
|
||||
#define isnan(x) _isnan(x)
|
||||
#define isinf(x) (!_finite(x))
|
||||
#endif
|
||||
|
||||
size_t Print::print(const char s[]) {
|
||||
size_t n = 0;
|
||||
while (*s) {
|
||||
n += write(*s++);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t Print::print(double value, int digits) {
|
||||
// https://github.com/arduino/Arduino/blob/db8cbf24c99dc930b9ccff1a43d018c81f178535/hardware/arduino/sam/cores/arduino/Print.cpp#L218
|
||||
if (isnan(value)) return print("nan");
|
||||
if (isinf(value)) return print("inf");
|
||||
|
||||
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 trying to use scientific notation, since we have sprintf
|
||||
sprintf(tmp, "%g", value);
|
||||
} else {
|
||||
// Here we have the exact same output as Arduino's implementation
|
||||
sprintf(tmp, "%.*f", digits, value);
|
||||
}
|
||||
|
||||
return print(tmp);
|
||||
}
|
||||
|
||||
size_t Print::print(long value) {
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%ld", value);
|
||||
return print(tmp);
|
||||
}
|
||||
|
||||
size_t Print::print(int value) {
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%d", value);
|
||||
return print(tmp);
|
||||
}
|
||||
|
||||
size_t Print::println() { return write('\r') + write('\n'); }
|
||||
|
||||
#endif
|
@ -10,7 +10,7 @@ file(GLOB_RECURSE IPP_FILES ../include/*.ipp)
|
||||
file(GLOB_RECURSE CPP_FILES *.cpp)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||
add_definitions(
|
||||
add_compile_options(
|
||||
-fno-exceptions
|
||||
-fno-rtti
|
||||
-pedantic
|
||||
@ -40,25 +40,30 @@ if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU)")
|
||||
add_definitions(
|
||||
-Wlogical-op
|
||||
-Wnoexcept
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
|
||||
add_compile_options(
|
||||
-Wstrict-null-sentinel
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.5)
|
||||
add_compile_options(-Wlogical-op) # the flag exists in 4.4 but is buggy
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.6)
|
||||
add_compile_options(-Wnoexcept)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
add_definitions(
|
||||
add_compile_options(
|
||||
-Wc++11-compat
|
||||
-Wdeprecated-register
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
add_definitions(
|
||||
-D_CRT_SECURE_NO_WARNINGS
|
||||
-W4)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_compile_options(-W4)
|
||||
endif()
|
||||
|
||||
add_library(ArduinoJson ${CPP_FILES} ${HPP_FILES} ${IPP_FILES})
|
||||
|
@ -195,7 +195,7 @@ bool JsonParser::parseStringTo(JsonVariant *destination) {
|
||||
if (hasQuotes) {
|
||||
*destination = value;
|
||||
} else {
|
||||
*destination = Unparsed(value);
|
||||
*destination = RawJson(value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -21,20 +21,6 @@ JsonArray::node_type *JsonArray::getNodeAt(size_t index) const {
|
||||
return node;
|
||||
}
|
||||
|
||||
JsonArray &JsonArray::createNestedArray() {
|
||||
if (!_buffer) return JsonArray::invalid();
|
||||
JsonArray &array = _buffer->createArray();
|
||||
add(array);
|
||||
return array;
|
||||
}
|
||||
|
||||
JsonObject &JsonArray::createNestedObject() {
|
||||
if (!_buffer) return JsonObject::invalid();
|
||||
JsonObject &object = _buffer->createObject();
|
||||
add(object);
|
||||
return object;
|
||||
}
|
||||
|
||||
void JsonArray::removeAt(size_t index) { removeNode(getNodeAt(index)); }
|
||||
|
||||
void JsonArray::writeTo(JsonWriter &writer) const {
|
||||
|
@ -34,6 +34,11 @@ JsonObject &JsonBuffer::parseObject(char *json, uint8_t nestingLimit) {
|
||||
return parser.parseObject();
|
||||
}
|
||||
|
||||
JsonVariant JsonBuffer::parse(char *json, uint8_t nestingLimit) {
|
||||
JsonParser parser(this, json, nestingLimit);
|
||||
return parser.parseVariant();
|
||||
}
|
||||
|
||||
char *JsonBuffer::strdup(const char *source, size_t length) {
|
||||
size_t size = length + 1;
|
||||
char *dest = static_cast<char *>(alloc(size));
|
||||
|
@ -18,35 +18,7 @@ using namespace ArduinoJson::Internals;
|
||||
|
||||
JsonObject JsonObject::_invalid(NULL);
|
||||
|
||||
JsonObject::node_type *JsonObject::getOrCreateNodeAt(JsonObjectKey key) {
|
||||
node_type *existingNode = getNodeAt(key);
|
||||
if (existingNode) return existingNode;
|
||||
|
||||
node_type *newNode = addNewNode();
|
||||
return newNode;
|
||||
}
|
||||
|
||||
template <typename TKey>
|
||||
JsonArray &JsonObject::createArrayAt(TKey key) {
|
||||
if (!_buffer) return JsonArray::invalid();
|
||||
JsonArray &array = _buffer->createArray();
|
||||
setNodeAt<TKey, const JsonVariant &>(key, array);
|
||||
return array;
|
||||
}
|
||||
template JsonArray &JsonObject::createArrayAt<const char *>(const char *);
|
||||
template JsonArray &JsonObject::createArrayAt<const String &>(const String &);
|
||||
|
||||
template <typename TKey>
|
||||
JsonObject &JsonObject::createObjectAt(TKey key) {
|
||||
if (!_buffer) return JsonObject::invalid();
|
||||
JsonObject &array = _buffer->createObject();
|
||||
setNodeAt<TKey, const JsonVariant &>(key, array);
|
||||
return array;
|
||||
}
|
||||
template JsonObject &JsonObject::createObjectAt<const char *>(const char *);
|
||||
template JsonObject &JsonObject::createObjectAt<const String &>(const String &);
|
||||
|
||||
JsonObject::node_type *JsonObject::getNodeAt(JsonObjectKey key) const {
|
||||
JsonObject::node_type *JsonObject::getNodeAt(const char *key) const {
|
||||
for (node_type *node = _firstNode; node; node = node->next) {
|
||||
if (!strcmp(node->content.key, key)) return node;
|
||||
}
|
||||
|
@ -17,31 +17,7 @@ using namespace ArduinoJson::Internals;
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
template <typename TFloat>
|
||||
static TFloat parse(const char *);
|
||||
|
||||
template <>
|
||||
float parse<float>(const char *s) {
|
||||
return static_cast<float>(strtod(s, NULL));
|
||||
}
|
||||
|
||||
template <>
|
||||
double parse<double>(const char *s) {
|
||||
return strtod(s, NULL);
|
||||
}
|
||||
|
||||
template <>
|
||||
long parse<long>(const char *s) {
|
||||
return strtol(s, NULL, 10);
|
||||
}
|
||||
|
||||
template <>
|
||||
int parse<int>(const char *s) {
|
||||
return atoi(s);
|
||||
}
|
||||
|
||||
template <>
|
||||
const char *JsonVariant::as<const char *>() const {
|
||||
const char *JsonVariant::asString() const {
|
||||
if (_type == JSON_UNPARSED && _content.asString &&
|
||||
!strcmp("null", _content.asString))
|
||||
return NULL;
|
||||
@ -50,33 +26,23 @@ const char *JsonVariant::as<const char *>() const {
|
||||
}
|
||||
|
||||
JsonFloat JsonVariant::asFloat() const {
|
||||
if (_type >= JSON_FLOAT_0_DECIMALS) return _content.asFloat;
|
||||
|
||||
if (_type == JSON_INTEGER || _type == JSON_BOOLEAN)
|
||||
return static_cast<JsonFloat>(_content.asInteger);
|
||||
|
||||
if ((_type == JSON_STRING || _type == JSON_UNPARSED) && _content.asString)
|
||||
return parse<JsonFloat>(_content.asString);
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
JsonInteger JsonVariant::asInteger() const {
|
||||
if (_type == JSON_INTEGER || _type == JSON_BOOLEAN) return _content.asInteger;
|
||||
|
||||
if (_type >= JSON_FLOAT_0_DECIMALS)
|
||||
return static_cast<JsonInteger>(_content.asFloat);
|
||||
|
||||
if ((_type == JSON_STRING || _type == JSON_UNPARSED) && _content.asString) {
|
||||
if (!strcmp("true", _content.asString)) return 1;
|
||||
return parse<JsonInteger>(_content.asString);
|
||||
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;
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
template <>
|
||||
String JsonVariant::as<String>() const {
|
||||
String JsonVariant::toString() const {
|
||||
String s;
|
||||
if ((_type == JSON_STRING || _type == JSON_UNPARSED) &&
|
||||
_content.asString != NULL)
|
||||
@ -86,8 +52,7 @@ String JsonVariant::as<String>() const {
|
||||
return s;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool JsonVariant::is<bool>() const {
|
||||
bool JsonVariant::isBoolean() const {
|
||||
if (_type == JSON_BOOLEAN) return true;
|
||||
|
||||
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
|
||||
@ -96,9 +61,9 @@ bool JsonVariant::is<bool>() const {
|
||||
!strcmp(_content.asString, "false");
|
||||
}
|
||||
|
||||
template <>
|
||||
bool JsonVariant::is<signed long>() const {
|
||||
if (_type == JSON_INTEGER) return true;
|
||||
bool JsonVariant::isInteger() const {
|
||||
if (_type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER)
|
||||
return true;
|
||||
|
||||
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
|
||||
|
||||
@ -109,8 +74,7 @@ bool JsonVariant::is<signed long>() const {
|
||||
return *end == '\0' && errno == 0;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool JsonVariant::is<double>() const {
|
||||
bool JsonVariant::isFloat() const {
|
||||
if (_type >= JSON_FLOAT_0_DECIMALS) return true;
|
||||
|
||||
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
|
||||
@ -123,27 +87,39 @@ bool JsonVariant::is<double>() const {
|
||||
}
|
||||
|
||||
void JsonVariant::writeTo(JsonWriter &writer) const {
|
||||
if (_type == JSON_ARRAY)
|
||||
_content.asArray->writeTo(writer);
|
||||
switch (_type) {
|
||||
case JSON_UNDEFINED:
|
||||
return;
|
||||
|
||||
else if (_type == JSON_OBJECT)
|
||||
_content.asObject->writeTo(writer);
|
||||
case JSON_ARRAY:
|
||||
_content.asArray->writeTo(writer);
|
||||
return;
|
||||
|
||||
else if (_type == JSON_STRING)
|
||||
writer.writeString(_content.asString);
|
||||
case JSON_OBJECT:
|
||||
_content.asObject->writeTo(writer);
|
||||
return;
|
||||
|
||||
else if (_type == JSON_UNPARSED)
|
||||
writer.writeRaw(_content.asString);
|
||||
case JSON_STRING:
|
||||
writer.writeString(_content.asString);
|
||||
return;
|
||||
|
||||
else if (_type == JSON_INTEGER)
|
||||
writer.writeInteger(_content.asInteger);
|
||||
case JSON_UNPARSED:
|
||||
writer.writeRaw(_content.asString);
|
||||
return;
|
||||
|
||||
else if (_type == JSON_BOOLEAN)
|
||||
writer.writeBoolean(_content.asInteger != 0);
|
||||
case JSON_NEGATIVE_INTEGER:
|
||||
writer.writeRaw('-');
|
||||
case JSON_POSITIVE_INTEGER:
|
||||
writer.writeInteger(_content.asInteger);
|
||||
return;
|
||||
|
||||
else if (_type >= JSON_FLOAT_0_DECIMALS) {
|
||||
uint8_t decimals = static_cast<uint8_t>(_type - JSON_FLOAT_0_DECIMALS);
|
||||
writer.writeFloat(_content.asFloat, decimals);
|
||||
case JSON_BOOLEAN:
|
||||
writer.writeBoolean(_content.asInteger != 0);
|
||||
return;
|
||||
|
||||
default:
|
||||
uint8_t decimals = static_cast<uint8_t>(_type - JSON_FLOAT_0_DECIMALS);
|
||||
writer.writeFloat(_content.asFloat, decimals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,3 +219,27 @@ TEST_F(ArduinoStringTests, JsonObject_PrettyPrintTo) {
|
||||
object.prettyPrintTo(json);
|
||||
ASSERT_EQ(String("{\r\n \"key\": \"value\"\r\n}"), json);
|
||||
}
|
||||
|
||||
TEST_F(ArduinoStringTests, JsonBuffer_GrowWhenAddingNewKey) {
|
||||
JsonObject &object = _jsonBuffer.createObject();
|
||||
String key1("hello"), key2("world");
|
||||
|
||||
object[key1] = 1;
|
||||
size_t sizeBefore = _jsonBuffer.size();
|
||||
object[key2] = 2;
|
||||
size_t sizeAfter = _jsonBuffer.size();
|
||||
|
||||
ASSERT_GT(sizeAfter - sizeBefore, key2.size());
|
||||
}
|
||||
|
||||
TEST_F(ArduinoStringTests, JsonBuffer_DontGrowWhenReusingKey) {
|
||||
JsonObject &object = _jsonBuffer.createObject();
|
||||
String key("hello");
|
||||
|
||||
object[key] = 1;
|
||||
size_t sizeBefore = _jsonBuffer.size();
|
||||
object[key] = 2;
|
||||
size_t sizeAfter = _jsonBuffer.size();
|
||||
|
||||
ASSERT_EQ(sizeBefore, sizeAfter);
|
||||
}
|
||||
|
@ -17,7 +17,11 @@ add_definitions(-DGTEST_HAS_PTHREAD=0)
|
||||
|
||||
# Workaround for Visual Studio 2012
|
||||
if (MSVC AND MSVC_VERSION EQUAL 1700)
|
||||
add_definitions(-D_VARIADIC_MAX=10)
|
||||
add_definitions(-D_VARIADIC_MAX=10)
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
add_executable(ArduinoJsonTests
|
||||
@ -25,6 +29,7 @@ add_executable(ArduinoJsonTests
|
||||
${GTEST_DIR}/src/gtest-all.cc
|
||||
${GTEST_DIR}/src/gtest_main.cc)
|
||||
|
||||
|
||||
target_link_libraries(ArduinoJsonTests ArduinoJson)
|
||||
|
||||
add_test(ArduinoJsonTests ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/ArduinoJsonTests)
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class GbathreeBug : public testing::Test {
|
||||
|
@ -1,48 +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 <gtest/gtest.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class Issue67 : public testing::Test {
|
||||
public:
|
||||
void whenInputIs(double value) { _variant = value; }
|
||||
|
||||
void outputMustBe(const char* expected) {
|
||||
char buffer[1024];
|
||||
_variant.printTo(buffer, sizeof(buffer));
|
||||
ASSERT_STREQ(expected, buffer);
|
||||
}
|
||||
|
||||
private:
|
||||
JsonVariant _variant;
|
||||
};
|
||||
|
||||
TEST_F(Issue67, BigPositiveDouble) {
|
||||
whenInputIs(1e100);
|
||||
outputMustBe("1e+100");
|
||||
}
|
||||
|
||||
TEST_F(Issue67, BigNegativeDouble) {
|
||||
whenInputIs(-1e100);
|
||||
outputMustBe("-1e+100");
|
||||
}
|
||||
|
||||
TEST_F(Issue67, Zero) {
|
||||
whenInputIs(0.0);
|
||||
outputMustBe("0.00");
|
||||
}
|
||||
|
||||
TEST_F(Issue67, SmallPositiveDouble) {
|
||||
whenInputIs(111.111);
|
||||
outputMustBe("111.11");
|
||||
}
|
||||
|
||||
TEST_F(Issue67, SmallNegativeDouble) {
|
||||
whenInputIs(-111.111);
|
||||
outputMustBe("-111.11");
|
||||
}
|
@ -7,18 +7,18 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <limits.h> // for LONG_MAX
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
|
||||
#define ARDUINOJSON_USE_LONG_LONG 0
|
||||
#define ARDUINOJSON_USE_INT64 0
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#define SUITE Issue90
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
static const char* superLong =
|
||||
"12345678901234567890123456789012345678901234567890123456789012345678901234"
|
||||
"5678901234567890123456789012345678901234567890123456789012345678901234567";
|
||||
|
||||
static const JsonVariant variant = Unparsed(superLong);
|
||||
static const JsonVariant variant = RawJson(superLong);
|
||||
|
||||
TEST(SUITE, IsNotALong) { ASSERT_FALSE(variant.is<long>()); }
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonArray_Add_Tests : public ::testing::Test {
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#define TEST_(name) TEST(JsonArray_Basic_Tests, name)
|
||||
|
64
test/JsonArray_CopyFrom_Tests.cpp
Normal file
64
test/JsonArray_CopyFrom_Tests.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
// 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 <gtest/gtest.h>
|
||||
|
||||
TEST(JsonArray_CopyFrom_Tests, OneDimension) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonArray& array = jsonBuffer.createArray();
|
||||
char json[32];
|
||||
int source[] = {1, 2, 3};
|
||||
|
||||
bool ok = array.copyFrom(source);
|
||||
ASSERT_TRUE(ok);
|
||||
|
||||
array.printTo(json, sizeof(json));
|
||||
ASSERT_STREQ("[1,2,3]", json);
|
||||
}
|
||||
|
||||
TEST(JsonArray_CopyFrom_Tests, OneDimension_JsonBufferTooSmall) {
|
||||
const size_t SIZE = JSON_ARRAY_SIZE(2);
|
||||
StaticJsonBuffer<SIZE> jsonBuffer;
|
||||
JsonArray& array = jsonBuffer.createArray();
|
||||
char json[32];
|
||||
int source[] = {1, 2, 3};
|
||||
|
||||
bool ok = array.copyFrom(source);
|
||||
ASSERT_FALSE(ok);
|
||||
|
||||
array.printTo(json, sizeof(json));
|
||||
ASSERT_STREQ("[1,2]", json);
|
||||
}
|
||||
|
||||
TEST(JsonArray_CopyFrom_Tests, TwoDimensions) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonArray& array = jsonBuffer.createArray();
|
||||
char json[32];
|
||||
int source[][3] = {{1, 2, 3}, {4, 5, 6}};
|
||||
|
||||
bool ok = array.copyFrom(source);
|
||||
ASSERT_TRUE(ok);
|
||||
|
||||
array.printTo(json, sizeof(json));
|
||||
ASSERT_STREQ("[[1,2,3],[4,5,6]]", json);
|
||||
}
|
||||
|
||||
TEST(JsonArray_CopyFrom_Tests, TwoDimensions_JsonBufferTooSmall) {
|
||||
const size_t SIZE =
|
||||
JSON_ARRAY_SIZE(2) + JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(2);
|
||||
StaticJsonBuffer<SIZE> jsonBuffer;
|
||||
JsonArray& array = jsonBuffer.createArray();
|
||||
char json[32];
|
||||
int source[][3] = {{1, 2, 3}, {4, 5, 6}};
|
||||
|
||||
bool ok = array.copyFrom(source);
|
||||
ASSERT_FALSE(ok);
|
||||
|
||||
array.printTo(json, sizeof(json));
|
||||
ASSERT_STREQ("[[1,2,3],[4,5]]", json);
|
||||
}
|
56
test/JsonArray_CopyTo_Tests.cpp
Normal file
56
test/JsonArray_CopyTo_Tests.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
// 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 <gtest/gtest.h>
|
||||
|
||||
TEST(JsonArray_CopyTo_Tests, BiggerOneDimensionIntegerArray) {
|
||||
char json[] = "[1,2,3]";
|
||||
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonArray& array = jsonBuffer.parseArray(json);
|
||||
|
||||
int destination[4] = {0};
|
||||
size_t result = array.copyTo(destination);
|
||||
|
||||
ASSERT_EQ(3, result);
|
||||
ASSERT_EQ(1, destination[0]);
|
||||
ASSERT_EQ(2, destination[1]);
|
||||
ASSERT_EQ(3, destination[2]);
|
||||
ASSERT_EQ(0, destination[3]);
|
||||
}
|
||||
|
||||
TEST(JsonArray_CopyTo_Tests, SmallerOneDimensionIntegerArray) {
|
||||
char json[] = "[1,2,3]";
|
||||
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonArray& array = jsonBuffer.parseArray(json);
|
||||
|
||||
int destination[2] = {0};
|
||||
size_t result = array.copyTo(destination);
|
||||
|
||||
ASSERT_EQ(2, result);
|
||||
ASSERT_EQ(1, destination[0]);
|
||||
ASSERT_EQ(2, destination[1]);
|
||||
}
|
||||
|
||||
TEST(JsonArray_CopyTo_Tests, TwoOneDimensionIntegerArray) {
|
||||
char json[] = "[[1,2],[3],[4]]";
|
||||
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
JsonArray& array = jsonBuffer.parseArray(json);
|
||||
|
||||
int destination[3][2] = {0};
|
||||
array.copyTo(destination);
|
||||
|
||||
ASSERT_EQ(1, destination[0][0]);
|
||||
ASSERT_EQ(2, destination[0][1]);
|
||||
ASSERT_EQ(3, destination[1][0]);
|
||||
ASSERT_EQ(0, destination[1][1]);
|
||||
ASSERT_EQ(4, destination[2][0]);
|
||||
ASSERT_EQ(0, destination[2][1]);
|
||||
}
|
@ -64,10 +64,25 @@ TEST_F(JsonArray_PrintTo_Tests, OneDoubleDefaultDigits) {
|
||||
}
|
||||
|
||||
TEST_F(JsonArray_PrintTo_Tests, OneDoubleFourDigits) {
|
||||
array.add(3.14159265358979323846, 4);
|
||||
outputMustBe("[3.1416]");
|
||||
}
|
||||
|
||||
TEST_F(JsonArray_PrintTo_Tests, OneDoubleFourDigits_AlternativeSyntax) {
|
||||
array.add(double_with_n_digits(3.14159265358979323846, 4));
|
||||
outputMustBe("[3.1416]");
|
||||
}
|
||||
|
||||
TEST_F(JsonArray_PrintTo_Tests, OneFloatDefaultDigits) {
|
||||
array.add(3.14159f);
|
||||
outputMustBe("[3.14]");
|
||||
}
|
||||
|
||||
TEST_F(JsonArray_PrintTo_Tests, OneFloatFourDigits) {
|
||||
array.add(3.14159f, 4);
|
||||
outputMustBe("[3.1416]");
|
||||
}
|
||||
|
||||
TEST_F(JsonArray_PrintTo_Tests, OneInteger) {
|
||||
array.add(1);
|
||||
|
||||
@ -81,6 +96,12 @@ TEST_F(JsonArray_PrintTo_Tests, TwoIntegers) {
|
||||
outputMustBe("[1,2]");
|
||||
}
|
||||
|
||||
TEST_F(JsonArray_PrintTo_Tests, RawJson) {
|
||||
array.add(RawJson("{\"key\":\"value\"}"));
|
||||
|
||||
outputMustBe("[{\"key\":\"value\"}]");
|
||||
}
|
||||
|
||||
TEST_F(JsonArray_PrintTo_Tests, OneIntegerOverCapacity) {
|
||||
array.add(1);
|
||||
array.add(2);
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonArray_Set_Tests : public ::testing::Test {
|
||||
|
@ -5,9 +5,9 @@
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdint.h>
|
||||
|
||||
class JsonArray_Subscript_Tests : public ::testing::Test {
|
||||
protected:
|
||||
@ -33,6 +33,15 @@ TEST_(StoreInteger) {
|
||||
EXPECT_FALSE(_array[0].is<double>());
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
TEST_(StoreLongLong) {
|
||||
_array[0] = 9223372036854775807;
|
||||
EXPECT_EQ(9223372036854775807, _array[0].as<long long>());
|
||||
EXPECT_TRUE(_array[0].is<int>());
|
||||
EXPECT_FALSE(_array[0].is<double>());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_(StoreDouble) {
|
||||
_array[0] = 123.45;
|
||||
EXPECT_EQ(123.45, _array[0].as<double>());
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonObject_Iterator_Test : public testing::Test {
|
||||
|
@ -5,10 +5,8 @@
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
class JsonObject_PrintTo_Tests : public testing::Test {
|
||||
public:
|
||||
@ -75,10 +73,17 @@ TEST_F(JsonObject_PrintTo_Tests, TwoIntegers) {
|
||||
outputMustBe("{\"a\":1,\"b\":2}");
|
||||
}
|
||||
|
||||
TEST_F(JsonObject_PrintTo_Tests, RawJson) {
|
||||
_object["a"] = RawJson("[1,2]");
|
||||
_object.set("b", RawJson("[4,5]"));
|
||||
outputMustBe("{\"a\":[1,2],\"b\":[4,5]}");
|
||||
}
|
||||
|
||||
TEST_F(JsonObject_PrintTo_Tests, TwoDoublesFourDigits) {
|
||||
_object["a"] = double_with_n_digits(3.14159265358979323846, 4);
|
||||
_object.set("b", 2.71828182845904523536, 4);
|
||||
outputMustBe("{\"a\":3.1416,\"b\":2.7183}");
|
||||
_object.set("c", double_with_n_digits(3.14159265358979323846, 3));
|
||||
outputMustBe("{\"a\":3.1416,\"b\":2.7183,\"c\":3.142}");
|
||||
}
|
||||
|
||||
TEST_F(JsonObject_PrintTo_Tests, TwoDoubleDefaultDigits) {
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonObject_Set_Tests : public ::testing::Test {
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonObject_Subscript_Tests : public ::testing::Test {
|
||||
|
@ -125,6 +125,14 @@ TEST_F(JsonParser_Array_Tests, TwoDoubles) {
|
||||
secondElementMustBe(1e2);
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Array_Tests, UnsignedLong) {
|
||||
whenInputIs("[4294967295]");
|
||||
|
||||
parseMustSucceed();
|
||||
sizeMustBe(1);
|
||||
firstElementMustBe(4294967295UL);
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Array_Tests, TwoBooleans) {
|
||||
whenInputIs("[true,false]");
|
||||
|
||||
|
91
test/JsonParser_Variant_Tests.cpp
Normal file
91
test/JsonParser_Variant_Tests.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
// 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 <gtest/gtest.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonParser_Variant_Test : public testing::Test {
|
||||
protected:
|
||||
void whenInputIs(const char* jsonString) {
|
||||
strcpy(_jsonString, jsonString);
|
||||
_result = _jsonBuffer.parse(_jsonString);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void resultMustEqual(T expected) {
|
||||
EXPECT_EQ(expected, _result.as<T>());
|
||||
}
|
||||
|
||||
void resultMustEqual(const char* expected) {
|
||||
EXPECT_STREQ(expected, _result.as<char*>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void resultTypeMustBe() {
|
||||
EXPECT_TRUE(_result.is<T>());
|
||||
}
|
||||
|
||||
void resultMustBeInvalid() { EXPECT_FALSE(_result.success()); }
|
||||
void resultMustBeValid() { EXPECT_TRUE(_result.success()); }
|
||||
|
||||
private:
|
||||
DynamicJsonBuffer _jsonBuffer;
|
||||
JsonVariant _result;
|
||||
char _jsonString[256];
|
||||
};
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, EmptyObject) {
|
||||
whenInputIs("{}");
|
||||
resultMustBeValid();
|
||||
resultTypeMustBe<JsonObject>();
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, EmptyArray) {
|
||||
whenInputIs("[]");
|
||||
resultMustBeValid();
|
||||
resultTypeMustBe<JsonArray>();
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, Integer) {
|
||||
whenInputIs("42");
|
||||
resultMustBeValid();
|
||||
resultTypeMustBe<int>();
|
||||
resultMustEqual(42);
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, Double) {
|
||||
whenInputIs("3.14");
|
||||
resultMustBeValid();
|
||||
resultTypeMustBe<double>();
|
||||
resultMustEqual(3.14);
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, String) {
|
||||
whenInputIs("\"hello world\"");
|
||||
resultMustBeValid();
|
||||
resultTypeMustBe<char*>();
|
||||
resultMustEqual("hello world");
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, True) {
|
||||
whenInputIs("true");
|
||||
resultMustBeValid();
|
||||
resultTypeMustBe<bool>();
|
||||
resultMustEqual(true);
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, False) {
|
||||
whenInputIs("false");
|
||||
resultMustBeValid();
|
||||
resultTypeMustBe<bool>();
|
||||
resultMustEqual(false);
|
||||
}
|
||||
|
||||
TEST_F(JsonParser_Variant_Test, Invalid) {
|
||||
whenInputIs("{");
|
||||
resultMustBeInvalid();
|
||||
}
|
@ -5,10 +5,11 @@
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static const char* null = 0;
|
||||
|
||||
TEST(JsonVariant_As_Tests, DoubleAsBool) {
|
||||
@ -31,6 +32,11 @@ TEST(JsonVariant_As_Tests, DoubleAsLong) {
|
||||
ASSERT_EQ(4L, variant.as<long>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, DoubleAsUnsigned) {
|
||||
JsonVariant variant = 4.2;
|
||||
ASSERT_EQ(4U, variant.as<unsigned>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, DoubleZeroAsBool) {
|
||||
JsonVariant variant = 0.0;
|
||||
ASSERT_FALSE(variant.as<bool>());
|
||||
@ -91,11 +97,16 @@ TEST(JsonVariant_As_Tests, LongZeroAsBool) {
|
||||
ASSERT_FALSE(variant.as<bool>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, LongAsDouble) {
|
||||
TEST(JsonVariant_As_Tests, PositiveLongAsDouble) {
|
||||
JsonVariant variant = 42L;
|
||||
ASSERT_EQ(42.0, variant.as<double>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, NegativeLongAsDouble) {
|
||||
JsonVariant variant = -42L;
|
||||
ASSERT_EQ(-42.0, variant.as<double>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, LongAsString) {
|
||||
JsonVariant variant = 42L;
|
||||
ASSERT_EQ(String("42"), variant.as<String>());
|
||||
@ -136,6 +147,18 @@ TEST(JsonVariant_As_Tests, NumberStringAsLong) {
|
||||
ASSERT_EQ(42L, variant.as<long>());
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
TEST(JsonVariant_As_Tests, NumberStringAsInt64Negative) {
|
||||
JsonVariant variant = "-9223372036854775808";
|
||||
ASSERT_EQ(-9223372036854775807 - 1, variant.as<long long>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, NumberStringAsInt64Positive) {
|
||||
JsonVariant variant = "9223372036854775807";
|
||||
ASSERT_EQ(9223372036854775807, variant.as<long long>());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(JsonVariant_As_Tests, RandomStringAsBool) {
|
||||
JsonVariant variant = "hello";
|
||||
ASSERT_FALSE(variant.as<bool>());
|
||||
@ -146,6 +169,16 @@ TEST(JsonVariant_As_Tests, RandomStringAsLong) {
|
||||
ASSERT_EQ(0L, variant.as<long>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, RandomStringAsConstCharPtr) {
|
||||
JsonVariant variant = "hello";
|
||||
ASSERT_STREQ("hello", variant.as<const char*>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, RandomStringAsCharPtr) {
|
||||
JsonVariant variant = "hello";
|
||||
ASSERT_STREQ("hello", variant.as<char*>());
|
||||
}
|
||||
|
||||
TEST(JsonVariant_As_Tests, RandomStringAsString) {
|
||||
JsonVariant variant = "hello";
|
||||
ASSERT_EQ(String("hello"), variant.as<String>());
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson/JsonVariant.hpp>
|
||||
|
||||
using namespace ArduinoJson;
|
||||
|
@ -6,13 +6,10 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
#define SUITE JsonVariant_Is_Tests
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
template <typename TTo, typename TFrom>
|
||||
void assertIsNot(TFrom value) {
|
||||
JsonVariant variant = value;
|
||||
@ -77,37 +74,35 @@ TEST(SUITE, StringIsInt) { assertIsNot<int>("42"); }
|
||||
TEST(SUITE, StringIsLong) { assertIsNot<long>("42"); }
|
||||
TEST(SUITE, StringIsString) { assertIs<const char*>("42"); }
|
||||
|
||||
TEST(SUITE, UnparsedTrueIsArra) { assertIsNot<JsonArray&>(Unparsed("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsBool) { assertIs<bool>(Unparsed("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsDouble) { assertIsNot<double>(Unparsed("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsFloat) { assertIsNot<float>(Unparsed("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsInt) { assertIsNot<int>(Unparsed("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsLong) { assertIsNot<long>(Unparsed("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsString) {
|
||||
assertIsNot<const char*>(Unparsed("true"));
|
||||
}
|
||||
TEST(SUITE, UnparsedTrueIsArra) { assertIsNot<JsonArray&>(RawJson("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsBool) { assertIs<bool>(RawJson("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsDouble) { assertIsNot<double>(RawJson("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsFloat) { assertIsNot<float>(RawJson("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsInt) { assertIsNot<int>(RawJson("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsLong) { assertIsNot<long>(RawJson("true")); }
|
||||
TEST(SUITE, UnparsedTrueIsString) { assertIsNot<const char*>(RawJson("true")); }
|
||||
|
||||
TEST(SUITE, UnparsedFalseIsArra) { assertIsNot<JsonArray&>(Unparsed("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsBool) { assertIs<bool>(Unparsed("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsDouble) { assertIsNot<double>(Unparsed("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsFloat) { assertIsNot<float>(Unparsed("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsInt) { assertIsNot<int>(Unparsed("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsLong) { assertIsNot<long>(Unparsed("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsArra) { assertIsNot<JsonArray&>(RawJson("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsBool) { assertIs<bool>(RawJson("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsDouble) { assertIsNot<double>(RawJson("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsFloat) { assertIsNot<float>(RawJson("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsInt) { assertIsNot<int>(RawJson("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsLong) { assertIsNot<long>(RawJson("false")); }
|
||||
TEST(SUITE, UnparsedFalseIsString) {
|
||||
assertIsNot<const char*>(Unparsed("false"));
|
||||
assertIsNot<const char*>(RawJson("false"));
|
||||
}
|
||||
|
||||
TEST(SUITE, UnparsedIntIsArra) { assertIsNot<JsonArray&>(Unparsed("42")); }
|
||||
TEST(SUITE, UnparsedIntIsBool) { assertIsNot<bool>(Unparsed("42")); }
|
||||
TEST(SUITE, UnparsedIntIsDouble) { assertIsNot<double>(Unparsed("42")); }
|
||||
TEST(SUITE, UnparsedIntIsFloat) { assertIsNot<float>(Unparsed("42")); }
|
||||
TEST(SUITE, UnparsedIntIsInt) { assertIs<int>(Unparsed("42")); }
|
||||
TEST(SUITE, UnparsedIntIsLong) { assertIs<long>(Unparsed("42")); }
|
||||
TEST(SUITE, UnparsedIntIsString) { assertIsNot<const char*>(Unparsed("42")); }
|
||||
TEST(SUITE, UnparsedIntIsArra) { assertIsNot<JsonArray&>(RawJson("42")); }
|
||||
TEST(SUITE, UnparsedIntIsBool) { assertIsNot<bool>(RawJson("42")); }
|
||||
TEST(SUITE, UnparsedIntIsDouble) { assertIsNot<double>(RawJson("42")); }
|
||||
TEST(SUITE, UnparsedIntIsFloat) { assertIsNot<float>(RawJson("42")); }
|
||||
TEST(SUITE, UnparsedIntIsInt) { assertIs<int>(RawJson("42")); }
|
||||
TEST(SUITE, UnparsedIntIsLong) { assertIs<long>(RawJson("42")); }
|
||||
TEST(SUITE, UnparsedIntIsString) { assertIsNot<const char*>(RawJson("42")); }
|
||||
|
||||
TEST(SUITE, UnparsedFloatIsBool) { assertIsNot<bool>(Unparsed("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsDouble) { assertIs<double>(Unparsed("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsFloat) { assertIs<float>(Unparsed("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsInt) { assertIsNot<int>(Unparsed("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsLong) { assertIsNot<long>(Unparsed("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsStr) { assertIsNot<const char*>(Unparsed("4.2")); }
|
||||
TEST(SUITE, UnparsedFloatIsBool) { assertIsNot<bool>(RawJson("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsDouble) { assertIs<double>(RawJson("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsFloat) { assertIs<float>(RawJson("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsInt) { assertIsNot<int>(RawJson("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsLong) { assertIsNot<long>(RawJson("4.2e-10")); }
|
||||
TEST(SUITE, UnparsedFloatIsStr) { assertIsNot<const char*>(RawJson("4.2")); }
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <ArduinoJson.h>
|
||||
#include <limits>
|
||||
|
||||
class JsonVariant_PrintTo_Tests : public testing::Test {
|
||||
protected:
|
||||
@ -15,8 +16,8 @@ class JsonVariant_PrintTo_Tests : public testing::Test {
|
||||
void outputMustBe(const char *expected) {
|
||||
char buffer[256] = "";
|
||||
size_t n = variant.printTo(buffer, sizeof(buffer));
|
||||
EXPECT_STREQ(expected, buffer);
|
||||
EXPECT_EQ(strlen(expected), n);
|
||||
ASSERT_STREQ(expected, buffer);
|
||||
ASSERT_EQ(strlen(expected), n);
|
||||
}
|
||||
};
|
||||
|
||||
@ -47,19 +48,59 @@ TEST_F(JsonVariant_PrintTo_Tests, DoubleFourDigits) {
|
||||
outputMustBe("3.1416");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, Infinity) {
|
||||
variant = std::numeric_limits<double>::infinity();
|
||||
outputMustBe("Infinity");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, MinusInfinity) {
|
||||
variant = -std::numeric_limits<double>::infinity();
|
||||
outputMustBe("-Infinity");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, SignalingNaN) {
|
||||
variant = std::numeric_limits<double>::signaling_NaN();
|
||||
outputMustBe("NaN");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, QuietNaN) {
|
||||
variant = std::numeric_limits<double>::quiet_NaN();
|
||||
outputMustBe("NaN");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, VeryBigPositiveDouble) {
|
||||
variant = JsonVariant(3.14159265358979323846e42, 4);
|
||||
outputMustBe("3.1416e42");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, VeryBigNegativeDouble) {
|
||||
variant = JsonVariant(-3.14159265358979323846e42, 4);
|
||||
outputMustBe("-3.1416e42");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, VerySmallPositiveDouble) {
|
||||
variant = JsonVariant(3.14159265358979323846e-42, 4);
|
||||
outputMustBe("3.1416e-42");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, VerySmallNegativeDouble) {
|
||||
variant = JsonVariant(-3.14159265358979323846e-42, 4);
|
||||
outputMustBe("-3.1416e-42");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, Integer) {
|
||||
variant = 42;
|
||||
outputMustBe("42");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, Long) {
|
||||
variant = 42L;
|
||||
outputMustBe("42");
|
||||
TEST_F(JsonVariant_PrintTo_Tests, NegativeLong) {
|
||||
variant = -42;
|
||||
outputMustBe("-42");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, Char) {
|
||||
variant = '*';
|
||||
outputMustBe("42");
|
||||
TEST_F(JsonVariant_PrintTo_Tests, UnsignedLong) {
|
||||
variant = 4294967295UL;
|
||||
outputMustBe("4294967295");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, True) {
|
||||
@ -71,3 +112,20 @@ TEST_F(JsonVariant_PrintTo_Tests, OneFalse) {
|
||||
variant = false;
|
||||
outputMustBe("false");
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
TEST_F(JsonVariant_PrintTo_Tests, NegativeInt64) {
|
||||
variant = -9223372036854775807 - 1;
|
||||
outputMustBe("-9223372036854775808");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, PositiveInt64) {
|
||||
variant = 9223372036854775807;
|
||||
outputMustBe("9223372036854775807");
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_PrintTo_Tests, UInt64) {
|
||||
variant = 18446744073709551615;
|
||||
outputMustBe("18446744073709551615");
|
||||
}
|
||||
#endif
|
||||
|
@ -6,40 +6,74 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <stdint.h>
|
||||
#include <limits>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonVariant_Storage_Tests : public ::testing::Test {
|
||||
protected:
|
||||
template <typename T>
|
||||
void testValue(T expected) {
|
||||
_actual = expected;
|
||||
EXPECT_EQ(expected, _actual.as<T>());
|
||||
JsonVariant variant = expected;
|
||||
EXPECT_EQ(expected, variant.as<T>());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void testReference(T &expected) {
|
||||
_actual = expected;
|
||||
EXPECT_EQ(expected, _actual.as<T &>());
|
||||
JsonVariant variant = expected;
|
||||
EXPECT_EQ(expected, variant.as<T &>());
|
||||
}
|
||||
|
||||
private:
|
||||
JsonVariant _actual;
|
||||
template <typename T>
|
||||
void testNumericType() {
|
||||
T min = std::numeric_limits<T>::min();
|
||||
T max = std::numeric_limits<T>::max();
|
||||
|
||||
JsonVariant variantMin(min);
|
||||
JsonVariant variantMax(max);
|
||||
|
||||
EXPECT_EQ(min, variantMin.as<T>());
|
||||
EXPECT_EQ(max, variantMax.as<T>());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(JsonVariant_Storage_Tests, Double) { testValue<double>(123.45); }
|
||||
TEST_F(JsonVariant_Storage_Tests, False) { testValue<bool>(false); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Float) { testValue<float>(123.45f); }
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
TEST_F(JsonVariant_Storage_Tests, SizeOfJsonInteger) {
|
||||
ASSERT_EQ(8, sizeof(Internals::JsonInteger));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_F(JsonVariant_Storage_Tests, Null) { testValue<const char *>(NULL); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SChar) { testValue<signed char>(123); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SInt) { testValue<signed int>(123); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SLong) { testValue<signed long>(123L); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SShort) { testValue<signed short>(123); }
|
||||
TEST_F(JsonVariant_Storage_Tests, String) { testValue<const char *>("hello"); }
|
||||
|
||||
TEST_F(JsonVariant_Storage_Tests, False) { testValue<bool>(false); }
|
||||
TEST_F(JsonVariant_Storage_Tests, True) { testValue<bool>(true); }
|
||||
TEST_F(JsonVariant_Storage_Tests, UChar) { testValue<unsigned char>(123); }
|
||||
TEST_F(JsonVariant_Storage_Tests, UInt) { testValue<unsigned int>(123U); }
|
||||
TEST_F(JsonVariant_Storage_Tests, ULong) { testValue<unsigned long>(123UL); }
|
||||
TEST_F(JsonVariant_Storage_Tests, UShort) { testValue<unsigned short>(123); }
|
||||
|
||||
TEST_F(JsonVariant_Storage_Tests, Double) { testNumericType<double>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Float) { testNumericType<float>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SChar) { testNumericType<signed char>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SInt) { testNumericType<signed int>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SLong) { testNumericType<signed long>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, SShort) { testNumericType<signed short>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, UChar) { testNumericType<unsigned char>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, UInt) { testNumericType<unsigned int>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, ULong) { testNumericType<unsigned long>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, UShort) { testNumericType<unsigned short>(); }
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
TEST_F(JsonVariant_Storage_Tests, LongLong) { testNumericType<unsigned long long>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, ULongLong) { testNumericType<unsigned long long>(); }
|
||||
#endif
|
||||
|
||||
TEST_F(JsonVariant_Storage_Tests, Int8) { testNumericType<int8_t>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Uint8) { testNumericType<uint8_t>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Int16) { testNumericType<int16_t>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Uint16) { testNumericType<uint16_t>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Int32) { testNumericType<int32_t>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Uint32) { testNumericType<uint32_t>(); }
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
TEST_F(JsonVariant_Storage_Tests, Int64) { testNumericType<int64_t>(); }
|
||||
TEST_F(JsonVariant_Storage_Tests, Uint64) { testNumericType<uint64_t>(); }
|
||||
#endif
|
||||
|
||||
TEST_F(JsonVariant_Storage_Tests, CanStoreObject) {
|
||||
DynamicJsonBuffer jsonBuffer;
|
||||
|
@ -6,7 +6,6 @@
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
class JsonVariant_Undefined_Tests : public ::testing::Test {
|
||||
@ -18,6 +17,10 @@ TEST_F(JsonVariant_Undefined_Tests, AsLongReturns0) {
|
||||
EXPECT_EQ(0, variant.as<long>());
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_Undefined_Tests, AsUnsignedReturns0) {
|
||||
EXPECT_EQ(0, variant.as<unsigned>());
|
||||
}
|
||||
|
||||
TEST_F(JsonVariant_Undefined_Tests, AsStringReturnsNull) {
|
||||
EXPECT_EQ(0, variant.asString());
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <sstream>
|
||||
#include <gtest/gtest.h>
|
||||
#define ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
TEST(StdStream, JsonVariantFalse) {
|
||||
|
@ -5,8 +5,8 @@
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
// If you like this project, please add a star!
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <ArduinoJson/Internals/StaticStringBuilder.hpp>
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
|
Reference in New Issue
Block a user