Compare commits

...

36 Commits

Author SHA1 Message Date
4e9f0b2e2e Set version to 5.9.0 2017-04-24 21:43:03 +02:00
223f14710d Now compatible with Particle 0.6.1 (issue #294 and PR #461 by @foodbag) 2017-04-24 21:40:19 +02:00
f7ae91b85d Removed unused stuffs 2017-04-22 11:35:55 +02:00
445dff499b ctest --output-on-failure 2017-04-22 11:34:12 +02:00
9afa05e2f4 Removed Print class and converted printTo() to a template method (issue #276) 2017-04-22 11:33:40 +02:00
c3e1677b7d Fixed warnings floating constant exceeds range of floatand floating constant truncated to zero (issue #483) 2017-04-20 14:46:52 +02:00
024976cda2 Renamed folder include/ to src/ (issue #461) 2017-04-20 10:26:40 +02:00
df541a2a22 Changed unit testing framework from Google Test to Catch 2017-04-18 18:22:24 +02:00
f2ef338cb8 Renamed JsonArray::removeAt() into remove() 2017-04-12 21:07:30 +02:00
8c6f64c111 Added JsonArray::remove(iterator) and JsonObject::remove(iterator) (issue #479) 2017-04-12 21:00:13 +02:00
5a16b2117b Travis: Disabled Teensy (PlatformioException: Could not load broken JSON) 2017-04-10 18:55:24 +02:00
71edcaf20f Split unit test into several executables 2017-04-10 15:36:59 +02:00
ac89d91db5 Organized test files in subfolders 2017-04-10 14:32:45 +02:00
e664c1ab05 Set version to 5.8.4 2017-03-26 21:33:12 +02:00
adba668109 Updated project URL 2017-03-25 22:05:06 +01:00
ad972725de Added a script to build a single file distribution 2017-03-25 21:56:37 +01:00
185eccf6f5 Added custom implementation of strtol() (issue #465)
`char` is now treated as an integral type (issue #337, #370)
2017-03-25 21:55:13 +01:00
c4567bac18 Added custom implementation of strtod() (issue #453) 2017-03-19 15:23:06 +01:00
13409c433a Added OpenEVSE LLC to the list of donators 2017-02-22 18:15:21 +01:00
20431debe0 Fuzzing: Run serializer too 2017-02-19 21:41:12 +01:00
797ea356ef Fuzzing: Better seed corpus 2017-02-19 21:30:22 +01:00
2321473c34 Added Prokhoryatov Alexey to the list of donators 2017-02-19 21:01:26 +01:00
0d5f65c5f3 Set version to 5.8.3 2017-02-11 15:12:03 +01:00
c30241775a Fixed JsonVariant::operator[const FlashStringHelper*] (issue #441) 2017-02-11 15:09:08 +01:00
31827d03f9 Added operators == and != for two JsonVariants (issue #436) 2017-02-11 15:06:17 +01:00
7bcdf3e722 JsonHttpClient: Close socket even when connection fails (issue #445) 2017-02-11 14:01:14 +01:00
db9a76f7c6 Fixed an access violation in DynamicJsonBuffer when memory allocation fails (issue #433) 2017-01-31 10:06:40 +01:00
3fd87e8e82 Added fuzzing/ to .mbedignore 2017-01-25 15:28:15 +01:00
22a2786610 Added Christoph Schmidt to the list of donators 2017-01-24 21:21:05 +01:00
2b5a6df1e1 Set version to 5.8.2 2017-01-22 18:08:32 +01:00
5fefeae404 Added deprecated attribute on asArray(), asObject() and asString() (issue #420) 2017-01-22 17:24:17 +01:00
d4f725d1fa Fixed error with string of type unsigned char* (issue #428) 2017-01-22 15:42:47 +01:00
a096098c1f Fixed error when the key of a JsonObject is a char[] and reduced code size when using const references (issue #423) 2017-01-22 11:10:45 +01:00
cc8c0472ca Fixed ignored Stream timeout and made sure we don't read more that necessary (issue #422) 2017-01-22 10:31:05 +01:00
fb554071dc Travis: Added -fsanitize to several builds 2017-01-21 19:49:44 +01:00
17a17c8957 Fixed parsing of comments (issue #421) 2017-01-17 21:48:13 +01:00
432 changed files with 18724 additions and 150945 deletions

View File

@ -2,10 +2,10 @@
Thanks for using ArduinoJson :-)
Before opening an issue, please make sure you've read these:
https://github.com/bblanchon/ArduinoJson/wiki/FAQ
https://github.com/bblanchon/ArduinoJson/wiki/Avoiding-pitfalls
https://bblanchon.github.io/ArduinoJson/faq/
https://bblanchon.github.io/ArduinoJson/doc/pitfalls/
Next, make sure you provide all the relevant information: platform, code snippet, and error messages.
Please be concise!
-->
-->

View File

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

View File

@ -7,103 +7,97 @@ matrix:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.4']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.4
env: SCRIPT=cmake GCC=4.4
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.5']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.5
env: SCRIPT=cmake GCC=4.5
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.6']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.6
env: SCRIPT=cmake GCC=4.6
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.7']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.7
env: SCRIPT=cmake GCC=4.7
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.8
env: SCRIPT=cmake GCC=4.8 SANITIZE=address
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.9
env: SCRIPT=cmake GCC=4.9 SANITIZE=leak
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-5
env: SCRIPT=cmake GCC=5 SANITIZE=undefined
- compiler: clang
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++
env: SCRIPT=cmake
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
packages: ['clang-3.5']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.5
env: SCRIPT=cmake CLANG=3.5 SANITIZE=address
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
packages: ['clang-3.6']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.6
env: SCRIPT=cmake CLANG=3.6 SANITIZE=leak
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
packages: ['clang-3.7']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.7
env: SCRIPT=cmake CLANG=3.7
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
packages: ['clang-3.8']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.8
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
packages: ['clang-3.8']
env: SCRIPT=sanitize CMAKE_CXX_COMPILER=clang++-3.8
env: SCRIPT=cmake CLANG=3.8 SANITIZE=undefined
- compiler: gcc
env: SCRIPT=coverage
- os: osx
osx_image: xcode6.4
compiler: clang
env: SCRIPT=cmake-osx
env: SCRIPT=cmake
- os: osx
osx_image: xcode7
compiler: clang
env: SCRIPT=cmake-osx
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.1
compiler: clang
env: SCRIPT=cmake-osx
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.2
compiler: clang
env: SCRIPT=cmake-osx
env: SCRIPT=cmake
- os: osx
osx_image: xcode7.3
compiler: clang
env: SCRIPT=cmake-osx
env: SCRIPT=cmake SANITIZE=address
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.6.12 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.8.2 BOARD=arduino:avr:uno
- env: SCRIPT=platformio BOARD=uno
- env: SCRIPT=platformio BOARD=due
- env: SCRIPT=platformio BOARD=esp01
- env: SCRIPT=platformio BOARD=teensy31
#- env: SCRIPT=platformio BOARD=teensy31C
cache:
directories:
- "~/.platformio"

View File

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

View File

@ -1,6 +1,43 @@
ArduinoJson: change log
=======================
v5.9.0
------
* Added `JsonArray::remove(iterator)` (issue #479)
* Added `JsonObject::remove(iterator)`
* Renamed `JsonArray::removeAt(size_t)` into `remove(size_t)`
* Renamed folder `include/` to `src/`
* Fixed warnings `floating constant exceeds range of float`and `floating constant truncated to zero` (issue #483)
* Removed `Print` class and converted `printTo()` to a template method (issue #276)
* Removed example `IndentedPrintExample.ino`
* Now compatible with Particle 0.6.1, thanks to Jacob Nite (issue #294 and PR #461 by @foodbag)
v5.8.4
------
* Added custom implementation of `strtod()` (issue #453)
* Added custom implementation of `strtol()` (issue #465)
* `char` is now treated as an integral type (issue #337, #370)
v5.8.3
------
* Fixed an access violation in `DynamicJsonBuffer` when memory allocation fails (issue #433)
* Added operators `==` and `!=` for two `JsonVariant`s (issue #436)
* Fixed `JsonVariant::operator[const FlashStringHelper*]` (issue #441)
v5.8.2
------
* Fixed parsing of comments (issue #421)
* Fixed ignored `Stream` timeout (issue #422)
* Made sure we don't read more that necessary (issue #422)
* Fixed error when the key of a `JsonObject` is a `char[]` (issue #423)
* Reduced code size when using `const` references
* Fixed error with string of type `unsigned char*` (issue #428)
* Added `deprecated` attribute on `asArray()`, `asObject()` and `asString()` (issue #420)
v5.8.1
------

View File

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

View File

@ -1,4 +1,4 @@
Arduino JSON library
ArduinoJson - C++ JSON library for IoT
====================
[![Build status](https://ci.appveyor.com/api/projects/status/m7s53wav1l0abssg/branch/master?svg=true)](https://ci.appveyor.com/project/bblanchon/arduinojson/branch/master) [![Build Status](https://travis-ci.org/bblanchon/ArduinoJson.svg?branch=master)](https://travis-ci.org/bblanchon/ArduinoJson) [![Coverage Status](https://img.shields.io/coveralls/bblanchon/ArduinoJson.svg)](https://coveralls.io/r/bblanchon/ArduinoJson?branch=master) [![Star this project](http://githubbadges.com/star.svg?user=bblanchon&repo=ArduinoJson&style=flat&color=fff&background=007ec6)](https://github.com/bblanchon/ArduinoJson)
@ -36,8 +36,6 @@ Works on
* RedBearLab boards (BLE Nano...)
* Computers (Windows, Linux, OSX...)
See [FAQ: Compatibility issues](https://github.com/bblanchon/ArduinoJson/wiki/Compatibility-issues)
Quick start
-----------
@ -82,7 +80,10 @@ root.printTo(Serial);
Documentation
-------------
The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)
The documentation is available online in the [ArduinoJson Website](https://bblanchon.github.io/ArduinoJson/).
The [ArduinoJson Assistant](https://bblanchon.github.io/ArduinoJson/assistant/) helps you get started with the library.
Testimonials
------------
@ -133,6 +134,9 @@ Special thanks to the following persons and companies who made generous donation
* Yoeri Kroon <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Andrew Melvin <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
* Doanh Luong <img alt ='Vietnam' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fb-1f1f3.svg' width='18' height='18'>
* Christoph Schmidt <img alt='Germany' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e9-1f1ea.svg' width='18' height='18'>
* OpenEVSE LLC <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Prokhoryatov Alexey <img alt='Russia' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f7-1f1fa.svg' width='18' height='18'>
---

View File

@ -1,4 +1,4 @@
version: 5.8.1.{build}
version: 5.9.0.{build}
environment:
matrix:
- CMAKE_GENERATOR: Visual Studio 14 2015
@ -15,4 +15,4 @@ before_build:
build_script:
- cmake --build . --config %CONFIGURATION%
test_script:
- ctest -V .
- ctest --output-on-failure .

View File

@ -1,35 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
using namespace ArduinoJson::Internals;
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
IndentedPrint serial(Serial);
serial.setTabSize(4);
serial.println("This is at indentation 0");
serial.indent();
serial.println("This is at indentation 1");
serial.println("This is also at indentation 1");
serial.indent();
serial.println("This is at indentation 2");
serial.unindent();
serial.unindent();
serial.println("This is back at indentation 0");
}
void loop() {
// not used in this example
}

View File

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

View File

@ -5,7 +5,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#include <ArduinoJson.h>
@ -41,8 +41,8 @@ void loop() {
printUserData(&userData);
}
}
disconnect();
}
disconnect();
wait();
}

View File

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

View File

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

View File

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

View File

@ -1,13 +1,13 @@
# CAUTION: this file is invoked by https://github.com/google/oss-fuzz
CXXFLAGS += -I../include
CXXFLAGS += -I../src
all: \
$(OUT)/json_fuzzer \
$(OUT)/json_fuzzer_seed_corpus.zip \
$(OUT)/json_fuzzer.options
$(OUT)/json_fuzzer: fuzzer.cpp
$(OUT)/json_fuzzer: fuzzer.cpp $(shell find ../src -type f)
$(CXX) $(CXXFLAGS) $< -o$@ $(LIB_FUZZING_ENGINE)
$(OUT)/json_fuzzer_seed_corpus.zip: seed_corpus/*

View File

@ -1,8 +1,9 @@
#!/bin/bash
# This script mimics an invocation from https://github.com/google/oss-fuzz
cd $(dirname $0)
export CXX='clang++'
export CXXFLAGS='-fsanitize-coverage=trace-pc-guard -fsanitize=address'
export LIB_FUZZING_ENGINE=-lFuzzer
make OUT=.
./json_fuzzer my_corpus seed_corpus
./json_fuzzer my_corpus seed_corpus -max_len=1024 -timeout=10

View File

@ -18,6 +18,9 @@ class memstream : public std::istream {
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
DynamicJsonBuffer jsonBuffer;
memstream json(data, size);
jsonBuffer.parse(json);
JsonVariant variant = jsonBuffer.parse(json);
if (variant.success()) {
variant.as<std::string>(); // <- serialize to JSON
}
return 0;
}

View File

@ -1,8 +0,0 @@
{
"sensor": "gps",
"time": 1351824120,
"data": [
48.75608,
2.302038
]
}

View File

@ -0,0 +1,10 @@
//comment
/*comment*/
[ //comment
/*comment*/"comment"/*comment*/,//comment
/*comment*/{//comment
/* comment*/"key"//comment
: //comment
"value"//comment
}/*comment*/
]//comment

View File

@ -0,0 +1 @@
[]

View File

@ -0,0 +1 @@
{}

View File

@ -0,0 +1 @@
[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20,[21,[22,[23,[24,[25,[26,[27,[28,[29,[30,[31,[32,[33,[34,[35,[36,[37,[38,[39,[40,[41,[42,[43,[44,[45,[46,[47,[48,[49,[50,[51,[52,[53,[54,[55,[56,[57,[58,[59,[60,[61,[62,[63,[64,[65,[66,[67,[68,[69,[70,[71,[72,[73,[74,[75,[76,[77,[78,[79,[80,[81,[82,[83,[84,[85,[86,[87,[88,[89,[90,[91,[92,[93,[94,[95,[96,[97,[98,[99,[100,[101,[102,[103,[104,[105,[106,[107,[108,[109,[110,[111,[112,[113,[114,[115,[116,[117,[118,[119,[120]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

View File

@ -0,0 +1,24 @@
[
123,
-123,
123.456,
-123.456,
12e34,
12e-34,
12e+34,
12E34,
12E-34,
12E+34,
12.34e56,
12.34e-56,
12.34e+56,
12.34E56,
12.34E-56,
12.34E+56,
NaN,
-NaN,
+NaN,
Infinity,
+Infinity,
-Infinity
]

View File

@ -0,0 +1,8 @@
[
"hello",
'hello',
hello,
{"hello":"world"},
{'hello':'world'},
{hello:world}
]

View File

@ -1,66 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include <stdlib.h>
namespace ArduinoJson {
namespace Internals {
template <typename TFloat>
TFloat parse(const char *);
template <>
inline float parse<float>(const char *s) {
return static_cast<float>(strtod(s, NULL));
}
template <>
inline double parse<double>(const char *s) {
return strtod(s, NULL);
}
template <>
inline long parse<long>(const char *s) {
return strtol(s, NULL, 10);
}
template <>
inline unsigned long parse<unsigned long>(const char *s) {
return strtoul(s, NULL, 10);
}
template <>
inline int parse<int>(const char *s) {
return atoi(s);
}
#if ARDUINOJSON_USE_LONG_LONG
template <>
inline long long parse<long long>(const char *s) {
return strtoll(s, NULL, 10);
}
template <>
inline unsigned long long parse<unsigned long long>(const char *s) {
return strtoull(s, NULL, 10);
}
#endif
#if ARDUINOJSON_USE_INT64
template <>
inline __int64 parse<__int64>(const char *s) {
return _strtoi64(s, NULL, 10);
}
template <>
inline unsigned __int64 parse<unsigned __int64>(const char *s) {
return _strtoui64(s, NULL, 10);
}
#endif
}
}

View File

@ -1,41 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
// Parse JSON string to create JsonArrays and JsonObjects
// This internal class is not indended to be used directly.
// Instead, use JsonBuffer.parseArray() or .parseObject()
template <typename TIterator>
class StringReader {
TIterator _input;
char _current, _next;
public:
StringReader(const TIterator& input) : _input(input) {
_current = _input.next();
_next = _input.next();
}
void move() {
_current = _next;
_next = _input.next();
}
char current() const {
return _current;
}
char next() const {
return _next;
}
};
}
}

View File

@ -1,106 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonVariantBase.hpp"
#include "StringTraits/StringTraits.hpp"
#include "TypeTraits/EnableIf.hpp"
namespace ArduinoJson {
template <typename TVariant, typename TComparand, typename Enable = void>
struct JsonVariantComparer {
static bool equals(const TVariant &variant, const TComparand &comparand) {
return variant.template as<TComparand>() == comparand;
}
};
template <typename TVariant, typename TString>
struct JsonVariantComparer<
TVariant, TString, typename TypeTraits::EnableIf<Internals::StringTraits<
TString>::has_equals>::type> {
static bool equals(const TVariant &variant, const TString &comparand) {
const char *value = variant.template as<const char *>();
return Internals::StringTraits<TString>::equals(comparand, value);
}
};
template <typename TImpl, typename TComparand>
inline bool operator==(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
typedef JsonVariantBase<TImpl> TVariant;
return JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator==(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
typedef JsonVariantBase<TImpl> TVariant;
return JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator!=(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
typedef JsonVariantBase<TImpl> TVariant;
return !JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator!=(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
typedef JsonVariantBase<TImpl> TVariant;
return !JsonVariantComparer<TVariant, TComparand>::equals(variant, comparand);
}
template <typename TImpl, typename TComparand>
inline bool operator<=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() <= right;
}
template <typename TImpl, typename TComparand>
inline bool operator<=(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand <= variant.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>=(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
return variant.template as<TComparand>() >= comparand;
}
template <typename TImpl, typename TComparand>
inline bool operator>=(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand >= variant.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator<(const JsonVariantBase<TImpl> &varian,
TComparand comparand) {
return varian.template as<TComparand>() < comparand;
}
template <typename TImpl, typename TComparand>
inline bool operator<(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand < variant.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>(const JsonVariantBase<TImpl> &variant,
TComparand comparand) {
return variant.template as<TComparand>() > comparand;
}
template <typename TImpl, typename TComparand>
inline bool operator>(TComparand comparand,
const JsonVariantBase<TImpl> &variant) {
return comparand > variant.template as<TComparand>();
}
}

View File

@ -1,44 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifndef ARDUINO
#include <stddef.h>
#include <stdint.h>
namespace ArduinoJson {
// This class reproduces Arduino's Print class
class Print {
public:
virtual ~Print() {}
virtual size_t write(uint8_t) = 0;
size_t print(const char* s) {
size_t n = 0;
while (*s) {
n += write(static_cast<uint8_t>(*s++));
}
return n;
}
size_t println() {
size_t n = 0;
n += write('\r');
n += write('\n');
return n;
}
};
}
#else
#include <Print.h>
#endif

View File

@ -1,37 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// A Print implementation that allows to write in a char[]
class StaticStringBuilder : public Print {
public:
StaticStringBuilder(char *buf, size_t size)
: buffer(buf), capacity(size - 1), length(0) {
buffer[0] = '\0';
}
virtual size_t write(uint8_t c) {
if (length >= capacity) return 0;
buffer[length++] = c;
buffer[length] = '\0';
return 1;
}
private:
char *buffer;
size_t capacity;
size_t length;
};
}
}

View File

@ -1,51 +0,0 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
struct CharPointerTraits {
class Iterator {
const char* _ptr;
public:
Iterator(const char* ptr) : _ptr(ptr ? ptr : "") {}
char next() {
char c = *_ptr;
if (c) ++_ptr;
return c;
}
};
static bool equals(const char* str, const char* expected) {
return strcmp(str, expected) == 0;
}
template <typename Buffer>
static char* duplicate(const char* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen(str) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy(dup, str, size);
return static_cast<char*>(dup);
}
static const bool has_append = false;
static const bool has_equals = true;
static const bool should_duplicate = false;
};
template <>
struct StringTraits<const char*, void> : CharPointerTraits {};
template <>
struct StringTraits<char*, void> : CharPointerTraits {};
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,5 +26,8 @@ Vagrant.configure(2) do |config|
echo "export PROJECT_NAME='arduinojson'" >> $HOME/.profile
echo "export CC='clang'" >> $HOME/.profile
echo "export CXX='clang++'" >> $HOME/.profile
echo "export LD_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/" >> $HOME/.profile
echo "Run /host/ArduinoJson/fuzzing/fuzz.sh" | sudo tee /etc/motd
SHELL
end

View File

@ -1,44 +0,0 @@
#!/bin/bash
FILE=../bin/ArduinoJsonTests.exe
MD5=""
file_changed() {
[[ ! -f "$FILE" ]] && return 1
NEW_MD5=$(md5sum $FILE)
[[ "$MD5" == "$NEW_MD5" ]] && return 1
MD5=$NEW_MD5
return 0
}
test_succeed() {
echo -en "\007"{,}
}
test_failed() {
echo -en "\007"{,,,,,,,,,,,}
}
run_tests() {
$FILE
case $? in
0)
test_succeed
;;
1)
test_failed
;;
esac
}
while true
do
if file_changed
then
run_tests
else
sleep 2
fi
done

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,11 +2,16 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
// enable deprecated functions by default
#ifndef ARDUINOJSON_ENABLE_DEPRECATED
#define ARDUINOJSON_ENABLE_DEPRECATED 1
#endif
#ifdef ARDUINO // assume this is an embedded platform
// store using float instead of double to reduce the memory usage (issue #134)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -13,9 +13,14 @@
namespace ArduinoJson {
namespace Internals {
template <typename T>
class List;
// A read-write forward iterator for List<T>
template <typename T>
class ListIterator {
friend class List<T>;
public:
explicit ListIterator(ListNode<T> *node = NULL) : _node(node) {}
@ -39,6 +44,14 @@ class ListIterator {
return *this;
}
ListIterator<T> &operator+=(size_t distance) {
while (_node && distance) {
_node = _node->next;
--distance;
}
return *this;
}
operator ListConstIterator<T>() const {
return ListConstIterator<T>(_node);
}

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -37,5 +37,17 @@ struct ValueSetter<TSource, typename TypeTraits::EnableIf<StringTraits<
return true;
}
};
template <typename TSource>
struct ValueSetter<TSource, typename TypeTraits::EnableIf<!StringTraits<
TSource>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination,
const TSource& source) {
// unsigned char* -> char*
destination = reinterpret_cast<const char*>(source);
return true;
}
};
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -84,7 +84,7 @@ class DynamicJsonBufferBase
char* newStart =
static_cast<char*>(_parent->allocInNewBlock(_length + 1));
if (_start && newStart) memcpy(newStart, _start, _length);
newStart[_length] = c;
if (newStart) newStart[_length] = c;
_start = newStart;
}
_length++;

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -49,9 +49,7 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
: Internals::List<JsonVariant>(buffer) {}
// Gets the value at the specified index
JsonVariant operator[](size_t index) const {
return get<JsonVariant>(index);
}
const JsonArraySubscript operator[](size_t index) const;
// Gets or sets the value at specified index
JsonArraySubscript operator[](size_t index);
@ -113,16 +111,15 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
// Gets the value at the specified index.
template <typename T>
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
node_type *node = findNode(index);
return node ? node->content.as<T>()
: Internals::JsonVariantDefault<T>::get();
const_iterator it = begin() += index;
return it != end() ? it->as<T>() : Internals::JsonVariantDefault<T>::get();
}
// Check the type of the value at specified index.
template <typename T>
bool is(size_t index) const {
node_type *node = findNode(index);
return node ? node->content.is<T>() : false;
const_iterator it = begin() += index;
return it != end() ? it->is<T>() : false;
}
// Creates a JsonArray and adds a reference at the end of the array.
@ -134,9 +131,10 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
JsonObject &createNestedObject();
// Removes element at specified index.
void removeAt(size_t index) {
removeNode(findNode(index));
void remove(size_t index) {
remove(begin() += index);
}
using Internals::List<JsonVariant>::remove;
// Returns a reference an invalid JsonArray.
// This object is meant to replace a NULL pointer.
@ -195,33 +193,30 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
void copyTo(T (&array)[N1][N2]) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
it->asArray().copyTo(array[i++]);
it->as<JsonArray>().copyTo(array[i++]);
}
}
private:
node_type *findNode(size_t index) const {
node_type *node = _firstNode;
while (node && index--) node = node->next;
return node;
#if ARDUINOJSON_ENABLE_DEPRECATED
DEPRECATED("use remove() instead")
FORCE_INLINE void removeAt(size_t index) {
return remove(index);
}
#endif
private:
template <typename TValueRef>
bool set_impl(size_t index, TValueRef value) {
node_type *node = findNode(index);
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
value);
iterator it = begin() += index;
if (it == end()) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
}
template <typename TValueRef>
bool add_impl(TValueRef value) {
node_type *node = addNewNode();
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
value);
iterator it = Internals::List<JsonVariant>::add();
if (it == end()) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value);
}
};

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -66,18 +66,24 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
// Gets the value associated with the specified key.
//
// JsonVariant operator[](TKey) const;
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const std::string&, const String&
template <typename TString>
const JsonVariant operator[](const TString& key) const {
return get_impl<const TString&, JsonVariant>(key);
typename TypeTraits::EnableIf<
!TypeTraits::IsArray<TString>::value,
const JsonObjectSubscript<const TString&> >::type
operator[](const TString& key) const {
return JsonObjectSubscript<const TString&>(*const_cast<JsonObject*>(this),
key);
}
//
// JsonVariant operator[](TKey) const;
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
const JsonVariant operator[](const TString* key) const {
return get_impl<const TString*, JsonVariant>(key);
const JsonObjectSubscript<const TString*> operator[](
const TString* key) const {
return JsonObjectSubscript<const TString*>(*const_cast<JsonObject*>(this),
key);
}
// Sets the specified key with the specified value.
@ -241,14 +247,14 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
bool>::type
containsKey(const TString& key) const {
return findNode<const TString&>(key) != NULL;
return findKey<const TString&>(key) != end();
}
//
// bool containsKey(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
bool containsKey(const TString* key) const {
return findNode<const TString*>(key) != NULL;
return findKey<const TString*>(key) != end();
}
// Removes the specified key and the associated value.
@ -259,15 +265,18 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value,
void>::type
remove(const TString& key) {
removeNode(findNode<const TString&>(key));
remove(findKey<const TString&>(key));
}
//
// void remove(TKey);
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
void remove(const TString* key) {
removeNode(findNode<const TString*>(key));
remove(findKey<const TString*>(key));
}
//
// void remove(iterator)
using Internals::List<JsonPair>::remove;
// Returns a reference an invalid JsonObject.
// This object is meant to replace a NULL pointer.
@ -280,41 +289,44 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>,
private:
// Returns the list node that matches the specified key.
template <typename TStringRef>
node_type* findNode(TStringRef key) const {
for (node_type* node = _firstNode; node; node = node->next) {
if (Internals::StringTraits<TStringRef>::equals(key, node->content.key))
return node;
iterator findKey(TStringRef key) {
iterator it;
for (it = begin(); it != end(); ++it) {
if (Internals::StringTraits<TStringRef>::equals(key, it->key)) break;
}
return NULL;
return it;
}
template <typename TStringRef>
const_iterator findKey(TStringRef key) const {
return const_cast<JsonObject*>(this)->findKey<TStringRef>(key);
}
template <typename TStringRef, typename TValue>
typename Internals::JsonVariantAs<TValue>::type get_impl(
TStringRef key) const {
node_type* node = findNode<TStringRef>(key);
return node ? node->content.value.as<TValue>()
: Internals::JsonVariantDefault<TValue>::get();
const_iterator it = findKey<TStringRef>(key);
return it != end() ? it->value.as<TValue>()
: Internals::JsonVariantDefault<TValue>::get();
}
template <typename TStringRef, typename TValueRef>
bool set_impl(TStringRef key, TValueRef value) {
node_type* node = findNode<TStringRef>(key);
if (!node) {
node = addNewNode();
if (!node) return false;
iterator it = findKey<TStringRef>(key);
if (it == end()) {
it = Internals::List<JsonPair>::add();
if (it == end()) return false;
bool key_ok = Internals::ValueSetter<TStringRef>::set(
_buffer, node->content.key, key);
bool key_ok =
Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key);
if (!key_ok) return false;
}
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content.value,
value);
return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value);
}
template <typename TStringRef, typename TValue>
bool is_impl(TStringRef key) const {
node_type* node = findNode<TStringRef>(key);
return node ? node->content.value.is<TValue>() : false;
const_iterator it = findKey<TStringRef>(key);
return it != end() ? it->value.is<TValue>() : false;
}
template <typename TStringRef>

View File

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

View File

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

View File

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

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -17,6 +17,7 @@
#include "RawJson.hpp"
#include "Serialization/JsonPrintable.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsChar.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsIntegral.hpp"
#include "TypeTraits/IsSame.hpp"
@ -39,8 +40,8 @@ class JsonObject;
// - a string (const char*)
// - a reference to a JsonArray or JsonObject
class JsonVariant : public JsonVariantBase<JsonVariant> {
friend void Internals::JsonSerializer::serialize(const JsonVariant &,
JsonWriter &);
template <typename Print>
friend class Internals::JsonSerializer;
public:
// Creates an uninitialized JsonVariant
@ -69,13 +70,15 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
}
// Create a JsonVariant containing an integer value.
// JsonVariant(char)
// JsonVariant(signed short)
// JsonVariant(signed int)
// JsonVariant(signed long)
// JsonVariant(signed char)
template <typename T>
JsonVariant(T value,
typename TypeTraits::EnableIf<
TypeTraits::IsSignedIntegral<T>::value>::type * = 0) {
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsSignedIntegral<T>::value ||
TypeTraits::IsSame<T, char>::value>::type * = 0) {
using namespace Internals;
if (value >= 0) {
_type = JSON_POSITIVE_INTEGER;
@ -98,9 +101,16 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
}
// Create a JsonVariant containing a string.
JsonVariant(const char *value) {
// JsonVariant(const char*);
// JsonVariant(const signed char*);
// JsonVariant(const unsigned char*);
template <typename TChar>
JsonVariant(
const TChar *value,
typename TypeTraits::EnableIf<TypeTraits::IsChar<TChar>::value>::type * =
0) {
_type = Internals::JSON_STRING;
_content.asString = value;
_content.asString = reinterpret_cast<const char *>(value);
}
// Create a JsonVariant containing an unparsed string
@ -121,24 +131,26 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// Get the variant as the specified type.
//
// short as<signed short>() const;
// int as<signed int>() const;
// long as<signed long>() const;
// char as<char>() const;
// signed char as<signed char>() const;
// signed short as<signed short>() const;
// signed int as<signed int>() const;
// signed long as<signed long>() const;
// unsigned char as<unsigned char>() const;
// unsigned short as<unsigned short>() const;
// unsigned int as<unsigned int>() const;
// unsigned long as<unsigned long>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSignedIntegral<T>::value,
T>::type
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, T>::type
as() const {
return static_cast<T>(asInteger());
return variantAsInteger<T>();
}
//
// short as<unsigned short>() const;
// int as<unsigned int>() const;
// long as<unsigned long>() const;
// bool as<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsUnsignedIntegral<T>::value,
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
T>::type
as() const {
return static_cast<T>(asUnsignedInteger());
return variantAsInteger<int>() != 0;
}
//
// double as<double>() const;
@ -147,7 +159,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
T>::type
as() const {
return static_cast<T>(asFloat());
return variantAsFloat<T>();
}
//
// const char* as<const char*>() const;
@ -157,7 +169,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
TypeTraits::IsSame<T, char *>::value,
const char *>::type
as() const {
return asString();
return variantAsString();
}
//
// std::string as<std::string>() const;
@ -165,21 +177,13 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
template <typename T>
typename TypeTraits::EnableIf<Internals::StringTraits<T>::has_append, T>::type
as() const {
const char *cstr = asString();
const char *cstr = variantAsString();
if (cstr) return T(cstr);
T s;
printTo(s);
return s;
}
//
// const bool as<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
T>::type
as() const {
return asInteger() != 0;
}
//
// JsonArray& as<JsonArray> const;
// JsonArray& as<JsonArray&> const;
template <typename T>
@ -188,7 +192,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonArray>::value,
JsonArray &>::type
as() const {
return asArray();
return variantAsArray();
}
//
// const JsonArray& as<const JsonArray&> const;
@ -198,7 +202,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
const JsonArray>::value,
const JsonArray &>::type
as() const {
return asArray();
return variantAsArray();
}
//
// JsonObject& as<JsonObject> const;
@ -209,7 +213,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonObject>::value,
JsonObject &>::type
as() const {
return asObject();
return variantAsObject();
}
//
// JsonObject& as<const JsonObject> const;
@ -220,7 +224,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
const JsonObject>::value,
const JsonObject &>::type
as() const {
return asObject();
return variantAsObject();
}
//
// JsonVariant as<JsonVariant> const;
@ -234,32 +238,35 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
// Tells weither the variant has the specified type.
// Returns true if the variant has type type T, false otherwise.
//
// short as<short>() const;
// int as<int>() const;
// long as<long>() const;
// bool is<char>() const;
// bool is<signed char>() const;
// bool is<signed short>() const;
// bool is<signed int>() const;
// bool is<signed long>() const;
// bool is<unsigned char>() const;
// bool is<unsigned short>() const;
// bool is<unsigned int>() const;
// bool is<unsigned long>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value &&
!TypeTraits::IsSame<T, bool>::value,
bool>::type
typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value, bool>::type
is() const {
return isInteger();
return variantIsInteger();
}
//
// double is<double>() const;
// float is<float>() const;
// bool is<double>() const;
// bool is<float>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
is() const {
return isFloat();
return variantIsFloat();
}
//
// const bool is<bool>() const
// bool is<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
bool>::type
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value, bool>::type
is() const {
return isBoolean();
return variantIsBoolean();
}
//
// bool is<const char*>() const;
@ -269,7 +276,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
TypeTraits::IsSame<T, char *>::value,
bool>::type
is() const {
return isString();
return variantIsString();
}
//
// bool is<JsonArray> const;
@ -283,7 +290,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonArray>::value,
bool>::type
is() const {
return isArray();
return variantIsArray();
}
//
// bool is<JsonObject> const;
@ -297,7 +304,7 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
JsonObject>::value,
bool>::type
is() const {
return isObject();
return variantIsObject();
}
// Returns true if the variant has a value
@ -305,34 +312,24 @@ class JsonVariant : public JsonVariantBase<JsonVariant> {
return _type != Internals::JSON_UNDEFINED;
}
// DEPRECATED: use as<char*>() instead
const char *asString() const;
// DEPRECATED: use as<JsonArray>() instead
JsonArray &asArray() const;
// DEPRECATED: use as<JsonObject>() instead
JsonObject &asObject() const;
private:
// It's not allowed to store a char
JsonArray &variantAsArray() const;
JsonObject &variantAsObject() const;
const char *variantAsString() const;
template <typename T>
JsonVariant(T value, typename TypeTraits::EnableIf<
TypeTraits::IsSame<T, char>::value>::type * = 0);
Internals::JsonFloat asFloat() const;
Internals::JsonInteger asInteger() const;
Internals::JsonUInt asUnsignedInteger() const;
bool isBoolean() const;
bool isFloat() const;
bool isInteger() const;
bool isArray() const {
T variantAsFloat() const;
template <typename T>
T variantAsInteger() const;
bool variantIsBoolean() const;
bool variantIsFloat() const;
bool variantIsInteger() const;
bool variantIsArray() const {
return _type == Internals::JSON_ARRAY;
}
bool isObject() const {
bool variantIsObject() const {
return _type == Internals::JSON_OBJECT;
}
bool isString() const {
bool variantIsString() const {
return _type == Internals::JSON_STRING ||
(_type == Internals::JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString));

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -21,10 +21,22 @@ class JsonObjectSubscript;
template <typename TImpl>
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
public:
// DEPRECATED: use as<char*>() instead
#if ARDUINOJSON_ENABLE_DEPRECATED
DEPRECATED("use as<JsonArray>() instead")
FORCE_INLINE JsonArray &asArray() const {
return as<JsonArray>();
}
DEPRECATED("use as<JsonObject>() instead")
FORCE_INLINE JsonObject &asObject() const {
return as<JsonObject>();
}
DEPRECATED("use as<char*>() instead")
FORCE_INLINE const char *asString() const {
return as<const char *>();
}
#endif
// Gets the variant as an array.
// Returns a reference to the JsonArray or JsonArray::invalid() if the
@ -34,11 +46,6 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
return as<JsonArray &>();
}
// DEPRECATED: use as<JsonArray>() instead
FORCE_INLINE JsonArray &asArray() const {
return as<JsonArray &>();
}
// Gets the variant as an object.
// Returns a reference to the JsonObject or JsonObject::invalid() if the
// variant is not an object.
@ -46,11 +53,6 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
return as<JsonObject &>();
}
// DEPRECATED: use as<JsonObject>() instead
FORCE_INLINE JsonObject &asObject() const {
return as<JsonObject &>();
}
template <typename T>
FORCE_INLINE operator T() const {
return as<T>();
@ -61,11 +63,16 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
return impl()->template as<T>();
}
template <typename T>
FORCE_INLINE bool is() const {
return impl()->template is<T>();
}
// Mimics an array or an object.
// Returns the size of the array or object if the variant has that type.
// Returns 0 if the variant is neither an array nor an object
size_t size() const {
return asArray().size() + asObject().size();
return as<JsonArray>().size() + as<JsonObject>().size();
}
// Mimics an array.
@ -86,27 +93,27 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<TString>::has_equals,
const JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) const {
return asObject()[key];
return as<JsonObject>()[key];
}
//
// const JsonObjectSubscript operator[](TKey) const;
// TKey = const char*, const char[N], const FlashStringHelper*
// TKey = const std::string&, const String&
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<TString>::has_equals,
JsonObjectSubscript<const TString &> >::type
operator[](const TString &key) {
return asObject()[key];
return as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
// TKey = const std::string&, const String&
// TKey = const char*, const char[N], const FlashStringHelper*
template <typename TString>
FORCE_INLINE typename TypeTraits::EnableIf<
Internals::StringTraits<TString *>::has_equals,
Internals::StringTraits<const TString *>::has_equals,
JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) {
return asObject()[key];
return as<JsonObject>()[key];
}
//
// JsonObjectSubscript operator[](TKey);
@ -116,7 +123,7 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
Internals::StringTraits<TString *>::has_equals,
const JsonObjectSubscript<const TString *> >::type
operator[](const TString *key) const {
return asObject()[key];
return as<JsonObject>()[key];
}
private:
@ -124,4 +131,9 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
return static_cast<const TImpl *>(this);
}
};
namespace TypeTraits {
template <typename T>
struct IsVariant : IsBaseOf<JsonVariantBase<T>, T> {};
}
}

View File

@ -0,0 +1,88 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "Data/JsonVariantComparer.hpp"
namespace ArduinoJson {
template <typename TVariant, typename TComparand>
inline bool operator==(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return Internals::JsonVariantComparer<TComparand>::equals(variant, comparand);
}
template <typename TVariant, typename TComparand>
inline typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator==(TComparand comparand, const JsonVariantBase<TVariant> &variant) {
return Internals::JsonVariantComparer<TComparand>::equals(variant, comparand);
}
template <typename TVariant, typename TComparand>
inline bool operator!=(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return !Internals::JsonVariantComparer<TComparand>::equals(variant,
comparand);
}
template <typename TVariant, typename TComparand>
inline typename TypeTraits::EnableIf<!TypeTraits::IsVariant<TComparand>::value,
bool>::type
operator!=(TComparand comparand, const JsonVariantBase<TVariant> &variant) {
return !Internals::JsonVariantComparer<TComparand>::equals(variant,
comparand);
}
template <typename TVariant, typename TComparand>
inline bool operator<=(const JsonVariantBase<TVariant> &left,
TComparand right) {
return left.template as<TComparand>() <= right;
}
template <typename TVariant, typename TComparand>
inline bool operator<=(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand <= variant.template as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator>=(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return variant.template as<TComparand>() >= comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator>=(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand >= variant.template as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator<(const JsonVariantBase<TVariant> &varian,
TComparand comparand) {
return varian.template as<TComparand>() < comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator<(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand < variant.template as<TComparand>();
}
template <typename TVariant, typename TComparand>
inline bool operator>(const JsonVariantBase<TVariant> &variant,
TComparand comparand) {
return variant.template as<TComparand>() > comparand;
}
template <typename TVariant, typename TComparand>
inline bool operator>(TComparand comparand,
const JsonVariantBase<TVariant> &variant) {
return comparand > variant.template as<TComparand>();
}
}

View File

@ -2,19 +2,20 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#include "Data/Parse.hpp"
#include "JsonArray.hpp"
#include "JsonObject.hpp"
#include "JsonVariant.hpp"
#include "Polyfills/isFloat.hpp"
#include "Polyfills/isInteger.hpp"
#include "Polyfills/parseFloat.hpp"
#include "Polyfills/parseInteger.hpp"
#include <errno.h> // for errno
#include <stdlib.h> // for strtol, strtod
#include <string.h> // for strcmp
namespace ArduinoJson {
@ -37,56 +38,38 @@ inline JsonVariant::JsonVariant(const JsonObject &object) {
}
}
inline JsonArray &JsonVariant::asArray() const {
inline JsonArray &JsonVariant::variantAsArray() const {
if (_type == Internals::JSON_ARRAY) return *_content.asArray;
return JsonArray::invalid();
}
inline JsonObject &JsonVariant::asObject() const {
inline JsonObject &JsonVariant::variantAsObject() const {
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
return JsonObject::invalid();
}
inline Internals::JsonInteger JsonVariant::asInteger() const {
template <typename T>
inline T JsonVariant::variantAsInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return _content.asInteger;
return static_cast<T>(_content.asInteger);
case JSON_NEGATIVE_INTEGER:
return -static_cast<Internals::JsonInteger>(_content.asInteger);
return static_cast<T>(_content.asInteger * -1);
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonInteger>(_content.asString);
return Polyfills::parseInteger<T>(_content.asString);
default:
return static_cast<Internals::JsonInteger>(_content.asFloat);
return static_cast<T>(_content.asFloat);
}
}
inline Internals::JsonUInt JsonVariant::asUnsignedInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
case JSON_NEGATIVE_INTEGER:
return _content.asInteger;
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonUInt>(_content.asString);
default:
return static_cast<Internals::JsonUInt>(_content.asFloat);
}
}
inline const char *JsonVariant::asString() const {
inline const char *JsonVariant::variantAsString() const {
using namespace Internals;
if (_type == JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString))
@ -95,25 +78,26 @@ inline const char *JsonVariant::asString() const {
return NULL;
}
inline Internals::JsonFloat JsonVariant::asFloat() const {
template <typename T>
inline T JsonVariant::variantAsFloat() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return static_cast<JsonFloat>(_content.asInteger);
return static_cast<T>(_content.asInteger);
case JSON_NEGATIVE_INTEGER:
return -static_cast<JsonFloat>(_content.asInteger);
return -static_cast<T>(_content.asInteger);
case JSON_STRING:
case JSON_UNPARSED:
return _content.asString ? parse<JsonFloat>(_content.asString) : 0;
return Polyfills::parseFloat<T>(_content.asString);
default:
return _content.asFloat;
return static_cast<T>(_content.asFloat);
}
}
inline bool JsonVariant::isBoolean() const {
inline bool JsonVariant::variantIsBoolean() const {
using namespace Internals;
if (_type == JSON_BOOLEAN) return true;
@ -123,31 +107,18 @@ inline bool JsonVariant::isBoolean() const {
!strcmp(_content.asString, "false");
}
inline bool JsonVariant::isInteger() const {
inline bool JsonVariant::variantIsInteger() const {
using namespace Internals;
if (_type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER)
return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtol(_content.asString, &end, 10);
return *end == '\0' && errno == 0;
return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER ||
(_type == JSON_UNPARSED && Polyfills::isInteger(_content.asString));
}
inline bool JsonVariant::isFloat() const {
inline bool JsonVariant::variantIsFloat() const {
using namespace Internals;
if (_type >= JSON_FLOAT_0_DECIMALS) return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtod(_content.asString, &end);
return *end == '\0' && errno == 0 && !is<long>();
return _type >= JSON_FLOAT_0_DECIMALS ||
(_type == JSON_UNPARSED && Polyfills::isFloat(_content.asString));
}
#if ARDUINOJSON_ENABLE_STD_STREAM

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -10,7 +10,13 @@
#ifdef _MSC_VER
#define FORCE_INLINE __forceinline
#define NO_INLINE __declspec(noinline)
#define DEPRECATED(msg) __declspec(deprecated(msg))
#else
#define FORCE_INLINE __attribute__((always_inline))
#define NO_INLINE __attribute__((noinline))
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
#define DEPRECATED(msg) __attribute__((deprecated(msg)))
#else
#define DEPRECATED(msg) __attribute__((deprecated))
#endif
#endif

View File

@ -0,0 +1,21 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Polyfills {
inline bool isdigit(char c) {
return '0' <= c && c <= '9';
}
inline bool issign(char c) {
return '-' == c || c == '+';
}
}
}

View File

@ -0,0 +1,42 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include <string.h> // for strcmp
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
inline bool isFloat(const char* s) {
if (!s) return false;
if (!strcmp(s, "NaN")) return true;
if (issign(*s)) s++;
if (!strcmp(s, "Infinity")) return true;
while (isdigit(*s)) s++;
bool has_dot = *s == '.';
if (has_dot) {
s++;
while (isdigit(*s)) s++;
}
bool has_exponent = *s == 'e' || *s == 'E';
if (has_exponent) {
s++;
if (issign(*s)) s++;
if (!isdigit(*s)) return false;
while (isdigit(*s)) s++;
}
return (has_dot || has_exponent) && *s == '\0';
}
}
}

View File

@ -0,0 +1,22 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
inline bool isInteger(const char* s) {
if (!s) return false;
if (issign(*s)) s++;
while (isdigit(*s)) s++;
return *s == '\0';
}
}
}

View File

@ -2,15 +2,16 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
// If Visual Studo <= 2012
#if defined(_MSC_VER) && _MSC_VER <= 1700
// If Visual Studo
#if defined(_MSC_VER)
#include <float.h>
#include <limits>
namespace ArduinoJson {
namespace Polyfills {
@ -23,6 +24,16 @@ template <typename T>
bool isInfinity(T x) {
return !_finite(x);
}
template <typename T>
T nan() {
return std::numeric_limits<T>::quiet_NaN();
}
template <typename T>
T inf() {
return std::numeric_limits<T>::infinity();
}
}
}
@ -43,7 +54,7 @@ bool isInfinity(T x) {
#endif
// Workaround for libs that #undef isnan or isinf
// https://github.com/bblanchon/ArduinoJson/issues/284
// https://bblanchon.github.io/ArduinoJson//issues/284
#if !defined(isnan) || !defined(isinf)
namespace std {}
#endif
@ -54,7 +65,7 @@ namespace Polyfills {
template <typename T>
bool isNaN(T x) {
// Workaround for libs that #undef isnan
// https://github.com/bblanchon/ArduinoJson/issues/284
// https://bblanchon.github.io/ArduinoJson//issues/284
#ifndef isnan
using namespace std;
#endif
@ -79,7 +90,7 @@ inline bool isNaN<float>(float x) {
template <typename T>
bool isInfinity(T x) {
// Workaround for libs that #undef isinf
// https://github.com/bblanchon/ArduinoJson/issues/284
// https://bblanchon.github.io/ArduinoJson//issues/284
#ifndef isinf
using namespace std;
#endif
@ -101,6 +112,16 @@ inline bool isInfinity<float>(float x) {
}
#endif
template <typename T>
T nan() {
return static_cast<T>(NAN);
}
template <typename T>
T inf() {
return static_cast<T>(INFINITY);
}
#if defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop

View File

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

View File

@ -0,0 +1,89 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../TypeTraits/FloatTraits.hpp"
#include "./ctype.hpp"
#include "./math.hpp"
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
inline T parseFloat(const char* s) {
typedef TypeTraits::FloatTraits<T> traits;
typedef typename traits::mantissa_type mantissa_t;
typedef typename traits::exponent_type exponent_t;
if (!s) return 0;
bool negative_result = false;
switch (*s) {
case '-':
negative_result = true;
case '+':
s++;
}
if (*s == 'n' || *s == 'N') return traits::nan();
if (*s == 'i' || *s == 'I')
return negative_result ? -traits::inf() : traits::inf();
mantissa_t mantissa = 0;
exponent_t exponent_offset = 0;
while (isdigit(*s)) {
if (mantissa < traits::mantissa_max / 10)
mantissa = mantissa * 10 + (*s - '0');
else
exponent_offset++;
s++;
}
if (*s == '.') {
s++;
while (isdigit(*s)) {
if (mantissa < traits::mantissa_max / 10) {
mantissa = mantissa * 10 + (*s - '0');
exponent_offset--;
}
s++;
}
}
int exponent = 0;
if (*s == 'e' || *s == 'E') {
s++;
bool negative_exponent = false;
if (*s == '-') {
negative_exponent = true;
s++;
} else if (*s == '+') {
s++;
}
while (isdigit(*s)) {
exponent = exponent * 10 + (*s - '0');
if (exponent + exponent_offset > traits::exponent_max) {
if (negative_exponent)
return negative_result ? -0.0f : 0.0f;
else
return negative_result ? -traits::inf() : traits::inf();
}
s++;
}
if (negative_exponent) exponent = -exponent;
}
exponent += exponent_offset;
T result = traits::make_float(static_cast<T>(mantissa), exponent);
return negative_result ? -result : result;
}
}
}

View File

@ -0,0 +1,40 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include <stdlib.h>
#include "../Configuration.hpp"
#include "./ctype.hpp"
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
T parseInteger(const char *s) {
if (!s) return 0;
T result = 0;
bool negative_result = false;
switch (*s) {
case '-':
negative_result = true;
case '+':
s++;
break;
}
while (isdigit(*s)) {
result = static_cast<T>(result * 10 + (*s - '0'));
s++;
}
return negative_result ? static_cast<T>(result * -1) : result;
}
}
}

View File

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

View File

@ -2,22 +2,24 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// A dummy Print implementation used in JsonPrintable::measureLength()
class DummyPrint : public Print {
class DummyPrint {
public:
virtual size_t write(uint8_t) {
size_t print(char) {
return 1;
}
size_t print(const char* s) {
return strlen(s);
}
};
}
}

View File

@ -2,12 +2,11 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
#include "../StringTraits/StringTraits.hpp"
namespace ArduinoJson {
@ -15,15 +14,21 @@ namespace Internals {
// A Print implementation that allows to write in a String
template <typename TString>
class DynamicStringBuilder : public Print {
class DynamicStringBuilder {
public:
DynamicStringBuilder(TString &str) : _str(str) {}
virtual size_t write(uint8_t c) {
StringTraits<TString>::append(_str, static_cast<char>(c));
size_t print(char c) {
StringTraits<TString>::append(_str, c);
return 1;
}
size_t print(const char *s) {
size_t initialLen = _str.length();
StringTraits<TString>::append(_str, s);
return _str.length() - initialLen;
}
private:
DynamicStringBuilder &operator=(const DynamicStringBuilder &);

View File

@ -2,20 +2,19 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// Decorator on top of Print to allow indented output.
// This class is used by JsonPrintable::prettyPrintTo() but can also be used
// for your own purpose, like logging.
class IndentedPrint : public Print {
template <typename Print>
class IndentedPrint {
public:
explicit IndentedPrint(Print &p) : sink(&p) {
level = 0;
@ -23,14 +22,21 @@ class IndentedPrint : public Print {
isNewLine = true;
}
virtual size_t write(uint8_t c) {
size_t print(char c) {
size_t n = 0;
if (isNewLine) n += writeTabs();
n += sink->write(c);
n += sink->print(c);
isNewLine = c == '\n';
return n;
}
size_t print(const char *s) {
// TODO: optimize
size_t n = 0;
while (*s) n += print(*s++);
return n;
}
// Adds one level of indentation
void indent() {
if (level < MAX_LEVEL) level++;
@ -54,7 +60,7 @@ class IndentedPrint : public Print {
size_t writeTabs() {
size_t n = 0;
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
for (int i = 0; i < level * tabSize; i++) n += sink->print(' ');
return n;
}

View File

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

View File

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

View File

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

View File

@ -2,18 +2,18 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include <stdint.h>
#include "../Data/Encoding.hpp"
#include "../Data/JsonFloat.hpp"
#include "../Data/JsonInteger.hpp"
#include "../Polyfills/attributes.hpp"
#include "../Polyfills/math.hpp"
#include "../Polyfills/normalize.hpp"
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
@ -25,6 +25,7 @@ namespace Internals {
// - JsonVariant::writeTo()
// Its derived by PrettyJsonWriter that overrides some members to add
// indentation.
template <typename Print>
class JsonWriter {
public:
explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
@ -150,7 +151,7 @@ class JsonWriter {
_length += _sink.print(s);
}
void writeRaw(char c) {
_length += _sink.write(c);
_length += _sink.print(c);
}
protected:

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -13,19 +13,27 @@ namespace ArduinoJson {
namespace Internals {
// Converts a compact JSON string into an indented one.
class Prettyfier : public Print {
template <typename Print>
class Prettyfier {
public:
explicit Prettyfier(IndentedPrint& p) : _sink(p) {
explicit Prettyfier(IndentedPrint<Print>& p) : _sink(p) {
_previousChar = 0;
_inString = false;
}
virtual size_t write(uint8_t c) {
size_t print(char c) {
size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
_previousChar = c;
return n;
}
size_t print(const char* s) {
// TODO: optimize
size_t n = 0;
while (*s) n += print(*s++);
return n;
}
private:
Prettyfier& operator=(const Prettyfier&); // cannot be assigned
@ -33,15 +41,15 @@ class Prettyfier : public Print {
return _previousChar == '{' || _previousChar == '[';
}
size_t handleStringChar(uint8_t c) {
size_t handleStringChar(char c) {
bool isQuote = c == '"' && _previousChar != '\\';
if (isQuote) _inString = false;
return _sink.write(c);
return _sink.print(c);
}
size_t handleMarkupChar(uint8_t c) {
size_t handleMarkupChar(char c) {
switch (c) {
case '{':
case '[':
@ -65,31 +73,29 @@ class Prettyfier : public Print {
}
}
size_t writeBlockClose(uint8_t c) {
size_t writeBlockClose(char c) {
size_t n = 0;
n += unindentIfNeeded();
n += _sink.write(c);
n += _sink.print(c);
return n;
}
size_t writeBlockOpen(uint8_t c) {
size_t writeBlockOpen(char c) {
size_t n = 0;
n += indentIfNeeded();
n += _sink.write(c);
n += _sink.print(c);
return n;
}
size_t writeColon() {
size_t n = 0;
n += _sink.write(':');
n += _sink.write(' ');
n += _sink.print(": ");
return n;
}
size_t writeComma() {
size_t n = 0;
n += _sink.write(',');
n += _sink.println();
n += _sink.print(",\r\n");
return n;
}
@ -97,14 +103,14 @@ class Prettyfier : public Print {
_inString = true;
size_t n = 0;
n += indentIfNeeded();
n += _sink.write('"');
n += _sink.print('"');
return n;
}
size_t writeNormalChar(uint8_t c) {
size_t writeNormalChar(char c) {
size_t n = 0;
n += indentIfNeeded();
n += _sink.write(c);
n += _sink.print(c);
return n;
}
@ -112,18 +118,18 @@ class Prettyfier : public Print {
if (!inEmptyBlock()) return 0;
_sink.indent();
return _sink.println();
return _sink.print("\r\n");
}
size_t unindentIfNeeded() {
if (inEmptyBlock()) return 0;
_sink.unindent();
return _sink.println();
return _sink.print("\r\n");
}
uint8_t _previousChar;
IndentedPrint& _sink;
char _previousChar;
IndentedPrint<Print>& _sink;
bool _inString;
};
}

View File

@ -0,0 +1,39 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
// A Print implementation that allows to write in a char[]
class StaticStringBuilder {
public:
StaticStringBuilder(char *buf, size_t size) : end(buf + size - 1), p(buf) {
*p = '\0';
}
size_t print(char c) {
if (p >= end) return 0;
*p++ = c;
*p = '\0';
return 1;
}
size_t print(const char *s) {
char *begin = p;
while (p < end && *s) *p++ = *s++;
*p = '\0';
return p - begin;
}
private:
char *end;
char *p;
};
}
}

View File

@ -2,7 +2,7 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
@ -11,22 +11,25 @@
#if ARDUINOJSON_ENABLE_STD_STREAM
#include "../Print.hpp"
#include <ostream>
namespace ArduinoJson {
namespace Internals {
class StreamPrintAdapter : public Print {
class StreamPrintAdapter {
public:
explicit StreamPrintAdapter(std::ostream& os) : _os(os) {}
virtual size_t write(uint8_t c) {
_os << static_cast<char>(c);
size_t print(char c) {
_os << c;
return 1;
}
size_t print(const char* s) {
_os << s;
return strlen(s);
}
private:
// cannot be assigned
StreamPrintAdapter& operator=(const StreamPrintAdapter&);

View File

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

View File

@ -2,11 +2,13 @@
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
#include <Stream.h>
#include "../TypeTraits/EnableIf.hpp"
@ -17,15 +19,35 @@ namespace ArduinoJson {
namespace Internals {
struct ArduinoStreamTraits {
class Iterator {
class Reader {
Stream& _stream;
char _current, _next;
public:
Iterator(Stream& stream) : _stream(stream) {}
Reader(Stream& stream) : _stream(stream), _current(0), _next(0) {}
void move() {
_current = _next;
_next = 0;
}
char current() {
if (!_current) _current = read();
return _current;
}
char next() {
int n = _stream.read();
return n >= 0 ? static_cast<char>(n) : '\0';
// assumes that current() has been called
if (!_next) _next = read();
return _next;
}
private:
char read() {
// don't use _stream.read() as it ignores the timeout
char c = 0;
_stream.readBytes(&c, 1);
return c;
}
};
};
@ -39,3 +61,5 @@ struct StringTraits<TStream,
: ArduinoStreamTraits {};
}
}
#endif

View File

@ -0,0 +1,61 @@
// Copyright Benoit Blanchon 2014-2017
// MIT License
//
// Arduino JSON library
// https://bblanchon.github.io/ArduinoJson/
// If you like this project, please add a star!
#pragma once
#include "../TypeTraits/EnableIf.hpp"
#include "../TypeTraits/IsChar.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TChar>
struct CharPointerTraits {
class Reader {
const TChar* _ptr;
public:
Reader(const TChar* ptr)
: _ptr(ptr ? ptr : reinterpret_cast<const TChar*>("")) {}
void move() {
++_ptr;
}
TChar current() const {
return _ptr[0];
}
TChar next() const {
return _ptr[1];
}
};
static bool equals(const TChar* str, const char* expected) {
return strcmp(reinterpret_cast<const char*>(str), expected) == 0;
}
template <typename Buffer>
static char* duplicate(const TChar* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen(reinterpret_cast<const char*>(str)) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy(dup, str, size);
return static_cast<char*>(dup);
}
static const bool has_append = false;
static const bool has_equals = true;
static const bool should_duplicate = false;
};
template <typename TChar>
struct StringTraits<TChar*, typename TypeTraits::EnableIf<
TypeTraits::IsChar<TChar>::value>::type>
: CharPointerTraits<TChar> {};
}
}

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