Compare commits

..

51 Commits

Author SHA1 Message Date
0588e578d5 Set version to 6.10.1 2019-04-23 08:47:54 +02:00
12f9aac4ea Fixed "no matching function for call to write(uint8_t)" (closes #972) 2019-04-23 08:46:18 +02:00
81bb3fce97 Fixed build on platformio 2019-04-21 14:35:23 +02:00
6011a2f51a Fixed deserializeJson() not being picky enough (fixes #969) 2019-04-21 14:35:13 +02:00
6071bd07ec Added a link to the FAQ 2019-04-20 12:10:29 +02:00
1c814d3bb6 Fixed warning on Clang 8 2019-03-24 19:39:23 +01:00
9862048a58 Fixed error "attributes are not allowed on a function-definition" 2019-03-24 19:00:23 +01:00
ebc52a5a65 Travis: Added Clang 8 2019-03-24 19:00:23 +01:00
eacad922df Travis: Added Clang 7 2019-03-24 19:00:23 +01:00
d910996613 Travis: Added GCC 8 2019-03-24 19:00:23 +01:00
2fc220fa33 Fixed code samples in the README 2019-03-24 18:21:58 +01:00
8cabda551d Fixed publish.sh not committing appveyor.yml 2019-03-22 22:04:03 +01:00
afd033e9c9 Set version to 6.10.0 2019-03-22 22:01:46 +01:00
6ec5ba521b Added JsonVariant::containsKey() 2019-03-22 21:58:12 +01:00
c8e49a7e4e Added JsonDocument::containsKey() (issue #938) 2019-03-22 08:40:46 +01:00
dee8c8e242 Added BasicJsonDocument to support custom allocator (issue #876) 2019-03-17 21:48:10 +01:00
576543c4b4 Added overflow handling in JsonVariant::as<T>() and JsonVariant::is<T>() 2019-03-06 15:31:37 +01:00
746f2882f7 Removed member call on null 2019-03-05 14:48:33 +01:00
c4cbf9d0bb Don't mark as a "system header" when debugging 2019-03-05 09:19:58 +01:00
49bd51b5f9 Updated version in AppVeyor 2019-03-04 12:21:58 +01:00
e53ae0f9bb Fixed the continuous integration 2019-03-04 12:18:11 +01:00
afdd913a2f Added links to the book page in each example 2019-03-04 12:17:41 +01:00
3df4efd512 Set version to 6.9.1 2019-03-01 18:16:45 +01:00
91dd45c387 Fixed naming conflict with "CAPACITY" (issue #839) 2019-03-01 18:14:23 +01:00
136ee0d576 Marked ArduinoJson.h as a "system header" 2019-03-01 17:31:55 +01:00
1ea8d92cc3 Muted warning "will change in GCC 7.1" (issue #914) 2019-03-01 12:12:47 +01:00
20fcb99830 Fixed warning "conversion may alter value" (issue #914) 2019-03-01 09:15:43 +01:00
f3265d2111 Fixed warning "cast-align" (issue #914) 2019-03-01 09:15:43 +01:00
d6e7709866 Travis: Add g++-arm-linux-gnueabihf 2019-03-01 09:15:43 +01:00
d11019d9e1 Travis: Split build and test scripts 2019-03-01 09:15:43 +01:00
cfd924622e Travis: Define CC and CXX in yaml 2019-03-01 09:15:41 +01:00
27c08b785d Travis: Assume CMake is installed 2019-02-28 17:33:24 +01:00
77f38e4449 Travis: restore build on GCC 4.4 2019-02-28 16:31:08 +01:00
16ddfbc4e0 Fixed strict-aliasing warning in FloatTraits.hpp 2019-02-28 15:37:42 +01:00
8dea900869 Travis: build in Release mode 2019-02-28 15:34:32 +01:00
f342dee2b4 Fixed warning "unused variable" with GCC 4.4 (issue #912) 2019-02-28 15:34:21 +01:00
1d5721f3bd Add an empty cpp file to detect warnings muted by catch.hpp 2019-02-28 15:32:29 +01:00
3170558d6d Added a clear error message for StaticJsonBuffer and DynamicJsonBuffer 2019-02-27 16:38:03 +01:00
3530aa88d6 Updated the examples on wandbox.org 2019-02-26 10:02:52 +01:00
21998890d4 Set version to 6.9.0 2019-02-26 08:43:45 +01:00
c9d6bd76c9 Added JsonDocument::remove() and JsonVariant::remove() 2019-02-25 13:21:10 +01:00
bc2ce178ea Added JsonVariant::clear() 2019-02-25 11:44:22 +01:00
e22e62d184 Added JsonDocument::size() 2019-02-25 11:07:01 +01:00
4181de119c Detect IncompleteInput in false, true, and null 2019-02-18 16:18:11 +01:00
56bf24e1ec Fixed JsonVariant::isNull() not returning true after set((char*)0) 2019-02-18 16:04:51 +01:00
e9b4c6289b Disambiguated the name get() with getElement() and getMember() 2019-02-15 15:53:53 +01:00
7ed92bebd3 Converted JsonArray::copyFrom()/copyTo() to free functions copyArray() 2019-02-15 15:33:04 +01:00
c3f71c1a99 Updated copyright year to 2019 2019-02-15 13:32:04 +01:00
7050ef675d Decode escaped Unicode characters like \u00DE (issue #304, PR #791) 2019-02-15 13:29:30 +01:00
070cd5b6c0 Added more tests of JsonVariant::is<T>() 2019-02-01 11:28:27 +01:00
2c2cc33c94 Updated version in Arduino Library badge 2019-01-30 16:42:21 +01:00
298 changed files with 3295 additions and 1592 deletions

View File

@ -2,122 +2,124 @@ sudo: false
language: cpp
matrix:
include:
- compiler: gcc
addons:
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.4']
env: SCRIPT=test _CC=gcc-4.4 _CXX=g++-4.4
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.6']
env: SCRIPT=cmake GCC=4.6
- compiler: gcc
addons:
env: SCRIPT=test _CC=gcc-4.6 _CXX=g++-4.6
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.7']
env: SCRIPT=cmake GCC=4.7
- compiler: gcc
addons:
env: SCRIPT=test _CC=gcc-4.7 _CXX=g++-4.7
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
env: SCRIPT=cmake GCC=4.8 SANITIZE=address
- compiler: gcc
addons:
env: SCRIPT=test _CC=gcc-4.8 _CXX=g++-4.8 SANITIZE=address
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9']
env: SCRIPT=cmake GCC=4.9 SANITIZE=leak
- compiler: gcc
addons:
env: SCRIPT=test _CC=gcc-4.9 _CXX=g++-4.9 SANITIZE=leak
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5']
env: SCRIPT=cmake GCC=5 # SANITIZE=undefined
- compiler: gcc
addons:
env: SCRIPT=test _CC=gcc-5 _CXX=g++-5 # SANITIZE=undefined
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-6']
env: SCRIPT=cmake GCC=6
- compiler: gcc
addons:
env: SCRIPT=test _CC=gcc-6 _CXX=g++-6
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-7']
env: SCRIPT=cmake GCC=7
- compiler: clang
env: SCRIPT=cmake
- compiler: clang
addons:
env: SCRIPT=test _CC=gcc-7 _CXX=g++-7
- addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-8']
env: SCRIPT=test _CC=gcc-8 _CXX=g++-8
- addons:
apt:
packages: ['g++-arm-linux-gnueabihf']
env: SCRIPT=build _CC=arm-linux-gnueabihf-gcc _CXX=arm-linux-gnueabihf-g++
- env: SCRIPT=test _CC=clang _CXX=clang++
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
packages: ['clang-3.5']
env: SCRIPT=cmake CLANG=3.5 SANITIZE=address
- compiler: clang
addons:
env: SCRIPT=test _CC=clang-3.5 _CXX=clang++-3.5 SANITIZE=address
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
packages: ['clang-3.6']
env: SCRIPT=cmake CLANG=3.6 SANITIZE=leak
- compiler: clang
addons:
env: SCRIPT=test _CC=clang-3.6 _CXX=clang++-3.6 SANITIZE=leak
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
packages: ['clang-3.7']
env: SCRIPT=cmake CLANG=3.7
- compiler: clang
addons:
env: SCRIPT=test _CC=clang-3.7 _CXX=clang++-3.7
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
packages: ['clang-3.8']
env: SCRIPT=cmake CLANG=3.8 SANITIZE=undefined
- compiler: clang
addons:
env: SCRIPT=test _CC=clang-3.8 _CXX=clang++-3.8 SANITIZE=undefined
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-3.9']
packages: ['clang-3.9']
env: SCRIPT=cmake CLANG=3.9
- compiler: clang
addons:
env: SCRIPT=test _CC=clang-3.9 _CXX=clang++-3.9
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-4.0']
packages: ['clang-4.0']
env: SCRIPT=cmake CLANG=4.0
- compiler: clang
addons:
env: SCRIPT=test _CC=clang-4.0 _CXX=clang++-4.0
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-5.0']
packages: ['clang-5.0']
env: SCRIPT=cmake CLANG=5.0
- compiler: clang
addons:
env: SCRIPT=test _CC=clang-5.0 _CXX=clang++-5.0
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-6.0']
packages: ['clang-6.0']
env: SCRIPT=cmake CLANG=6.0
- compiler: gcc
env: SCRIPT=coverage
env: SCRIPT=test _CC=clang-6.0 _CXX=clang++-6.0
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-7']
packages: ['clang-7']
env: SCRIPT=test _CC=clang-7 _CXX=clang++-7
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-8']
packages: ['clang-8']
env: SCRIPT=test _CC=clang-8 _CXX=clang++-8
- env: SCRIPT=coverage
- os: osx
osx_image: xcode7.3
compiler: clang
env: SCRIPT=cmake
env: SCRIPT=test
- os: osx
osx_image: xcode8.3
compiler: clang
env: SCRIPT=cmake
env: SCRIPT=test
- os: osx
osx_image: xcode9.4
compiler: clang
env: SCRIPT=cmake
env: SCRIPT=test
- os: osx
osx_image: xcode10
compiler: clang
env: SCRIPT=cmake SANITIZE=address
env: SCRIPT=test SANITIZE=address
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.8.2 BOARD=arduino:samd:mkr1000
- env: SCRIPT=platformio BOARD=uno
- env: SCRIPT=platformio BOARD=esp01
- compiler: clang
addons:
- addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-trusty-6.0']
packages: ['clang-6.0','llvm-6.0']

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#include "src/ArduinoJson.h"

View File

@ -1,6 +1,55 @@
ArduinoJson: change log
=======================
v6.10.1 (2019-04-23)
-------
* Fixed error "attributes are not allowed on a function-definition"
* Fixed `deserializeJson()` not being picky enough (issue #969)
* Fixed error "no matching function for call to write(uint8_t)" (issue #972)
v6.10.0 (2019-03-22)
-------
* Fixed an integer overflow in the JSON deserializer
* Added overflow handling in `JsonVariant::as<T>()` and `JsonVariant::is<T>()`.
- `as<T>()` returns `0` if the integer `T` overflows
- `is<T>()` returns `false` if the integer `T` overflows
* Added `BasicJsonDocument` to support custom allocator (issue #876)
* Added `JsonDocument::containsKey()` (issue #938)
* Added `JsonVariant::containsKey()`
v6.9.1 (2019-03-01)
------
* Fixed warning "unused variable" with GCC 4.4 (issue #912)
* Fixed warning "cast increases required alignment" (issue #914)
* Fixed warning "conversion may alter value" (issue #914)
* Fixed naming conflict with "CAPACITY" (issue #839)
* Muted warning "will change in GCC 7.1" (issue #914)
* Added a clear error message for `StaticJsonBuffer` and `DynamicJsonBuffer`
* Marked ArduinoJson.h as a "system header"
v6.9.0 (2019-02-26)
------
* Decode escaped Unicode characters like \u00DE (issue #304, PR #791)
Many thanks to Daniel Schulte (aka @trilader) who implemented this feature.
* Added option ARDUINOJSON_DECODE_UNICODE to enable it
* Converted `JsonArray::copyFrom()/copyTo()` to free functions `copyArray()`
* Renamed `JsonArray::copyFrom()` and `JsonObject::copyFrom()` to `set()`
* Renamed `JsonArray::get()` to `getElement()`
* Renamed `JsonArray::add()` (without arg) to `addElement()`
* Renamed `JsonObject::get()` to `getMember()`
* Renamed `JsonObject::getOrCreate()` to `getOrAddMember()`
* Fixed `JsonVariant::isNull()` not returning `true` after `set((char*)0)`
* Fixed segfault after `variant.set(serialized((char*)0))`
* Detect `IncompleteInput` in `false`, `true`, and `null`
* Added `JsonDocument::size()`
* Added `JsonDocument::remove()`
* Added `JsonVariant::clear()`
* Added `JsonVariant::remove()`
v6.8.0-beta (2019-01-30)
-----------

View File

@ -1,5 +1,5 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# Copyright Benoit Blanchon 2014-2019
# MIT License
cmake_minimum_required(VERSION 3.0)

View File

@ -1,7 +1,7 @@
The MIT License (MIT)
---------------------
Copyright © 2014-2018 Benoit BLANCHON
Copyright © 2014-2019 Benoit BLANCHON
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -2,7 +2,7 @@
---
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.7.0-beta)](https://www.ardu-badge.com/ArduinoJson/6.7.0-beta)
[![arduino-library-badge](https://www.ardu-badge.com/badge/ArduinoJson.svg?version=6.10.1)](https://www.ardu-badge.com/ArduinoJson/6.10.1)
[![Build Status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/6.x?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/6.x)
[![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=6.x)](https://travis-ci.org/bblanchon/ArduinoJson)
[![Coverage Status](https://coveralls.io/repos/github/bblanchon/ArduinoJson/badge.svg?branch=6.x)](https://coveralls.io/github/bblanchon/ArduinoJson?branch=6.x)
@ -67,11 +67,10 @@ char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302
DynamicJsonDocument doc(1024);
deserializeJson(doc, json);
JsonObjectRef root = doc.as<JsonObject>();
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
const char* sensor = doc["sensor"];
long time = doc["time"];
double latitude = doc["data"][0];
double longitude = doc["data"][1];
```
See the [tutorial on arduinojson.org](https://arduinojson.org/doc/decoding/?utm_source=github&utm_medium=readme)
@ -83,11 +82,10 @@ Here is a program that generates a JSON document with ArduinoJson:
```c++
DynamicJsonDocument doc(1024);
JsonObject root = doc.to<JsonObject>();
root["sensor"] = "gps";
root["time"] = 1351824120;
doc["sensor"] = "gps";
doc["time"] = 1351824120;
JsonArray data = root.createNestedArray("data");
JsonArray data = doc.createNestedArray("data");
data.add(48.756080);
data.add(2.302038);

View File

@ -1,4 +1,4 @@
version: 6.4.0.{build}
version: 6.10.1.{build}
environment:
matrix:
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to store your project configuration in a file.
@ -10,6 +10,8 @@
// "hostname": "examples.com",
// "port": 2731
// }
//
// https://arduinojson.org/v6/example/config/
#include <ArduinoJson.h>
#include <SD.h>
@ -19,7 +21,8 @@
//
// Never use a JsonDocument to store the configuration!
// A JsonDocument is *not* a permanent storage; it's only a temporary storage
// used during the serialization phase.
// used during the serialization phase. See:
// https://arduinojson.org/v6/faq/why-must-i-create-a-separate-config-object/
struct Config {
char hostname[64];
int port;
@ -130,4 +133,15 @@ void loop() {
// not used in this example
}
// Visit https://arduinojson.org/v6/example/config/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization or deserialization problem.
//
// The book "Mastering ArduinoJson" contains a case study of a project that has
// a complex configuration with nested members.
// Contrary to this example, the project in the book uses the SPIFFS filesystem.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,8 +1,10 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to generate a JSON document with ArduinoJson.
//
// https://arduinojson.org/v6/example/generator/
#include <ArduinoJson.h>
@ -61,4 +63,15 @@ void loop() {
// not used in this example
}
// Visit https://arduinojson.org/v6/example/generator/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
// It begins with a simple example, like the one above, and then adds more
// features like serializing directly to a file or an HTTP request.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to parse a JSON document in an HTTP response.
@ -15,6 +15,8 @@
// 2.302038
// ]
// }
//
// https://arduinojson.org/v6/example/http-client/
#include <ArduinoJson.h>
#include <Ethernet.h>
@ -98,4 +100,16 @@ void loop() {
// not used in this example
}
// Visit https://arduinojson.org/v6/example/http-client/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on deserialization
// showing how to parse the response from GitHub's API. In the last chapter,
// it shows how to parse the huge documents from OpenWeatherMap
// and Reddit.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,8 +1,10 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to deserialize a JSON document with ArduinoJson.
//
// https://arduinojson.org/v6/example/parser/
#include <ArduinoJson.h>
@ -64,4 +66,15 @@ void loop() {
// not used in this example
}
// Visit https://arduinojson.org/v6/example/parser/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// deserialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on deserialization.
// It begins with a simple example, like the one above, and then adds more
// features like deserializing directly from a file or an HTTP request.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to implement an HTTP server that sends a JSON document
@ -12,6 +12,8 @@
// "analog": [0, 76, 123, 158, 192, 205],
// "digital": [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0]
// }
//
// https://arduinojson.org/v6/example/http-server/
#include <ArduinoJson.h>
#include <Ethernet.h>
@ -94,4 +96,15 @@ void loop() {
client.stop();
}
// Visit https://arduinojson.org/v6/example/http-server/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
// It begins with a simple example, then adds more features like serializing
// directly to a file or an HTTP client.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to send a JSON document to a UDP socket.
@ -16,6 +16,8 @@
// For example, you can run netcat on your computer
// $ ncat -ulp 8888
// See https://nmap.org/ncat/
//
// https://arduinojson.org/v6/example/udp-beacon/
#include <ArduinoJson.h>
#include <Ethernet.h>
@ -84,4 +86,15 @@ void loop() {
delay(10000);
}
// Visit https://arduinojson.org/v6/example/udp-beacon/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any
// serialization problem.
//
// The book "Mastering ArduinoJson" contains a tutorial on serialization.
// It begins with a simple example, then adds more features like serializing
// directly to a file or any stream.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,9 +1,11 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to deserialize a MessagePack document with
// ArduinoJson.
//
// https://arduinojson.org/v6/example/msgpack-parser/
#include <ArduinoJson.h>
@ -71,5 +73,3 @@ void setup() {
void loop() {
// not used in this example
}
// Visit https://arduinojson.org/v6/example/msgpack-parser/ for more.

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows the different ways you can use Flash strings with
@ -8,6 +8,8 @@
// Use Flash strings sparingly, because ArduinoJson duplicates them in the
// JsonDocument. Prefer plain old char*, as they are more efficient in term of
// code size, speed, and memory usage.
//
// https://arduinojson.org/v6/example/progmem/
#include <ArduinoJson.h>
@ -17,7 +19,7 @@ void setup() {
DynamicJsonDocument doc(1024);
// You can use a Flash String as your JSON input.
// WARNING: the string in the input will be duplicated in the JsonDocument.
// WARNING: the strings in the input will be duplicated in the JsonDocument.
deserializeJson(doc, F("{\"sensor\":\"gps\",\"time\":1351824120,"
"\"data\":[48.756080,2.302038]}"));
JsonObject obj = doc.as<JsonObject>();
@ -56,4 +58,15 @@ void loop() {
// not used in this example
}
// Visit https://arduinojson.org/v6/example/progmem/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any memory
// problem.
//
// The book "Mastering ArduinoJson" contains a quick C++ course that explains
// how your microcontroller stores strings in memory. It also tells why you
// should not abuse Flash strings with ArduinoJson.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows the different ways you can use String with ArduinoJson.
@ -7,6 +7,8 @@
// Use String objects sparingly, because ArduinoJson duplicates them in the
// JsonDocument. Prefer plain old char[], as they are more efficient in term of
// code size, speed, and memory usage.
//
// https://arduinojson.org/v6/example/string/
#include <ArduinoJson.h>
@ -62,4 +64,14 @@ void loop() {
// not used in this example
}
// Visit https://arduinojson.org/v6/example/string/ for more.
// See also
// --------
//
// https://arduinojson.org/ contains the documentation for all the functions
// used above. It also includes an FAQ that will help you solve any problem.
//
// The book "Mastering ArduinoJson" contains a quick C++ course that explains
// how your microcontroller stores strings in memory. On several occasions, it
// shows how you can avoid String in your program.
// Learn more at https://arduinojson.org/book/
// Use the coupon code TWENTY for a 20% discount ❤❤❤❤❤

View File

@ -1,5 +1,5 @@
# ArduinoJson - arduinojson.org
# Copyright Benoit Blanchon 2014-2018
# Copyright Benoit Blanchon 2014-2019
# MIT License
if(MSVC)

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
// This file is NOT use by Google's OSS fuzz

View File

@ -0,0 +1 @@
9720730739393920739

View File

@ -7,7 +7,7 @@
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"version": "6.8.0-beta",
"version": "6.10.1",
"authors": {
"name": "Benoit Blanchon",
"url": "https://blog.benoitblanchon.fr"

View File

@ -1,5 +1,5 @@
name=ArduinoJson
version=6.8.0-beta
version=6.10.1
author=Benoit Blanchon <blog.benoitblanchon.fr>
maintainer=Benoit Blanchon <blog.benoitblanchon.fr>
sentence=An efficient and elegant JSON library for Arduino.

View File

@ -18,12 +18,16 @@ update_version_in_source () {
sed -i~ -bE "4s/HEAD/$TAG ($DATE)/; 5s/-+/$UNDERLINE/" CHANGELOG.md
rm CHANGELOG.md*~
sed -i~ -bE "s/\"version\":.*$/\"version\": \"$VERSION\",/" library.json
rm library.json*~
sed -i~ -bE "s/version=.*$/version=$VERSION/" library.properties
rm library.properties*~
sed -i~ -bE "s/version: .*$/version: $VERSION.{build}/" appveyor.yml
rm appveyor.yml*~
sed -i~ -bE \
-e "s/ARDUINOJSON_VERSION .*$/ARDUINOJSON_VERSION \"$VERSION\"/" \
-e "s/ARDUINOJSON_VERSION_MAJOR .*$/ARDUINOJSON_VERSION_MAJOR $MAJOR/" \
@ -34,7 +38,7 @@ update_version_in_source () {
}
commit_new_version () {
git add src/ArduinoJson/version.hpp CHANGELOG.md library.json library.properties
git add src/ArduinoJson/version.hpp README.md CHANGELOG.md library.json library.properties appveyor.yml
git commit -m "Set version to $VERSION"
}

14
scripts/travis/build.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/sh -ex
export CC="$_CC"
export CXX="$_CXX"
if [ -n "$SANITIZE" ]; then
export CXXFLAGS="-fsanitize=$SANITIZE"
BUILD_TYPE="Debug"
else
BUILD_TYPE="Release"
fi
cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE .
cmake --build .

View File

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

View File

@ -1,8 +1,6 @@
#!/bin/sh -eux
curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1
/tmp/bin/cmake -DCOVERAGE=true .
cmake -DCOVERAGE=true .
make
make test

View File

@ -3,7 +3,7 @@
ROOT_DIR=$(dirname $0)/../../
INCLUDE_DIR=${ROOT_DIR}/src/
FUZZING_DIR=${ROOT_DIR}/fuzzing/
CXXFLAGS="-g -fprofile-instr-generate -fcoverage-mapping -fsanitize=address,fuzzer"
CXXFLAGS="-g -fprofile-instr-generate -fcoverage-mapping -fsanitize=address,undefined,fuzzer -fno-sanitize-recover=all"
fuzz() {
NAME="$1"

View File

@ -4,6 +4,18 @@ pip install --user platformio
rm -r test
case $BOARD in
uno)
platformio lib install 868 # SD library
platformio lib install 872 # Ethernet library
;;
esp01)
platformio lib uninstall 161 || true
platformio lib uninstall 868 || true
platformio lib uninstall 872 || true
;;
esac
for EXAMPLE in $PWD/examples/*/*.ino;
do
platformio ci $EXAMPLE -l '.' -b $BOARD

4
scripts/travis/test.sh Executable file
View File

@ -0,0 +1,4 @@
#!/bin/sh -ex
"$(dirname "$0")/build.sh"
ctest --output-on-failure .

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to generate a JSON document with ArduinoJson.
@ -8,11 +8,11 @@
#include "ArduinoJson.h"
int main() {
// The JSON document
// Allocate the JSON document
//
// Inside the brackets, 200 is the RAM allocated to this document.
// Don't forget to change this value to match your requirement.
// Use arduinojson.org/assistant to compute the capacity.
// Use arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<200> doc;
// StaticJsonObject allocates memory on the stack, it can be
@ -20,30 +20,35 @@ int main() {
//
// DynamicJsonDocument doc(200);
// Make our document be an object
JsonObject root = doc.to<JsonObject>();
// Add values in the object
// StaticJsonObject allocates memory on the stack, it can be
// replaced by DynamicJsonDocument which allocates in the heap.
//
// 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;
// DynamicJsonDocument doc(200);
// Add values in the document
//
doc["sensor"] = "gps";
doc["time"] = 1351824120;
// Add an array.
//
JsonArray data = root.createNestedArray("data");
JsonArray data = doc.createNestedArray("data");
data.add(48.756080);
data.add(2.302038);
serializeJson(root, std::cout);
// This prints:
// Generate the minified JSON and send it to STDOUT
//
serializeJson(doc, std::cout);
// The above line prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
// Start a new line
std::cout << std::endl;
serializeJsonPretty(root, std::cout);
// This prints:
// Generate the prettified JSON and send it to STDOUT
//
serializeJsonPretty(doc, std::cout);
// The above line prints:
// {
// "sensor": "gps",
// "time": 1351824120,
@ -52,6 +57,4 @@ int main() {
// 2.302038
// ]
// }
return 0;
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to deserialize a JSON document with ArduinoJson.
@ -8,23 +8,26 @@
#include "ArduinoJson.h"
int main() {
// Root JSON object
// Allocate the JSON document
//
// Inside the brackets, 300 is the size of the memory pool in bytes.
// Inside the brackets, 200 is the capacity of the memory pool in bytes.
// Don't forget to change this value to match your JSON document.
// Use arduinojson.org/assistant to compute the capacity.
// Use arduinojson.org/v6/assistant to compute the capacity.
StaticJsonDocument<300> doc;
// StaticJsonDocument<N> allocates memory on the stack, it can be
// replaced by DynamicJsonObject which allocates in the heap.
// replaced by DynamicJsonDocument which allocates in the heap.
//
// DynamicJsonObject doc(200);
// DynamicJsonDocument doc(200);
// 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.
// Using a char[], as shown here, enables the "zero-copy" mode. This mode uses
// the minimal amount of memory because the JsonDocument stores pointers to
// the input buffer.
// If you use another type of input, ArduinoJson must copy the strings from
// the input to the JsonDocument, so you need to increase the capacity of the
// JsonDocument.
char json[] =
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
@ -37,17 +40,14 @@ int main() {
return 1;
}
// Get the root object in the document
JsonObject root = doc.as<JsonObject>();
// Fetch values.
//
// Most of the time, you can rely on the implicit casts.
// In other case, you can do doc["time"].as<long>();
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
const char* sensor = doc["sensor"];
long time = doc["time"];
double latitude = doc["data"][0];
double longitude = doc["data"][1];
// Print values.
std::cout << sensor << std::endl;

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
//
// This example shows how to generate a JSON document with ArduinoJson.
@ -49,17 +49,14 @@ int main() {
return 1;
}
// Get the root object in the document
JsonObject root = doc.as<JsonObject>();
// Fetch values.
//
// Most of the time, you can rely on the implicit casts.
// In other case, you can do doc["time"].as<long>();
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
const char* sensor = doc["sensor"];
long time = doc["time"];
double latitude = doc["data"][0];
double longitude = doc["data"][1];
// Print values.
std::cout << sensor << std::endl;

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,9 +1,17 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#ifndef ARDUINOJSON_DEBUG
#ifdef __clang__
#pragma clang system_header
#elif defined __GNUC__
#pragma GCC system_header
#endif
#endif
#include "ArduinoJson/Namespace.hpp"
#include "ArduinoJson/Array/ArrayRef.hpp"
@ -15,6 +23,7 @@
#include "ArduinoJson/Array/ArrayImpl.hpp"
#include "ArduinoJson/Array/ElementProxy.hpp"
#include "ArduinoJson/Array/Utilities.hpp"
#include "ArduinoJson/Collection/CollectionImpl.hpp"
#include "ArduinoJson/Object/MemberProxy.hpp"
#include "ArduinoJson/Object/ObjectImpl.hpp"
@ -27,6 +36,8 @@
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
#include "ArduinoJson/MsgPack/MsgPackSerializer.hpp"
#include "ArduinoJson/compatibility.hpp"
namespace ArduinoJson {
typedef ARDUINOJSON_NAMESPACE::ArrayConstRef JsonArrayConst;
typedef ARDUINOJSON_NAMESPACE::ArrayRef JsonArray;
@ -39,6 +50,8 @@ typedef ARDUINOJSON_NAMESPACE::String JsonString;
typedef ARDUINOJSON_NAMESPACE::UInt JsonUInt;
typedef ARDUINOJSON_NAMESPACE::VariantConstRef JsonVariantConst;
typedef ARDUINOJSON_NAMESPACE::VariantRef JsonVariant;
using ARDUINOJSON_NAMESPACE::BasicJsonDocument;
using ARDUINOJSON_NAMESPACE::copyArray;
using ARDUINOJSON_NAMESPACE::DeserializationError;
using ARDUINOJSON_NAMESPACE::deserializeJson;
using ARDUINOJSON_NAMESPACE::deserializeMsgPack;

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -11,12 +11,12 @@ namespace ARDUINOJSON_NAMESPACE {
template <typename TArray>
inline ArrayRef ArrayShortcuts<TArray>::createNestedArray() const {
return impl()->add().template to<ArrayRef>();
return impl()->addElement().template to<ArrayRef>();
}
template <typename TArray>
inline ObjectRef ArrayShortcuts<TArray>::createNestedObject() const {
return impl()->add().template to<ObjectRef>();
return impl()->addElement().template to<ObjectRef>();
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -23,7 +23,8 @@ template <typename TData>
class ArrayRefBase {
public:
operator VariantConstRef() const {
return VariantConstRef(reinterpret_cast<const VariantData*>(_data));
const void* data = _data; // prevent warning cast-align
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
}
template <typename Visitor>
@ -77,6 +78,10 @@ class ArrayConstRef : public ArrayRefBase<const CollectionData>,
}
FORCE_INLINE VariantConstRef operator[](size_t index) const {
return getElement(index);
}
FORCE_INLINE VariantConstRef getElement(size_t index) const {
return VariantConstRef(_data ? _data->get(index) : 0);
}
};
@ -94,15 +99,15 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
: base_type(data), _pool(pool) {}
operator VariantRef() {
return VariantRef(_pool, reinterpret_cast<VariantData*>(_data));
void* data = _data; // prevent warning cast-align
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
}
operator ArrayConstRef() const {
return ArrayConstRef(_data);
}
using ArrayShortcuts::add;
VariantRef add() const {
VariantRef addElement() const {
return VariantRef(_pool, arrayAdd(_data, _pool));
}
@ -115,71 +120,18 @@ class ArrayRef : public ArrayRefBase<CollectionData>,
return iterator();
}
// Imports a 1D array
template <typename T, size_t N>
FORCE_INLINE bool copyFrom(T (&array)[N]) const {
return copyFrom(array, N);
}
// Imports a 1D array
template <typename T>
bool copyFrom(T* array, size_t len) const {
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]) const {
bool ok = true;
for (size_t i = 0; i < N1; i++) {
ArrayRef nestedArray = createNestedArray();
for (size_t j = 0; j < N2; j++) {
ok &= nestedArray.add(array[i][j]);
}
}
return ok;
}
// Copy a ArrayRef
FORCE_INLINE bool copyFrom(ArrayConstRef src) const {
FORCE_INLINE bool set(ArrayConstRef src) const {
if (!_data || !src._data) return false;
return _data->copyFrom(*src._data, _pool);
}
// Exports a 1D array
template <typename T, size_t N>
FORCE_INLINE 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 (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 {
if (!_data) return;
size_t i = 0;
for (iterator it = begin(); it != end() && i < N1; ++it) {
it->as<ArrayRef>().copyTo(array[i++]);
}
}
FORCE_INLINE bool operator==(ArrayRef rhs) const {
return arrayEquals(_data, rhs._data);
}
// Gets the value at the specified index.
FORCE_INLINE VariantRef get(size_t index) const {
FORCE_INLINE VariantRef getElement(size_t index) const {
return VariantRef(_pool, _data ? _data->get(index) : 0);
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -29,14 +29,14 @@ class ArrayShortcuts {
// std::string, String, ObjectRef
template <typename T>
FORCE_INLINE bool add(const T &value) const {
return impl()->add().set(value);
return impl()->addElement().set(value);
}
//
// bool add(TValue);
// TValue = char*, const char*, const __FlashStringHelper*
template <typename T>
FORCE_INLINE bool add(T *value) const {
return impl()->add().set(value);
return impl()->addElement().set(value);
}
private:

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -24,7 +24,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
: _array(array), _index(index) {}
FORCE_INLINE this_type& operator=(const this_type& src) {
getElement().set(src.as<VariantConstRef>());
getUpstreamElement().set(src.as<VariantConstRef>());
return *this;
}
@ -35,7 +35,7 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
// std::string, String, ArrayRef, ObjectRef
template <typename T>
FORCE_INLINE this_type& operator=(const T& src) {
getElement().set(src);
getUpstreamElement().set(src);
return *this;
}
//
@ -43,27 +43,31 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
// TValue = char*, const char*, const __FlashStringHelper*
template <typename T>
FORCE_INLINE this_type& operator=(T* src) {
getElement().set(src);
getUpstreamElement().set(src);
return *this;
}
FORCE_INLINE void clear() const {
getUpstreamElement().clear();
}
FORCE_INLINE bool isNull() const {
return getElement().isNull();
return getUpstreamElement().isNull();
}
template <typename T>
FORCE_INLINE typename VariantAs<T>::type as() const {
return getElement().template as<T>();
return getUpstreamElement().template as<T>();
}
template <typename T>
FORCE_INLINE bool is() const {
return getElement().template is<T>();
return getUpstreamElement().template is<T>();
}
template <typename T>
FORCE_INLINE typename VariantTo<T>::type to() const {
return getElement().template to<T>();
return getUpstreamElement().template to<T>();
}
// Replaces the value
@ -73,53 +77,75 @@ class ElementProxy : public VariantOperators<ElementProxy<TArray> >,
// std::string, String, ArrayRef, ObjectRef
template <typename TValue>
FORCE_INLINE bool set(const TValue& value) const {
return getElement().set(value);
return getUpstreamElement().set(value);
}
//
// bool set(TValue)
// TValue = char*, const char*, const __FlashStringHelper*
template <typename TValue>
FORCE_INLINE bool set(TValue* value) const {
return getElement().set(value);
return getUpstreamElement().set(value);
}
template <typename Visitor>
void accept(Visitor& visitor) const {
return getElement().accept(visitor);
return getUpstreamElement().accept(visitor);
}
FORCE_INLINE size_t size() const {
return getElement().size();
return getUpstreamElement().size();
}
template <typename TNestedKey>
VariantRef get(TNestedKey* key) const {
return getElement().get(key);
VariantRef getMember(TNestedKey* key) const {
return getUpstreamElement().getMember(key);
}
template <typename TNestedKey>
VariantRef get(const TNestedKey& key) const {
return getElement().get(key);
VariantRef getMember(const TNestedKey& key) const {
return getUpstreamElement().getMember(key);
}
template <typename TNestedKey>
VariantRef getOrCreate(TNestedKey* key) const {
return getElement().getOrCreate(key);
VariantRef getOrAddMember(TNestedKey* key) const {
return getUpstreamElement().getOrAddMember(key);
}
template <typename TNestedKey>
VariantRef getOrCreate(const TNestedKey& key) const {
return getElement().getOrCreate(key);
VariantRef getOrAddMember(const TNestedKey& key) const {
return getUpstreamElement().getOrAddMember(key);
}
using ArrayShortcuts<ElementProxy>::add;
VariantRef add() const {
return getElement().add();
VariantRef addElement() const {
return getUpstreamElement().addElement();
}
VariantRef getElement(size_t index) const {
return getUpstreamElement().getElement(index);
}
FORCE_INLINE void remove(size_t index) const {
getUpstreamElement().remove(index);
}
// remove(char*) const
// remove(const char*) const
// remove(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
TChar* key) const {
getUpstreamElement().remove(key);
}
// remove(const std::string&) const
// remove(const String&) const
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString& key) const {
getUpstreamElement().remove(key);
}
private:
FORCE_INLINE VariantRef getElement() const {
return _array.get(_index);
FORCE_INLINE VariantRef getUpstreamElement() const {
return _array.getElement(_index);
}
TArray _array;

View File

@ -0,0 +1,66 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "ArrayRef.hpp"
namespace ARDUINOJSON_NAMESPACE {
// Copy a 1D array to a JsonArray
template <typename T, size_t N>
inline bool copyArray(T (&src)[N], ArrayRef dst) {
return copyArray(src, N, dst);
}
// Copy a 1D array to a JsonArray
template <typename T>
inline bool copyArray(T* src, size_t len, ArrayRef dst) {
bool ok = true;
for (size_t i = 0; i < len; i++) {
ok &= dst.add(src[i]);
}
return ok;
}
// Copy a 2D array to a JsonArray
template <typename T, size_t N1, size_t N2>
inline bool copyArray(T (&src)[N1][N2], ArrayRef dst) {
bool ok = true;
for (size_t i = 0; i < N1; i++) {
ArrayRef nestedArray = dst.createNestedArray();
for (size_t j = 0; j < N2; j++) {
ok &= nestedArray.add(src[i][j]);
}
}
return ok;
}
// Copy a JsonArray to a 1D array
template <typename T, size_t N>
inline size_t copyArray(ArrayConstRef src, T (&dst)[N]) {
return copyArray(src, dst, N);
}
// Copy a JsonArray to a 1D array
template <typename T>
inline size_t copyArray(ArrayConstRef src, T* dst, size_t len) {
size_t i = 0;
for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < len;
++it)
dst[i++] = *it;
return i;
}
// Copy a JsonArray to a 2D array
template <typename T, size_t N1, size_t N2>
inline void copyArray(ArrayConstRef src, T (&dst)[N1][N2]) {
size_t i = 0;
for (ArrayConstRef::iterator it = src.begin(); it != src.end() && i < N1;
++it) {
copyArray(it->as<ArrayConstRef>(), dst[i++]);
}
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -26,7 +26,7 @@ inline VariantSlot* CollectionData::addSlot(MemoryPool* pool) {
}
inline VariantData* CollectionData::add(MemoryPool* pool) {
return addSlot(pool)->data();
return slotData(addSlot(pool));
}
template <typename TAdaptedString>

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -88,28 +88,38 @@
#ifdef ARDUINO
// Enable support for Arduino String
// Enable support for Arduino's String class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#endif
// Enable support for Arduino Stream
// Enable support for Arduino's Stream class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1
#endif
// Enable support for Arduino's Print class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 1
#endif
#else // ARDUINO
// Disable support for Arduino String
// Enable support for Arduino's String class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#endif
// Disable support for Arduino Stream
// Enable support for Arduino's Stream class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM
#define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0
#endif
// Enable support for Arduino's Print class
#ifndef ARDUINOJSON_ENABLE_ARDUINO_PRINT
#define ARDUINOJSON_ENABLE_ARDUINO_PRINT 0
#endif
#endif // ARDUINO
#ifndef ARDUINOJSON_ENABLE_PROGMEM
@ -120,6 +130,11 @@
#endif
#endif
// Convert unicode escape sequence (\u0123) to UTF-8
#ifndef ARDUINOJSON_DECODE_UNICODE
#define ARDUINOJSON_DECODE_UNICODE 0
#endif
// Control the exponentiation threshold for big numbers
// CAUTION: cannot be more that 1e9 !!!!
#ifndef ARDUINOJSON_POSITIVE_EXPONENTIATION_THRESHOLD
@ -134,7 +149,7 @@
#ifndef ARDUINOJSON_LITTLE_ENDIAN
#if defined(_MSC_VER) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
(defined(__LITTLE_ENDIAN__))
defined(__LITTLE_ENDIAN__) || defined(__i386) || defined(__x86_64)
#define ARDUINOJSON_LITTLE_ENDIAN 1
#else
#define ARDUINOJSON_LITTLE_ENDIAN 0

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -0,0 +1,89 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "JsonDocument.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename TAllocator>
class AllocatorOwner {
protected:
AllocatorOwner() {}
AllocatorOwner(const AllocatorOwner& src) : _allocator(src._allocator) {}
AllocatorOwner(TAllocator allocator) : _allocator(allocator) {}
void* allocate(size_t n) {
return _allocator.allocate(n);
}
void deallocate(void* p) {
_allocator.deallocate(p);
}
private:
TAllocator _allocator;
};
template <typename TAllocator>
class BasicJsonDocument : AllocatorOwner<TAllocator>, public JsonDocument {
public:
explicit BasicJsonDocument(size_t capa, TAllocator allocator = TAllocator())
: AllocatorOwner<TAllocator>(allocator), JsonDocument(allocPool(capa)) {}
BasicJsonDocument(const BasicJsonDocument& src)
: AllocatorOwner<TAllocator>(src),
JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
template <typename T>
BasicJsonDocument(const T& src,
typename enable_if<IsVisitable<T>::value>::type* = 0)
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
// disambiguate
BasicJsonDocument(VariantRef src)
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
~BasicJsonDocument() {
freePool();
}
BasicJsonDocument& operator=(const BasicJsonDocument& src) {
reallocPoolIfTooSmall(src.memoryUsage());
set(src);
return *this;
}
template <typename T>
BasicJsonDocument& operator=(const T& src) {
reallocPoolIfTooSmall(src.memoryUsage());
set(src);
return *this;
}
private:
MemoryPool allocPool(size_t requiredSize) {
size_t capa = addPadding(requiredSize);
return MemoryPool(reinterpret_cast<char*>(this->allocate(capa)), capa);
}
void reallocPoolIfTooSmall(size_t requiredSize) {
if (requiredSize <= capacity()) return;
freePool();
replacePool(allocPool(addPadding(requiredSize)));
}
void freePool() {
this->deallocate(memoryPool().buffer());
}
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,70 +1,25 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "JsonDocument.hpp"
#include "BasicJsonDocument.hpp"
#include <stdlib.h> // malloc, free
namespace ARDUINOJSON_NAMESPACE {
class DynamicJsonDocument : public JsonDocument {
public:
explicit DynamicJsonDocument(size_t capa)
: JsonDocument(allocPool(capa)) {}
DynamicJsonDocument(const DynamicJsonDocument& src)
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
struct DefaultAllocator {
void* allocate(size_t n) {
return malloc(n);
}
template <typename T>
DynamicJsonDocument(const T& src,
typename enable_if<IsVisitable<T>::value>::type* = 0)
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
// disambiguate
DynamicJsonDocument(VariantRef src)
: JsonDocument(allocPool(src.memoryUsage())) {
set(src);
}
~DynamicJsonDocument() {
freePool();
}
DynamicJsonDocument& operator=(const DynamicJsonDocument& src) {
reallocPoolIfTooSmall(src.memoryUsage());
set(src);
return *this;
}
template <typename T>
DynamicJsonDocument& operator=(const T& src) {
reallocPoolIfTooSmall(src.memoryUsage());
set(src);
return *this;
}
private:
MemoryPool allocPool(size_t requiredSize) {
size_t capa = addPadding(requiredSize);
return MemoryPool(reinterpret_cast<char*>(malloc(capa)), capa);
}
void reallocPoolIfTooSmall(size_t requiredSize) {
if (requiredSize <= capacity()) return;
freePool();
replacePool(allocPool(addPadding(requiredSize)));
}
void freePool() {
free(memoryPool().buffer());
void deallocate(void* p) {
free(p);
}
};
typedef BasicJsonDocument<DefaultAllocator> DynamicJsonDocument;
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -57,6 +57,10 @@ class JsonDocument : public Visitable {
return _pool.capacity();
}
size_t size() const {
return _data.size();
}
bool set(const JsonDocument& src) {
return to<VariantRef>().set(src.as<VariantRef>());
}
@ -83,7 +87,7 @@ class JsonDocument : public Visitable {
}
ArrayRef createNestedArray() {
return add().to<ArrayRef>();
return addElement().to<ArrayRef>();
}
// createNestedArray(char*)
@ -91,18 +95,18 @@ class JsonDocument : public Visitable {
// createNestedArray(const __FlashStringHelper*)
template <typename TChar>
ArrayRef createNestedArray(TChar* key) {
return getOrCreate(key).template to<ArrayRef>();
return getOrAddMember(key).template to<ArrayRef>();
}
// createNestedArray(const std::string&)
// createNestedArray(const String&)
template <typename TString>
ArrayRef createNestedArray(const TString& key) {
return getOrCreate(key).template to<ArrayRef>();
return getOrAddMember(key).template to<ArrayRef>();
}
ObjectRef createNestedObject() {
return add().to<ObjectRef>();
return addElement().to<ObjectRef>();
}
// createNestedObject(char*)
@ -110,14 +114,29 @@ class JsonDocument : public Visitable {
// createNestedObject(const __FlashStringHelper*)
template <typename TChar>
ObjectRef createNestedObject(TChar* key) {
return getOrCreate(key).template to<ObjectRef>();
return getOrAddMember(key).template to<ObjectRef>();
}
// createNestedObject(const std::string&)
// createNestedObject(const String&)
template <typename TString>
ObjectRef createNestedObject(const TString& key) {
return getOrCreate(key).template to<ObjectRef>();
return getOrAddMember(key).template to<ObjectRef>();
}
// containsKey(char*) const
// containsKey(const char*) const
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
bool containsKey(TChar* key) const {
return !getMember(key).isUndefined();
}
// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
bool containsKey(const TString& key) const {
return !getMember(key).isUndefined();
}
// operator[](const std::string&)
@ -146,7 +165,7 @@ class JsonDocument : public Visitable {
FORCE_INLINE
typename enable_if<IsString<TString>::value, VariantConstRef>::type
operator[](const TString& key) const {
return getVariant()[key];
return getMember(key);
}
// operator[](char*) const
@ -156,7 +175,7 @@ class JsonDocument : public Visitable {
FORCE_INLINE
typename enable_if<IsString<TChar*>::value, VariantConstRef>::type
operator[](TChar* key) const {
return getVariant()[key];
return getMember(key);
}
FORCE_INLINE ElementProxy<JsonDocument&> operator[](size_t index) {
@ -164,51 +183,72 @@ class JsonDocument : public Visitable {
}
FORCE_INLINE VariantConstRef operator[](size_t index) const {
return VariantConstRef(_data.get(index));
return getElement(index);
}
FORCE_INLINE VariantRef get(size_t index) {
return VariantRef(&_pool, _data.get(index));
FORCE_INLINE VariantRef getElement(size_t index) {
return VariantRef(&_pool, _data.getElement(index));
}
// get(char*) const
// get(const char*) const
// get(const __FlashStringHelper*) const
FORCE_INLINE VariantConstRef getElement(size_t index) const {
return VariantConstRef(_data.getElement(index));
}
// JsonVariantConst getMember(char*) const
// JsonVariantConst getMember(const char*) const
// JsonVariantConst getMember(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantRef get(TChar* key) {
return VariantRef(&_pool, _data.get(adaptString(key)));
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
return VariantConstRef(_data.getMember(adaptString(key)));
}
// get(const std::string&) const
// get(const String&) const
// JsonVariantConst getMember(const std::string&) const
// JsonVariantConst getMember(const String&) const
template <typename TString>
FORCE_INLINE
typename enable_if<IsString<TString>::value, VariantConstRef>::type
getMember(const TString& key) const {
return VariantConstRef(_data.getMember(adaptString(key)));
}
// JsonVariant getMember(char*)
// JsonVariant getMember(const char*)
// JsonVariant getMember(const __FlashStringHelper*)
template <typename TChar>
FORCE_INLINE VariantRef getMember(TChar* key) {
return VariantRef(&_pool, _data.getMember(adaptString(key)));
}
// JsonVariant getMember(const std::string&)
// JsonVariant getMember(const String&)
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type
get(const TString& key) {
return VariantRef(&_pool, _data.get(adaptString(key)));
getMember(const TString& key) {
return VariantRef(&_pool, _data.getMember(adaptString(key)));
}
// getOrCreate(char*)
// getOrCreate(const char*)
// getOrCreate(const __FlashStringHelper*)
// getOrAddMember(char*)
// getOrAddMember(const char*)
// getOrAddMember(const __FlashStringHelper*)
template <typename TChar>
FORCE_INLINE VariantRef getOrCreate(TChar* key) {
return VariantRef(&_pool, _data.getOrCreate(adaptString(key), &_pool));
FORCE_INLINE VariantRef getOrAddMember(TChar* key) {
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
}
// getOrCreate(const std::string&)
// getOrCreate(const String&)
// getOrAddMember(const std::string&)
// getOrAddMember(const String&)
template <typename TString>
FORCE_INLINE VariantRef getOrCreate(const TString& key) {
return VariantRef(&_pool, _data.getOrCreate(adaptString(key), &_pool));
FORCE_INLINE VariantRef getOrAddMember(const TString& key) {
return VariantRef(&_pool, _data.getOrAddMember(adaptString(key), &_pool));
}
FORCE_INLINE VariantRef add() {
return VariantRef(&_pool, _data.add(&_pool));
FORCE_INLINE VariantRef addElement() {
return VariantRef(&_pool, _data.addElement(&_pool));
}
template <typename TValue>
FORCE_INLINE bool add(const TValue& value) {
return add().set(value);
return addElement().set(value);
}
// add(char*) const
@ -216,7 +256,26 @@ class JsonDocument : public Visitable {
// add(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE bool add(TChar* value) {
return add().set(value);
return addElement().set(value);
}
FORCE_INLINE void remove(size_t index) {
_data.remove(index);
}
// remove(char*)
// remove(const char*)
// remove(const __FlashStringHelper*)
template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar*>::value>::type remove(
TChar* key) {
_data.remove(adaptString(key));
}
// remove(const std::string&)
// remove(const String&)
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString& key) {
_data.remove(adaptString(key));
}
protected:

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -8,28 +8,28 @@
namespace ARDUINOJSON_NAMESPACE {
template <size_t CAPACITY>
template <size_t desiredCapacity>
class StaticJsonDocument : public JsonDocument {
static const size_t ACTUAL_CAPACITY =
AddPadding<Max<1, CAPACITY>::value>::value;
static const size_t _capacity =
AddPadding<Max<1, desiredCapacity>::value>::value;
public:
StaticJsonDocument() : JsonDocument(_buffer, ACTUAL_CAPACITY) {}
StaticJsonDocument() : JsonDocument(_buffer, _capacity) {}
StaticJsonDocument(const StaticJsonDocument& src)
: JsonDocument(_buffer, ACTUAL_CAPACITY) {
: JsonDocument(_buffer, _capacity) {
set(src);
}
template <typename T>
StaticJsonDocument(const T& src,
typename enable_if<IsVisitable<T>::value>::type* = 0)
: JsonDocument(_buffer, ACTUAL_CAPACITY) {
: JsonDocument(_buffer, _capacity) {
set(src);
}
// disambiguate
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, ACTUAL_CAPACITY) {
StaticJsonDocument(VariantRef src) : JsonDocument(_buffer, _capacity) {
set(src);
}
@ -45,7 +45,7 @@ class StaticJsonDocument : public JsonDocument {
}
private:
char _buffer[ACTUAL_CAPACITY];
char _buffer[_capacity];
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,16 +1,16 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../Deserialization/deserialize.hpp"
#include "../Memory/MemoryPool.hpp"
#include "../Numbers/isFloat.hpp"
#include "../Numbers/isInteger.hpp"
#include "../Numbers/parseNumber.hpp"
#include "../Polyfills/type_traits.hpp"
#include "../Variant/VariantData.hpp"
#include "EscapeSequence.hpp"
#include "Utf8.hpp"
namespace ARDUINOJSON_NAMESPACE {
@ -18,7 +18,6 @@ template <typename TReader, typename TStringStorage>
class JsonDeserializer {
typedef typename remove_reference<TStringStorage>::type::StringBuilder
StringBuilder;
typedef const char *StringType;
public:
JsonDeserializer(MemoryPool &pool, TReader reader,
@ -123,10 +122,10 @@ class JsonDeserializer {
if (!slot) return DeserializationError::NoMemory;
// Parse key
StringType key;
const char *key;
err = parseKey(key);
if (err) return err;
slot->setOwnedKey(key);
slot->setOwnedKey(make_not_null(key));
// Skip spaces
err = skipSpacesAndComments();
@ -161,7 +160,7 @@ class JsonDeserializer {
}
}
DeserializationError parseKey(StringType &key) {
DeserializationError parseKey(const char *&key) {
if (isQuote(current())) {
return parseQuotedString(key);
} else {
@ -170,14 +169,14 @@ class JsonDeserializer {
}
DeserializationError parseStringValue(VariantData &variant) {
StringType value;
const char *value;
DeserializationError err = parseQuotedString(value);
if (err) return err;
variant.setOwnedString(value);
variant.setOwnedString(make_not_null(value));
return DeserializationError::Ok;
}
DeserializationError parseQuotedString(StringType &result) {
DeserializationError parseQuotedString(const char *&result) {
StringBuilder builder = _stringStorage.startString();
const char stopChar = current();
@ -192,7 +191,18 @@ class JsonDeserializer {
if (c == '\\') {
c = current();
if (c == '\0') return DeserializationError::IncompleteInput;
if (c == 'u') return DeserializationError::NotSupported;
if (c == 'u') {
#if ARDUINOJSON_DECODE_UNICODE
uint16_t codepoint;
move();
DeserializationError err = parseCodepoint(codepoint);
if (err) return err;
Utf8::encodeCodepoint(codepoint, builder);
continue;
#else
return DeserializationError::NotSupported;
#endif
}
// replace char
c = EscapeSequence::unescapeChar(c);
if (c == '\0') return DeserializationError::InvalidInput;
@ -207,7 +217,7 @@ class JsonDeserializer {
return DeserializationError::Ok;
}
DeserializationError parseNonQuotedString(StringType &result) {
DeserializationError parseNonQuotedString(const char *&result) {
StringBuilder builder = _stringStorage.startString();
char c = current();
@ -240,18 +250,51 @@ class JsonDeserializer {
}
buffer[n] = 0;
if (isInteger(buffer)) {
result.setInteger(parseInteger<Integer>(buffer));
} else if (isFloat(buffer)) {
result.setFloat(parseFloat<Float>(buffer));
} else if (!strcmp(buffer, "true")) {
c = buffer[0];
if (c == 't') { // true
result.setBoolean(true);
} else if (!strcmp(buffer, "false")) {
return n == 4 ? DeserializationError::Ok
: DeserializationError::IncompleteInput;
}
if (c == 'f') { // false
result.setBoolean(false);
} else if (!strcmp(buffer, "null")) {
// already null
} else {
return DeserializationError::InvalidInput;
return n == 5 ? DeserializationError::Ok
: DeserializationError::IncompleteInput;
}
if (c == 'n') { // null
// the variant is already null
return n == 4 ? DeserializationError::Ok
: DeserializationError::IncompleteInput;
}
ParsedNumber<Float, UInt> num = parseNumber<Float, UInt>(buffer);
switch (num.type()) {
case VALUE_IS_NEGATIVE_INTEGER:
result.setNegativeInteger(num.uintValue);
return DeserializationError::Ok;
case VALUE_IS_POSITIVE_INTEGER:
result.setPositiveInteger(num.uintValue);
return DeserializationError::Ok;
case VALUE_IS_FLOAT:
result.setFloat(num.floatValue);
return DeserializationError::Ok;
}
return DeserializationError::InvalidInput;
}
DeserializationError parseCodepoint(uint16_t &codepoint) {
codepoint = 0;
for (uint8_t i = 0; i < 4; ++i) {
char digit = current();
if (!digit) return DeserializationError::IncompleteInput;
uint8_t value = decodeHex(digit);
if (value > 0x0F) return DeserializationError::InvalidInput;
codepoint = uint16_t((codepoint << 4) | value);
move();
}
return DeserializationError::Ok;
}
@ -269,6 +312,12 @@ class JsonDeserializer {
return c == '\'' || c == '\"';
}
static inline uint8_t decodeHex(char c) {
if (c < 'A') return uint8_t(c - '0');
c = char(c & ~0x20); // uppercase
return uint8_t(c - 'A' + 10);
}
DeserializationError skipSpacesAndComments() {
for (;;) {
switch (current()) {

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -0,0 +1,26 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
namespace ARDUINOJSON_NAMESPACE {
namespace Utf8 {
template <typename TStringBuilder>
inline void encodeCodepoint(uint16_t codepoint, TStringBuilder &str) {
if (codepoint < 0x80) {
str.append(char(codepoint));
return;
}
if (codepoint >= 0x00000800) {
str.append(char(0xe0 /*0b11100000*/ | (codepoint >> 12)));
str.append(char(((codepoint >> 6) & 0x3f /*0b00111111*/) | 0x80));
} else {
str.append(char(0xc0 /*0b11000000*/ | (codepoint >> 6)));
}
str.append(char((codepoint & 0x3f /*0b00111111*/) | 0x80));
}
} // namespace Utf8
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -91,7 +91,7 @@ class MemoryPool {
return reinterpret_cast<T*>(allocRight(sizeof(T)));
}
char* allocRight(size_t bytes) {
void* allocRight(size_t bytes) {
if (!canAlloc(bytes)) return 0;
_right -= bytes;
return _right;

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -17,7 +17,6 @@ template <typename TReader, typename TStringStorage>
class MsgPackDeserializer {
typedef typename remove_reference<TStringStorage>::type::StringBuilder
StringBuilder;
typedef const char *StringType;
public:
MsgPackDeserializer(MemoryPool &pool, TReader reader,
@ -80,8 +79,7 @@ class MsgPackDeserializer {
#if ARDUINOJSON_USE_LONG_LONG
return readInteger<uint64_t>(variant);
#else
readInteger<uint32_t>();
return readInteger<uint32_t>(variant);
return DeserializationError::NotSupported;
#endif
case 0xd0:
@ -97,8 +95,7 @@ class MsgPackDeserializer {
#if ARDUINOJSON_USE_LONG_LONG
return readInteger<int64_t>(variant);
#else
if (!skip(4)) return DeserializationError::IncompleteInput;
return readInteger<int32_t>(variant);
return DeserializationError::NotSupported;
#endif
case 0xca:
@ -227,20 +224,20 @@ class MsgPackDeserializer {
}
template <typename T>
DeserializationError readString(StringType &str) {
DeserializationError readString(const char *&str) {
T size;
if (!readInteger(size)) return DeserializationError::IncompleteInput;
return readString(str, size);
}
DeserializationError readString(VariantData &variant, size_t n) {
StringType s;
const char *s;
DeserializationError err = readString(s, n);
if (!err) variant.setOwnedString(s);
if (!err) variant.setOwnedString(make_not_null(s));
return err;
}
DeserializationError readString(StringType &result, size_t n) {
DeserializationError readString(const char *&result, size_t n) {
StringBuilder builder = _stringStorage.startString();
for (; n; --n) {
uint8_t c;
@ -287,10 +284,10 @@ class MsgPackDeserializer {
VariantSlot *slot = object.addSlot(_pool);
if (!slot) return DeserializationError::NoMemory;
StringType key;
const char *key;
DeserializationError err = parseKey(key);
if (err) return err;
slot->setOwnedKey(key);
slot->setOwnedKey(make_not_null(key));
err = parse(*slot->data());
if (err) return err;
@ -299,7 +296,7 @@ class MsgPackDeserializer {
return DeserializationError::Ok;
}
DeserializationError parseKey(StringType &key) {
DeserializationError parseKey(const char *&key) {
uint8_t code;
if (!readByte(code)) return DeserializationError::IncompleteInput;

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -24,6 +24,7 @@ class MsgPackSerializer {
}
template <typename T>
ARDUINOJSON_NO_SANITIZE("float-cast-overflow")
typename enable_if<sizeof(T) == 8>::type visitFloat(T value64) {
float value32 = float(value64);
if (value32 == value64) {

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -9,30 +9,33 @@
namespace ARDUINOJSON_NAMESPACE {
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 8>) {
#if ARDUINOJSON_LITTLE_ENDIAN
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 8>) {
swap(p[0], p[7]);
swap(p[1], p[6]);
swap(p[2], p[5]);
swap(p[3], p[4]);
}
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 4>) {
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 4>) {
swap(p[0], p[3]);
swap(p[1], p[2]);
}
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 2>) {
inline void fixEndianess(uint8_t *p, integral_constant<size_t, 2>) {
swap(p[0], p[1]);
}
inline void fixEndianess(uint8_t*, integral_constant<size_t, 1>) {}
inline void fixEndianess(uint8_t *, integral_constant<size_t, 1>) {}
template <typename T>
inline void fixEndianess(T& value) {
#if ARDUINOJSON_LITTLE_ENDIAN
fixEndianess(reinterpret_cast<uint8_t*>(&value),
inline void fixEndianess(T &value) {
fixEndianess(reinterpret_cast<uint8_t *>(&value),
integral_constant<size_t, sizeof(T)>());
#endif
}
#else
template <typename T>
inline void fixEndianess(T &) {}
#endif
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -19,4 +19,5 @@
#define ARDUINOJSON_NAMESPACE \
ARDUINOJSON_CONCAT8(ArduinoJson, ARDUINOJSON_VERSION_MAJOR, \
ARDUINOJSON_VERSION_MINOR, ARDUINOJSON_VERSION_REVISION, \
_, ARDUINOJSON_USE_LONG_LONG, _, ARDUINOJSON_USE_DOUBLE)
_, ARDUINOJSON_USE_LONG_LONG, ARDUINOJSON_USE_DOUBLE, \
ARDUINOJSON_DECODE_UNICODE)

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -7,6 +7,7 @@
#include <stddef.h> // for size_t
#include <stdint.h>
#include "../Configuration.hpp"
#include "../Polyfills/alias_cast.hpp"
#include "../Polyfills/math.hpp"
namespace ARDUINOJSON_NAMESPACE {
@ -16,10 +17,10 @@ struct FloatTraits {};
template <typename T>
struct FloatTraits<T, 8 /*64bits*/> {
typedef int64_t mantissa_type;
typedef uint64_t mantissa_type;
static const short mantissa_bits = 52;
static const mantissa_type mantissa_max =
(static_cast<mantissa_type>(1) << mantissa_bits) - 1;
(mantissa_type(1) << mantissa_bits) - 1;
typedef int16_t exponent_type;
static const exponent_type exponent_max = 308;
@ -94,25 +95,28 @@ struct FloatTraits<T, 8 /*64bits*/> {
return forge(0x7ff00000, 0x00000000);
}
static T highest() {
return forge(0x7FEFFFFF, 0xFFFFFFFF);
}
static T lowest() {
return forge(0xFFEFFFFF, 0xFFFFFFFF);
}
// constructs a double floating point values from its binary representation
// we use this function to workaround platforms with single precision literals
// (for example, when -fsingle-precision-constant is passed to GCC)
static T forge(uint32_t msb, uint32_t lsb) {
union {
uint64_t integerBits;
T floatBits;
};
integerBits = (uint64_t(msb) << 32) | lsb;
return floatBits;
return alias_cast<T>((uint64_t(msb) << 32) | lsb);
}
};
template <typename T>
struct FloatTraits<T, 4 /*32bits*/> {
typedef int32_t mantissa_type;
typedef uint32_t mantissa_type;
static const short mantissa_bits = 23;
static const mantissa_type mantissa_max =
(static_cast<mantissa_type>(1) << mantissa_bits) - 1;
(mantissa_type(1) << mantissa_bits) - 1;
typedef int8_t exponent_type;
static const exponent_type exponent_max = 38;
@ -150,12 +154,7 @@ struct FloatTraits<T, 4 /*32bits*/> {
}
static T forge(uint32_t bits) {
union {
uint32_t integerBits;
T floatBits;
};
integerBits = bits;
return floatBits;
return alias_cast<T>(bits);
}
static T nan() {
@ -165,5 +164,13 @@ struct FloatTraits<T, 4 /*32bits*/> {
static T inf() {
return forge(0x7f800000);
}
static T highest() {
return forge(0x7f7fffff);
}
static T lowest() {
return forge(0xFf7fffff);
}
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -0,0 +1,105 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wconversion"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#include "../Polyfills/limits.hpp"
#include "Float.hpp"
#include "FloatTraits.hpp"
#include "Integer.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename TOut, typename TIn>
typename enable_if<is_integral<TOut>::value && sizeof(TOut) <= sizeof(TIn),
bool>::type
canStorePositiveInteger(TIn value) {
return value <= TIn(numeric_limits<TOut>::highest());
}
template <typename TOut, typename TIn>
typename enable_if<is_integral<TOut>::value && sizeof(TIn) < sizeof(TOut),
bool>::type
canStorePositiveInteger(TIn) {
return true;
}
template <typename TOut, typename TIn>
typename enable_if<is_floating_point<TOut>::value, bool>::type
canStorePositiveInteger(TIn) {
return true;
}
template <typename TOut, typename TIn>
typename enable_if<is_floating_point<TOut>::value, bool>::type
canStoreNegativeInteger(TIn) {
return true;
}
template <typename TOut, typename TIn>
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
sizeof(TOut) <= sizeof(TIn),
bool>::type
canStoreNegativeInteger(TIn value) {
return value <= TIn(numeric_limits<TOut>::highest()) + 1;
}
template <typename TOut, typename TIn>
typename enable_if<is_integral<TOut>::value && is_signed<TOut>::value &&
sizeof(TIn) < sizeof(TOut),
bool>::type
canStoreNegativeInteger(TIn) {
return true;
}
template <typename TOut, typename TIn>
typename enable_if<is_integral<TOut>::value && is_unsigned<TOut>::value,
bool>::type
canStoreNegativeInteger(TIn) {
return false;
}
template <typename TOut, typename TIn>
TOut convertPositiveInteger(TIn value) {
return canStorePositiveInteger<TOut>(value) ? TOut(value) : 0;
}
template <typename TOut, typename TIn>
TOut convertNegativeInteger(TIn value) {
return canStoreNegativeInteger<TOut>(value) ? TOut(~value + 1) : 0;
}
template <typename TOut, typename TIn>
typename enable_if<is_floating_point<TOut>::value, TOut>::type convertFloat(
TIn value) {
return TOut(value);
}
template <typename TOut, typename TIn>
typename enable_if<!is_floating_point<TOut>::value, TOut>::type convertFloat(
TIn value) {
return value >= numeric_limits<TOut>::lowest() &&
value <= numeric_limits<TOut>::highest()
? TOut(value)
: 0;
}
} // namespace ARDUINOJSON_NAMESPACE
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

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

View File

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

View File

@ -1,88 +1,18 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../Numbers/FloatTraits.hpp"
#include "../Polyfills/ctype.hpp"
#include "../Polyfills/math.hpp"
#include "convertNumber.hpp"
#include "parseNumber.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename T>
inline T parseFloat(const char* s) {
typedef FloatTraits<T> traits;
typedef typename traits::mantissa_type mantissa_t;
typedef typename traits::exponent_type exponent_t;
if (!s) return 0; // NULL
bool negative_result = false;
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;
}
if (*s == 't') return 1; // true
if (*s == 'n' || *s == 'N') return traits::nan();
if (*s == 'i' || *s == 'I')
return negative_result ? -traits::inf() : traits::inf();
mantissa_t mantissa = 0;
exponent_t exponent_offset = 0;
while (isdigit(*s)) {
if (mantissa < traits::mantissa_max / 10)
mantissa = mantissa * 10 + (*s - '0');
else
exponent_offset++;
s++;
}
if (*s == '.') {
s++;
while (isdigit(*s)) {
if (mantissa < traits::mantissa_max / 10) {
mantissa = mantissa * 10 + (*s - '0');
exponent_offset--;
}
s++;
}
}
int exponent = 0;
if (*s == 'e' || *s == 'E') {
s++;
bool negative_exponent = false;
if (*s == '-') {
negative_exponent = true;
s++;
} else if (*s == '+') {
s++;
}
while (isdigit(*s)) {
exponent = exponent * 10 + (*s - '0');
if (exponent + exponent_offset > traits::exponent_max) {
if (negative_exponent)
return negative_result ? -0.0f : 0.0f;
else
return negative_result ? -traits::inf() : traits::inf();
}
s++;
}
if (negative_exponent) exponent = -exponent;
}
exponent += exponent_offset;
T result = traits::make_float(static_cast<T>(mantissa), exponent);
return negative_result ? -result : result;
// try to reuse the same parameters as JsonDeserializer
typedef typename choose_largest<Float, T>::type TFloat;
return parseNumber<TFloat, UInt>(s).template as<T>();
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,37 +1,19 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../Configuration.hpp"
#include "../Polyfills/ctype.hpp"
#include "../Polyfills/type_traits.hpp"
#include "convertNumber.hpp"
#include "parseNumber.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename T>
T parseInteger(const char *s) {
if (!s) return 0; // NULL
if (*s == 't') return 1; // "true"
T result = 0;
bool negative_result = false;
switch (*s) {
case '-':
negative_result = true;
s++;
break;
case '+':
s++;
break;
}
while (isdigit(*s)) {
result = T(result * 10 + T(*s - '0'));
s++;
}
return negative_result ? T(~result + 1) : result;
// try to reuse the same parameters as JsonDeserializer
typedef typename choose_largest<UInt, typename make_unsigned<T>::type>::type
TUInt;
return parseNumber<Float, TUInt>(s).template as<T>();
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -0,0 +1,150 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../Polyfills/assert.hpp"
#include "../Polyfills/ctype.hpp"
#include "../Polyfills/math.hpp"
#include "../Polyfills/type_traits.hpp"
#include "../Variant/VariantContent.hpp"
#include "FloatTraits.hpp"
#include "convertNumber.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename TFloat, typename TUInt>
struct ParsedNumber {
ParsedNumber() : uintValue(0), floatValue(0), _type(VALUE_IS_NULL) {}
ParsedNumber(TUInt value, bool is_negative)
: uintValue(value),
floatValue(TFloat(value)),
_type(uint8_t(is_negative ? VALUE_IS_NEGATIVE_INTEGER
: VALUE_IS_POSITIVE_INTEGER)) {}
ParsedNumber(TFloat value) : floatValue(value), _type(VALUE_IS_FLOAT) {}
template <typename T>
T as() const {
switch (_type) {
case VALUE_IS_NEGATIVE_INTEGER:
return convertNegativeInteger<T>(uintValue);
case VALUE_IS_POSITIVE_INTEGER:
return convertPositiveInteger<T>(uintValue);
case VALUE_IS_FLOAT:
return convertFloat<T>(floatValue);
default:
return 0;
}
}
uint8_t type() const {
return _type;
}
TUInt uintValue;
TFloat floatValue;
uint8_t _type;
};
template <typename A, typename B>
struct choose_largest : conditional<(sizeof(A) > sizeof(B)), A, B> {};
template <typename TFloat, typename TUInt>
inline ParsedNumber<TFloat, TUInt> parseNumber(const char *s) {
typedef FloatTraits<TFloat> traits;
typedef typename choose_largest<typename traits::mantissa_type, TUInt>::type
mantissa_t;
typedef typename traits::exponent_type exponent_t;
typedef ParsedNumber<TFloat, TUInt> return_type;
ARDUINOJSON_ASSERT(s != 0);
bool is_negative = false;
switch (*s) {
case '-':
is_negative = true;
s++;
break;
case '+':
s++;
break;
}
if (*s == 'n' || *s == 'N') return traits::nan();
if (*s == 'i' || *s == 'I')
return is_negative ? -traits::inf() : traits::inf();
if (!isdigit(*s) && *s != '.') return return_type();
mantissa_t mantissa = 0;
exponent_t exponent_offset = 0;
const mantissa_t maxUint = TUInt(-1);
while (isdigit(*s)) {
uint8_t digit = uint8_t(*s - '0');
if (mantissa > maxUint / 10) break;
mantissa *= 10;
if (mantissa > maxUint - digit) break;
mantissa += digit;
s++;
}
if (*s == '\0') return return_type(TUInt(mantissa), is_negative);
// avoid mantissa overflow
while (mantissa > traits::mantissa_max) {
mantissa /= 10;
exponent_offset++;
}
// remaing digits can't fit in the mantissa
while (isdigit(*s)) {
exponent_offset++;
s++;
}
if (*s == '.') {
s++;
while (isdigit(*s)) {
if (mantissa < traits::mantissa_max / 10) {
mantissa = mantissa * 10 + uint8_t(*s - '0');
exponent_offset--;
}
s++;
}
}
int exponent = 0;
if (*s == 'e' || *s == 'E') {
s++;
bool negative_exponent = false;
if (*s == '-') {
negative_exponent = true;
s++;
} else if (*s == '+') {
s++;
}
while (isdigit(*s)) {
exponent = exponent * 10 + (*s - '0');
if (exponent + exponent_offset > traits::exponent_max) {
if (negative_exponent)
return is_negative ? -0.0f : 0.0f;
else
return is_negative ? -traits::inf() : traits::inf();
}
s++;
}
if (negative_exponent) exponent = -exponent;
}
exponent += exponent_offset;
// we should be at the end of the string, otherwise it's an error
if (*s != '\0') return return_type();
TFloat result = traits::make_float(static_cast<TFloat>(mantissa), exponent);
return is_negative ? -result : result;
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -25,53 +25,80 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
: _object(variant), _key(key) {}
FORCE_INLINE operator VariantConstRef() const {
return getMember();
return getUpstreamMember();
}
FORCE_INLINE this_type &operator=(const this_type &src) {
getOrCreateMember().set(src);
getOrAddUpstreamMember().set(src);
return *this;
}
template <typename TValue>
FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type
operator=(const TValue &src) {
getOrCreateMember().set(src);
getOrAddUpstreamMember().set(src);
return *this;
}
// operator=(char*) const
// operator=(const char*) const
// operator=(const __FlashStringHelper*) const
// operator=(char*)
// operator=(const char*)
// operator=(const __FlashStringHelper*)
template <typename TChar>
FORCE_INLINE this_type &operator=(TChar *src) {
getOrCreateMember().set(src);
getOrAddUpstreamMember().set(src);
return *this;
}
FORCE_INLINE void clear() const {
getUpstreamMember().clear();
}
FORCE_INLINE bool isNull() const {
return getMember().isNull();
return getUpstreamMember().isNull();
}
template <typename TValue>
FORCE_INLINE typename VariantAs<TValue>::type as() const {
return getMember().template as<TValue>();
return getUpstreamMember().template as<TValue>();
}
template <typename TValue>
FORCE_INLINE bool is() const {
return getMember().template is<TValue>();
return getUpstreamMember().template is<TValue>();
}
FORCE_INLINE size_t size() const {
return getUpstreamMember().size();
}
FORCE_INLINE void remove(size_t index) const {
getUpstreamMember().remove(index);
}
// remove(char*) const
// remove(const char*) const
// remove(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar *>::value>::type remove(
TChar *key) const {
getUpstreamMember().remove(key);
}
// remove(const std::string&) const
// remove(const String&) const
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value>::type remove(
const TString &key) const {
getUpstreamMember().remove(key);
}
template <typename TValue>
FORCE_INLINE typename VariantTo<TValue>::type to() {
return getOrCreateMember().template to<TValue>();
return getOrAddUpstreamMember().template to<TValue>();
}
template <typename TValue>
FORCE_INLINE typename enable_if<!is_array<TValue>::value, bool>::type set(
const TValue &value) {
return getOrCreateMember().set(value);
return getOrAddUpstreamMember().set(value);
}
// set(char*) const
@ -79,56 +106,60 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >,
// set(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE bool set(const TChar *value) {
return getOrCreateMember().set(value);
return getOrAddUpstreamMember().set(value);
}
template <typename Visitor>
void accept(Visitor &visitor) const {
return getMember().accept(visitor);
return getUpstreamMember().accept(visitor);
}
using ArrayShortcuts<MemberProxy>::add;
FORCE_INLINE VariantRef add() const {
return getOrCreateMember().add();
FORCE_INLINE VariantRef addElement() const {
return getOrAddUpstreamMember().addElement();
}
// get(char*) const
// get(const char*) const
// get(const __FlashStringHelper*) const
// getElement(size_t) const
FORCE_INLINE VariantRef getElement(size_t index) const {
return getUpstreamMember().getElement(index);
}
// getMember(char*) const
// getMember(const char*) const
// getMember(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantRef get(TChar *key) const {
return getMember().get(key);
FORCE_INLINE VariantRef getMember(TChar *key) const {
return getUpstreamMember().getMember(key);
}
// get(const std::string&) const
// get(const String&) const
// getMember(const std::string&) const
// getMember(const String&) const
template <typename TString>
FORCE_INLINE VariantRef get(const TString &key) const {
return getMember().get(key);
FORCE_INLINE VariantRef getMember(const TString &key) const {
return getUpstreamMember().getMember(key);
}
// getOrCreate(char*) const
// getOrCreate(const char*) const
// getOrCreate(const __FlashStringHelper*) const
// getOrAddMember(char*) const
// getOrAddMember(const char*) const
// getOrAddMember(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantRef getOrCreate(TChar *key) const {
return getOrCreateMember().getOrCreate(key);
FORCE_INLINE VariantRef getOrAddMember(TChar *key) const {
return getOrAddUpstreamMember().getOrAddMember(key);
}
// getOrCreate(const std::string&) const
// getOrCreate(const String&) const
// getOrAddMember(const std::string&) const
// getOrAddMember(const String&) const
template <typename TString>
FORCE_INLINE VariantRef getOrCreate(const TString &key) const {
return getOrCreateMember().getOrCreate(key);
FORCE_INLINE VariantRef getOrAddMember(const TString &key) const {
return getOrAddUpstreamMember().getOrAddMember(key);
}
private:
FORCE_INLINE VariantRef getMember() const {
return _object.get(_key);
FORCE_INLINE VariantRef getUpstreamMember() const {
return _object.getMember(_key);
}
FORCE_INLINE VariantRef getOrCreateMember() const {
return _object.getOrCreate(_key);
FORCE_INLINE VariantRef getOrAddUpstreamMember() const {
return _object.getOrAddMember(_key);
}
TObject _object;

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -16,11 +16,6 @@ void objectAccept(const CollectionData *obj, Visitor &visitor) {
visitor.visitNull();
}
template <typename TAdaptedString>
inline bool objectContainsKey(const CollectionData *obj, TAdaptedString key) {
return obj && obj->containsKey(key);
}
inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) {
if (lhs == rhs) return true;
if (!lhs || !rhs) return false;

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -13,26 +13,40 @@ template <typename TObject>
template <typename TString>
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(
const TString& key) const {
return impl()->getOrCreate(key).template to<ArrayRef>();
return impl()->getOrAddMember(key).template to<ArrayRef>();
}
template <typename TObject>
template <typename TChar>
inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const {
return impl()->getOrCreate(key).template to<ArrayRef>();
return impl()->getOrAddMember(key).template to<ArrayRef>();
}
template <typename TObject>
template <typename TString>
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
const TString& key) const {
return impl()->getOrCreate(key).template to<ObjectRef>();
return impl()->getOrAddMember(key).template to<ObjectRef>();
}
template <typename TObject>
template <typename TChar>
inline ObjectRef ObjectShortcuts<TObject>::createNestedObject(
TChar* key) const {
return impl()->getOrCreate(key).template to<ObjectRef>();
return impl()->getOrAddMember(key).template to<ObjectRef>();
}
template <typename TObject>
template <typename TString>
inline typename enable_if<IsString<TString>::value, bool>::type
ObjectShortcuts<TObject>::containsKey(const TString& key) const {
return !impl()->getMember(key).isUndefined();
}
template <typename TObject>
template <typename TChar>
inline typename enable_if<IsString<TChar*>::value, bool>::type
ObjectShortcuts<TObject>::containsKey(TChar* key) const {
return !impl()->getMember(key).isUndefined();
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -18,7 +18,8 @@ template <typename TData>
class ObjectRefBase {
public:
operator VariantConstRef() const {
return VariantConstRef(reinterpret_cast<const VariantData*>(_data));
const void* data = _data; // prevent warning cast-align
return VariantConstRef(reinterpret_cast<const VariantData*>(data));
}
template <typename Visitor>
@ -26,21 +27,6 @@ class ObjectRefBase {
objectAccept(_data, visitor);
}
// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
FORCE_INLINE bool containsKey(const TString& key) const {
return objectContainsKey(_data, adaptString(key));
}
// containsKey(char*) const
// containsKey(const char*) const
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE bool containsKey(TChar* key) const {
return objectContainsKey(_data, adaptString(key));
}
FORCE_INLINE bool isNull() const {
return _data == 0;
}
@ -82,18 +68,33 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>,
return iterator();
}
// get(const std::string&) const
// get(const String&) const
// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
FORCE_INLINE VariantConstRef get(const TString& key) const {
FORCE_INLINE bool containsKey(const TString& key) const {
return !getMember(key).isUndefined();
}
// containsKey(char*) const
// containsKey(const char*) const
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE bool containsKey(TChar* key) const {
return !getMember(key).isUndefined();
}
// getMember(const std::string&) const
// getMember(const String&) const
template <typename TString>
FORCE_INLINE VariantConstRef getMember(const TString& key) const {
return get_impl(adaptString(key));
}
// get(char*) const
// get(const char*) const
// get(const __FlashStringHelper*) const
// getMember(char*) const
// getMember(const char*) const
// getMember(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantConstRef get(TChar* key) const {
FORCE_INLINE VariantConstRef getMember(TChar* key) const {
return get_impl(adaptString(key));
}
@ -140,7 +141,8 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
: base_type(data), _pool(buf) {}
operator VariantRef() const {
return VariantRef(_pool, reinterpret_cast<VariantData*>(_data));
void* data = _data; // prevent warning cast-align
return VariantRef(_pool, reinterpret_cast<VariantData*>(data));
}
operator ObjectConstRef() const {
@ -161,38 +163,38 @@ class ObjectRef : public ObjectRefBase<CollectionData>,
_data->clear();
}
FORCE_INLINE bool copyFrom(ObjectConstRef src) {
FORCE_INLINE bool set(ObjectConstRef src) {
if (!_data || !src._data) return false;
return _data->copyFrom(*src._data, _pool);
}
// get(const std::string&) const
// get(const String&) const
// getMember(const std::string&) const
// getMember(const String&) const
template <typename TString>
FORCE_INLINE VariantRef get(const TString& key) const {
FORCE_INLINE VariantRef getMember(const TString& key) const {
return get_impl(adaptString(key));
}
// get(char*) const
// get(const char*) const
// get(const __FlashStringHelper*) const
// getMember(char*) const
// getMember(const char*) const
// getMember(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantRef get(TChar* key) const {
FORCE_INLINE VariantRef getMember(TChar* key) const {
return get_impl(adaptString(key));
}
// getOrCreate(const std::string&) const
// getOrCreate(const String&) const
// getOrAddMember(const std::string&) const
// getOrAddMember(const String&) const
template <typename TString>
FORCE_INLINE VariantRef getOrCreate(const TString& key) const {
FORCE_INLINE VariantRef getOrAddMember(const TString& key) const {
return getOrCreate_impl(adaptString(key));
}
// getOrCreate(char*) const
// getOrCreate(const char*) const
// getOrCreate(const __FlashStringHelper*) const
// getOrAddMember(char*) const
// getOrAddMember(const char*) const
// getOrAddMember(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE VariantRef getOrCreate(TChar* key) const {
FORCE_INLINE VariantRef getOrAddMember(TChar* key) const {
return getOrCreate_impl(adaptString(key));
}

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -15,6 +15,19 @@ class MemberProxy;
template <typename TObject>
class ObjectShortcuts {
public:
// containsKey(const std::string&) const
// containsKey(const String&) const
template <typename TString>
FORCE_INLINE typename enable_if<IsString<TString>::value, bool>::type
containsKey(const TString &key) const;
// containsKey(char*) const
// containsKey(const char*) const
// containsKey(const __FlashStringHelper*) const
template <typename TChar>
FORCE_INLINE typename enable_if<IsString<TChar *>::value, bool>::type
containsKey(TChar *key) const;
// operator[](const std::string&) const
// operator[](const String&) const
template <typename TString>

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -0,0 +1,28 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include <stdint.h>
#include <stdlib.h> // for size_t
#include "../Configuration.hpp"
#include "../Polyfills/math.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename T, typename F>
struct alias_cast_t {
union {
F raw;
T data;
};
};
template <typename T, typename F>
T alias_cast(F raw_data) {
alias_cast_t<T, F> ac;
ac.raw = raw_data;
return ac.data;
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
@ -33,3 +33,13 @@
#else
#define NOEXCEPT throw()
#endif
#if defined(__has_attribute)
#if __has_attribute(no_sanitize)
#define ARDUINOJSON_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
#else
#define ARDUINOJSON_NO_SANITIZE(check)
#endif
#else
#define ARDUINOJSON_NO_SANITIZE(check)
#endif

View File

@ -1,5 +1,5 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once

View File

@ -0,0 +1,33 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../assert.hpp"
namespace ARDUINOJSON_NAMESPACE {
template <typename T>
class not_null {
public:
explicit not_null(T ptr) : _ptr(ptr) {
ARDUINOJSON_ASSERT(ptr != NULL);
}
T get() const {
ARDUINOJSON_ASSERT(_ptr != NULL);
return _ptr;
}
private:
T _ptr;
};
template <typename T>
not_null<T> make_not_null(T ptr) {
ARDUINOJSON_ASSERT(ptr != NULL);
return not_null<T>(ptr);
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@ -0,0 +1,45 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2019
// MIT License
#pragma once
#include "../Polyfills/type_traits.hpp"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4310)
#endif
namespace ARDUINOJSON_NAMESPACE {
// Differs from standard because we can't use the symbols "min" and "max"
template <typename T, typename Enable = void>
struct numeric_limits;
template <typename T>
struct numeric_limits<T, typename enable_if<is_unsigned<T>::value>::type> {
static T lowest() {
return 0;
}
static T highest() {
return T(-1);
}
};
template <typename T>
struct numeric_limits<
T, typename enable_if<is_integral<T>::value && is_signed<T>::value>::type> {
static T lowest() {
return T(T(1) << (sizeof(T) * 8 - 1));
}
static T highest() {
return T(~lowest());
}
};
} // namespace ARDUINOJSON_NAMESPACE
#ifdef _MSC_VER
#pragma warning(pop)
#endif

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