Compare commits

..

159 Commits
v4.1 ... v5.7.2

Author SHA1 Message Date
d3bc52951a Set version to 5.7.2 2016-11-23 21:54:56 +01:00
2f7232859e Fixed PROGMEM causing an exception on ESP8266 (issue #383) 2016-11-23 21:53:29 +01:00
4a7232ac99 Added DynamicJsonBuffer to the keywords 2016-11-23 21:25:49 +01:00
72d78432c9 Made PROGMEM available on more platforms (issue #381) 2016-11-16 22:24:58 +01:00
f6cd42d916 Travis: Added Arduino 1.6.12, removed 1.5.8 2016-11-16 22:24:41 +01:00
542dff2a08 Added Andrew Melvin to the list of donators 2016-11-15 21:48:40 +01:00
e75e843c88 Moved JsonBuffer size calculator to https://bblanchon.github.io/ArduinoJson/ 2016-11-13 20:48:03 +01:00
146a76247c Set version to 5.7.1 2016-11-13 20:21:16 +01:00
f28157cab7 Fixed compilation error when index is not an int (issue #381) 2016-11-13 20:19:36 +01:00
1ce16ce449 Added support for PROGMEM (issue #76) 2016-11-13 20:16:12 +01:00
c310e7e8b7 Set version to 5.7.0 2016-11-06 17:52:57 +01:00
aa2ef79e55 Templatized all functions using String or std::string
* Removed `ArduinoJson::String`
* Removed `JsonVariant::defaultValue<T>()`
* Removed non-template `JsonObject::get()` and `JsonArray.get()`
* Fixed support for `StringSumHelper` (issue #184)
* Replaced `ARDUINOJSON_USE_ARDUINO_STRING` by `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_ARDUINO_STRING` (issue #378)
* Added example `StringExample.ino` to show where `String` can be used
2016-11-06 17:52:18 +01:00
7ad57f1c33 Added Yoeri Kroon to the list of donators 2016-10-27 15:19:13 +02:00
cbfd331e50 JsonBuffer calculator now generates more compact expression 2016-09-30 10:44:05 +02:00
e6f55b1f6f Increased default nesting limit to 50 when compiled for a computer (issue #349) 2016-09-21 22:11:38 +02:00
bb805e93cb Set version to 5.6.7 2016-09-20 10:11:19 +02:00
deb57b960b Fixed parser that incorrectly rejected floats containing a + (issue #349) 2016-09-19 10:08:14 +02:00
8a9b918bf4 Fixed undefined behavior in Prettyfier and Print (issue #354) 2016-09-17 13:51:54 +02:00
2f6f3d0629 Fixed return value of JsonObject::set() (issue #350) 2016-09-16 10:10:31 +02:00
a60b35f41c Extracted class JsonSerializer 2016-09-11 13:43:21 +02:00
6757f35a3a Set version to 5.6.6 2016-08-29 20:55:36 +02:00
ffb9b6d1ba Fixed JsonVariant::success() which didn't propagate JsonArray::success() nor JsonObject::success() (issue #342). 2016-08-29 20:54:39 +02:00
e401498e4a Fixed JsonBuffer size calculator 2016-08-26 10:10:19 +02:00
d30e940b3b Added JsonBuffer size calculator 2016-08-25 19:08:12 +02:00
05ea5e04c8 Added Darlington Adibe to the list of donators 2016-08-25 11:40:31 +02:00
a7ef99d0fe Added .mbedignore for ARM mbdeb (PR #334 by @nuket) 2016-08-25 11:40:04 +02:00
f2a8b52c2c PlatformIO: Use the same name as for Arduino IDE (PR #339) 2016-08-24 13:44:10 +02:00
409ca7ee4e Fixed -Wparentheses warning introduced in v5.6.5 (PR #335 by @nuket) 2016-08-17 20:37:44 +02:00
387b565705 Set version to 5.6.5 2016-08-15 12:25:48 +02:00
96f486001d as<char*>() now returns true when input is null (issue #330) 2016-08-15 12:24:08 +02:00
a498abc14a Set version to 5.6.4 2016-07-20 13:16:14 +02:00
c64340a9bb Fixed error in float serialization (issue #324) 2016-07-20 13:15:17 +02:00
79d80a5dbf Set version to 5.6.3 2016-07-19 08:59:42 +02:00
7ebff5949f Fixed call of overloaded isinf(double&) is ambiguous (issue #284) 2016-07-19 08:57:19 +02:00
434080572c AppVeyor: Disabled build on MinGW32 2016-07-17 18:29:38 +02:00
c87a0e97ab Added as<JsonArray>() as a synonym for as<JsonArray&>()... (issue #291) 2016-07-17 17:22:58 +02:00
2dbd94951c Improved speed of float serialization (about twice faster) 2016-07-10 16:12:49 +02:00
1e044f50c7 Set version to 5.6.2 2016-06-30 20:23:58 +02:00
a7aa98510c Restored Travis build on all clang version 2016-06-30 20:23:21 +02:00
729ab56878 Fixed build when another lib does #undef isnan (issue #284) 2016-06-30 20:22:47 +02:00
907b627e16 Set version to 5.6.1 2016-06-24 09:24:44 +02:00
10fcca20f8 Added missing #pragma once (issue #310) 2016-06-23 21:27:24 +02:00
59cd1f1433 Fix packaging script 2016-06-22 21:51:37 +02:00
4a2c570270 Set version to 5.6.0 2016-06-22 21:42:55 +02:00
8c7edbd9c3 ArduinoJson is now a header-only library (issue #199) 2016-06-22 21:41:19 +02:00
0801e16327 Added GitHub issue template 2016-06-15 10:13:43 +02:00
0df2a365f5 Set version to 5.5.1 2016-06-06 22:12:48 +02:00
c7d6d33e6c Fixed compilation error with Intel Galileo (issue #299) 2016-06-06 22:10:28 +02:00
c705f3cfeb Disabled build on Clang 3.5, 3.6, 3.7 and 3.8 because llvm.org/apt is down 2016-06-06 22:09:34 +02:00
7fecb36aee Added Kestutis Liaugminas to the list of donators 2016-06-03 20:16:47 +02:00
657a2ea8d9 Added Jon Williams to the list of donators 2016-05-23 11:02:19 +02:00
dd064f4c96 Added Arduino 1.6.9 to the continuous integration 2016-05-22 22:24:31 +02:00
3bc05b97ea Set version to 5.5.0 2016-05-22 15:00:09 +02:00
bbd515f6f6 Added Nick Koumaris to the list of donators 2016-05-22 14:58:48 +02:00
9b3e3a3d9c Renamed JsonVariant::invalid<T>() to JsonVariant::defaultValue<T>() 2016-05-18 09:17:45 +02:00
a3a2ca4796 Added JsonVariant::success() (issue #279) 2016-05-18 09:15:49 +02:00
eab13dc565 Added Martijn van den Burg to the list of donators 2016-05-16 20:35:26 +02:00
bebd1c400c Added OSX build on Travis 2016-05-15 09:41:53 +02:00
36d1bb2f52 Added Charles-Henri Hallard to the list of donator 2016-05-08 20:59:59 +02:00
ae32695c3e Set version to 5.4.0 2016-05-06 08:46:13 +02:00
c5d19a4dbd Changed ::String to ArduinoJson::String (issue #275) 2016-05-06 08:44:31 +02:00
78728c6547 Set version to 5.3.0 2016-04-30 09:49:45 +02:00
a8032f81d9 Added JsonVariant JsonBuffer::parse() (issue #265) 2016-04-30 09:47:53 +02:00
a138791964 Added custom implementation of ftoa (issues #266, #267, #269 and #270) 2016-04-28 18:54:14 +02:00
f9f002c8f7 Fix unsigned long printed as signed long (issue #170) 2016-04-28 08:42:59 +02:00
f192d5c12e Set version to 5.2.0 2016-04-16 16:17:19 +02:00
a6724bd03f Added RawJson() to insert pregenerated JSON portions (issue #259) 2016-04-16 16:15:01 +02:00
c77c3f33ef Added JsonArray::copyTo() and JsonArray::copyFrom() (issue #254) 2016-04-14 20:06:38 +02:00
623aeee9bf Added example JsonHttpClient (issue #256) 2016-04-08 20:11:36 +02:00
a241d53d28 Added JsonVariant::as<char*>() as a synonym for JsonVariant::as<const char*>() (issue #257) 2016-04-05 20:47:04 +02:00
11500d2ff5 Fixed strange Markdown rendering in README 2016-04-05 10:27:50 +02:00
85708bc94f Added Arduino 1.6.8 to the continuous integration 2016-04-05 09:49:12 +02:00
ba6e8856f2 Added Tweet from @hemalchevli 2016-04-04 22:23:51 +02:00
c8448b0abf Added Gustavo Donizeti Gini to the list of donators 2016-02-29 09:27:52 +01:00
e35248ffc4 Set version to 5.1.1 2016-02-23 21:30:01 +01:00
b47a3b566a Removed duplication when one replaces a value in a (PR #232 by @ulion) 2016-02-23 21:27:52 +01:00
6ab23bd523 Added RedBearLab BLE Nano to the list of supported platforms 2016-02-17 10:24:37 +01:00
987afff0e9 Travis: added GCC 4.4, 4.5, 4.7, 4.8, 4.9, 5.2 and Clang 3.5, 3.6, 3.7 2016-02-17 10:15:40 +01:00
564c62f3b3 Set version to 5.1.0 2016-02-14 16:20:33 +01:00
8733f95e51 Added support of long long (issue #171)
Moved all build settings to `ArduinoJson/Configuration.hpp`
Added AppVeyor settings in source tree
2016-02-14 16:18:13 +01:00
ce63e9c3c3 Added comments in examples 2016-02-01 13:31:07 +01:00
77b7124cf1 Set version to 5.0.8 2016-01-31 21:57:08 +01:00
6a608d4b49 Fixed JsonVariant::is<bool>() that was incorrectly returning false (issue #214) 2016-01-31 21:56:04 +01:00
01924618bd Merge pull request #215 from ivankravets/patch-1
Use tagged source code from repo
2016-01-31 21:00:46 +01:00
666e2fd0ce Use tagged source code from repo
http://docs.platformio.org/en/latest/librarymanager/config.html#version
2016-01-31 21:24:37 +02:00
0cfc25d751 Added Johann Stieger to the list of donators 2016-01-07 22:40:12 +01:00
b6d8e6c989 Updated copyright year from 2015 to 2016 2016-01-07 22:39:57 +01:00
ab2502f7b8 Fix misspelled PlatformIO 2015-12-23 14:42:22 +01:00
c57e6f3bd8 Made the library compatible with platform.io (issue #181) 2015-12-22 23:43:44 +01:00
b54f1ffc1d Travis: build with Arduino 1.5.8 and 1.6.7 2015-12-22 22:01:30 +01:00
bd0ea42277 Added a badge with the number of stars 2015-11-25 21:22:49 +01:00
7ae43bc4f8 Set version to 5.0.7 2015-11-25 21:15:11 +01:00
056682327b Changed String to be a typedef of std::string (issues #142 and #161) 2015-11-25 21:09:18 +01:00
8b66a25f66 Removed a useless line of code 2015-11-22 10:18:21 +01:00
96245dd3b4 Made library easier to use from a CMake project: simply add_subdirectory(ArduinoJson/src) 2015-11-19 21:53:27 +01:00
9cc49da68a Moved to the new Travis infrastructure 2015-11-19 21:31:23 +01:00
224918b463 Set version to 5.0.6 2015-11-09 23:10:14 +01:00
cbeefa2503 Examples: Added a loop to wait for serial port to be ready (issue #156) 2015-11-09 22:56:49 +01:00
6d68806633 Added donators list 2015-11-09 22:55:29 +01:00
ba3617c22f Added parameter to DynamicJsonBuffer constructor to set initial size (issue #152) 2015-11-09 21:37:40 +01:00
b7d9bb2765 Merge pull request #150 from marvinroger/patch-1
Add library category
2015-11-06 14:50:18 +01:00
74b42e2251 Add library category 2015-11-06 14:30:20 +01:00
c0cf9c3fcc Use float instead of double to reduce the size of JsonVariant (issue #134) 2015-10-30 23:03:16 +01:00
9f3ce18f06 Add overload JsonObjectSuscript::set(value, decimals) (issue #143) 2015-10-30 22:29:47 +01:00
b9e3255c9e Reached 100.00% code coverage :-) 2015-09-29 22:20:36 +02:00
e657396f65 Added -fno-rtti 2015-09-29 21:51:21 +02:00
929f608f2f Added list of supported platforms 2015-09-29 21:49:19 +02:00
c6a4bfa886 Fixed ambiguous overload with JsonArraySubscript and JsonObjectSubscript (issue #122) 2015-09-28 22:14:50 +02:00
d5e25b12b8 Added a comment to prevent issue #112 2015-09-27 14:18:14 +02:00
7cf6fe6d62 Fixed return type of JsonArray::is<T>() and some others (issue #121) 2015-09-19 16:25:18 +02:00
155dd653e7 Fixed printTo(String) which wrote numbers instead of strings (issue #120) 2015-09-19 16:23:09 +02:00
b5c8cd1766 Set version to 5.0.3 2015-09-19 16:20:06 +02:00
4967e389c5 Added a script to create the package with the old layout (issues #97, #114, #116) 2015-09-13 21:04:30 +02:00
ffbaebd198 Added testimonials from Reddit users erm_what_ and makerhacks 2015-09-06 22:11:53 +02:00
04b8781c8d Fixed GCC warning "declaration shadows a member" (issue #103) 2015-09-01 22:26:51 +02:00
5a4d993f7d Fixed memory alignment, which made ESP8266 crash (issue #104) 2015-09-01 22:21:50 +02:00
823a172681 Fixed segmentation fault in StaticJsonBuffer (issue #104) 2015-08-29 22:51:17 +02:00
a1943e21ed Fixed compilation on Visual Studio 2010 and 2012 (issue #107) 2015-08-27 21:47:49 +02:00
01c287bc89 Removed -Wdeprecated-register for GCC 2015-08-26 21:00:28 +02:00
0cf8249b14 Fixed Clang warning "register specifier is deprecated" (issue #102) 2015-08-26 20:49:24 +02:00
a8265a799d Merge pull request #100 from Eriatolc/master
Fix typo in Readme & clean file
2015-08-24 18:18:05 +02:00
18bb653f10 fix typo 2015-08-24 18:10:10 +02:00
a003a31952 Fixed compilation with Arduino 1.0.6 (issue #99) 2015-08-24 15:20:40 +02:00
0a1c27f873 Updated copyright year 2015-08-20 15:24:35 +02:00
75f8e25aed Added a script to measure the size of the sample programs 2015-08-19 22:12:20 +02:00
39c506b419 Reduced generator size. Fixed Visual Studio warnings 2015-08-19 16:08:19 +02:00
ef2641b49b Store parsed token as string and allow conversion between various types (issues #64, #69, #90, #93) 2015-08-10 17:22:22 +02:00
bce101578d Merge branch 'master' into 5.0 2015-08-02 14:28:20 +02:00
10e466426a Removed the wrong #include 2015-08-02 09:20:21 +02:00
9b90aeffa5 Added call to arduino compiler in travis 2015-08-02 09:20:08 +02:00
601b51890f Fixed segmentation fault in when memory allocation fails (issue #92) 2015-08-01 16:57:29 +02:00
2524a00a96 Fixed segmentation fault in DynamicJsonBuffer when memory allocation fails (issue #92) 2015-08-01 16:31:59 +02:00
e31d667bec Added support of comments in JSON input (issue #88) 2015-07-27 22:18:54 +02:00
c161f698fc Implicitly duplicate String in the JsonBuffer (issue #84, #87) 2015-07-25 15:38:12 +02:00
92e687303d Added support of non standard JSON input (issue #44) 2015-07-10 22:11:26 +02:00
f5b83f9314 Added greeting to Giancarlo Canales Barreto 2015-06-14 15:26:33 +02:00
5e7b9ec688 Fix buffer overflow (pull request #81) 2015-06-10 21:33:20 +02:00
78ae0b8aee Updated changelog 2015-05-31 14:42:09 +02:00
283dffc035 Switched to the new library layout 2015-05-31 14:31:41 +02:00
0aded2a798 Reduced code size 2015-05-31 14:25:01 +02:00
1b5be892b9 Added support of String class (issue #55, #56, #70, #77) 2015-05-25 15:38:58 +02:00
756c279cdc Redesigned JsonVariant to leverage converting constructors instead of assignment operators 2015-05-23 15:32:50 +02:00
08d05df00e Added JsonPrintable::measureLength() (issue #75) 2015-05-09 16:53:48 +02:00
c385862be1 Updated change log for v4.3 2015-05-03 15:49:44 +02:00
0eff567910 Added JsonArray::removeAt() (issue #58) 2015-05-02 15:16:18 +02:00
94d38c0680 Added issue #68 in changelog 2015-04-27 16:01:05 +02:00
81285f49fe Fixed issue #68 2015-04-27 15:57:40 +02:00
877096d49d Fixed issue #67 2015-04-23 21:27:58 +02:00
bfe60243a4 Fixed issue #65 2015-04-18 15:37:15 +02:00
ca9d606e72 Added example JsonUdpBeacon 2015-02-25 22:27:30 +01:00
24d21467dd Updated change log for v4.2 2015-02-07 20:49:05 +01:00
41651136bf Switched back to old library layout (issues #39, #43 and #45) 2015-02-07 20:46:46 +01:00
5e5f060fc0 Updated copyright for 2015 2015-02-07 16:05:48 +01:00
29ab5fc9c2 Reduced code size by 12 bytes 2015-02-07 16:01:09 +01:00
80913b8044 Fixed Visual Studio's warnings 2015-02-07 15:05:46 +01:00
02960f28e4 Fix coveralls command line 2015-02-03 14:38:44 +01:00
8db338ba14 Removed global new operator overload (issue #40, #45 and #46) 2015-02-01 20:59:31 +01:00
dadd8986dc Mute compiler warning (issue #47) 2015-01-15 21:05:14 +01:00
e2016cf65b Added an example with EthernetServer 2015-01-10 15:25:27 +01:00
177 changed files with 7510 additions and 2452 deletions

5
.clang-format Normal file
View File

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

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.sh text eol=lf

11
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

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

3
.gitignore vendored
View File

@ -3,3 +3,6 @@
/build
/bin
/lib
/sftp-config.json
.tags
.tags_sorted_by_file

5
.mbedignore Normal file
View File

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

View File

@ -1,12 +1,116 @@
language: c++
compiler:
- gcc
- clang
before_install:
- sudo pip install cpp-coveralls
before_script:
- cmake -DCOVERAGE=true .
script:
- make && make test
after_success:
- coveralls --include include --include src --gcov-options '\-lp'
sudo: false
language: cpp
matrix:
include:
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.4']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.4
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.5']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.5
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.6']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.6
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.7']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.7
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.8']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.8
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-4.9']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-4.9
- compiler: gcc
addons:
apt:
sources: ['ubuntu-toolchain-r-test']
packages: ['g++-5']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=g++-5
- compiler: clang
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.5']
packages: ['clang-3.5']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.5
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.6']
packages: ['clang-3.6']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.6
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.7']
packages: ['clang-3.7']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.7
- compiler: clang
addons:
apt:
sources: ['ubuntu-toolchain-r-test','llvm-toolchain-precise-3.8']
packages: ['clang-3.8']
env: SCRIPT=cmake CMAKE_CXX_COMPILER=clang++-3.8
- compiler: gcc
env: SCRIPT=coverage
- os: osx
osx_image: beta-xcode6.1
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: beta-xcode6.2
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: beta-xcode6.3
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode6.4
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode7
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode7.1
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode7.2
compiler: clang
env: SCRIPT=cmake-osx
- os: osx
osx_image: xcode7.3
compiler: clang
env: SCRIPT=cmake-osx
- env: SCRIPT=arduino VERSION=1.6.7 BOARD=arduino:avr:uno
- env: SCRIPT=arduino VERSION=1.6.12 BOARD=arduino:avr:uno
- env: SCRIPT=platformio BOARD=uno
- env: SCRIPT=platformio BOARD=due
- env: SCRIPT=platformio BOARD=esp01
- env: SCRIPT=platformio BOARD=teensy31
cache:
directories:
- "~/.platformio"
script: scripts/travis/$SCRIPT.sh

8
ArduinoJson.h Normal file
View File

@ -0,0 +1,8 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include "include/ArduinoJson.h"

View File

@ -1,5 +1,257 @@
Arduino JSON: change log
========================
ArduinoJson: change log
=======================
v5.7.2
------
* Made PROGMEM available on more platforms (issue #381)
* Fixed PROGMEM causing an exception on ESP8266 (issue #383)
v5.7.1
------
* Added support for PROGMEM (issue #76)
* Fixed compilation error when index is not an `int` (issue #381)
v5.7.0
------
* Templatized all functions using `String` or `std::string`
* Removed `ArduinoJson::String`
* Removed `JsonVariant::defaultValue<T>()`
* Removed non-template `JsonObject::get()` and `JsonArray.get()`
* Fixed support for `StringSumHelper` (issue #184)
* Replaced `ARDUINOJSON_USE_ARDUINO_STRING` by `ARDUINOJSON_ENABLE_STD_STRING` and `ARDUINOJSON_ENABLE_ARDUINO_STRING` (issue #378)
* Added example `StringExample.ino` to show where `String` can be used
* Increased default nesting limit to 50 when compiled for a computer (issue #349)
**BREAKING CHANGES**:
The non-template functions `JsonObject::get()` and `JsonArray.get()` have been removed. This means that you need to explicitely tell the type you expect in return.
Old code:
```c++
#define ARDUINOJSON_USE_ARDUINO_STRING 0
JsonVariant value1 = myObject.get("myKey");
JsonVariant value2 = myArray.get(0);
```
New code:
```c++
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#define ARDUINOJSON_ENABLE_STD_STRING 1
JsonVariant value1 = myObject.get<JsonVariant>("myKey");
JsonVariant value2 = myArray.get<JsonVariant>(0);
```
v5.6.7
------
* Fixed `array[idx].as<JsonVariant>()` and `object[key].as<JsonVariant>()`
* Fixed return value of `JsonObject::set()` (issue #350)
* Fixed undefined behavior in `Prettyfier` and `Print` (issue #354)
* Fixed parser that incorrectly rejected floats containing a `+` (issue #349)
v5.6.6
------
* Fixed `-Wparentheses` warning introduced in v5.6.5 (PR #335 by @nuket)
* Added `.mbedignore` for ARM mbdeb (PR #334 by @nuket)
* Fixed `JsonVariant::success()` which didn't propagate `JsonArray::success()` nor `JsonObject::success()` (issue #342).
v5.6.5
------
* `as<char*>()` now returns `true` when input is `null` (issue #330)
v5.6.4
------
* Fixed error in float serialization (issue #324)
v5.6.3
------
* Improved speed of float serialization (about twice faster)
* Added `as<JsonArray>()` as a synonym for `as<JsonArray&>()`... (issue #291)
* Fixed `call of overloaded isinf(double&) is ambiguous` (issue #284)
v5.6.2
------
* Fixed build when another lib does `#undef isnan` (issue #284)
v5.6.1
------
* Added missing `#pragma once` (issue #310)
v5.6.0
------
* ArduinoJson is now a header-only library (issue #199)
v5.5.1
------
* Fixed compilation error with Intel Galileo (issue #299)
v5.5.0
------
* Added `JsonVariant::success()` (issue #279)
* Renamed `JsonVariant::invalid<T>()` to `JsonVariant::defaultValue<T>()`
v5.4.0
------
* Changed `::String` to `ArduinoJson::String` (issue #275)
* Changed `::Print` to `ArduinoJson::Print` too
v5.3.0
------
* Added custom implementation of `ftoa` (issues #266, #267, #269 and #270)
* Added `JsonVariant JsonBuffer::parse()` (issue #265)
* Fixed `unsigned long` printed as `signed long` (issue #170)
v5.2.0
------
* Added `JsonVariant::as<char*>()` as a synonym for `JsonVariant::as<const char*>()` (issue #257)
* Added example `JsonHttpClient` (issue #256)
* Added `JsonArray::copyTo()` and `JsonArray::copyFrom()` (issue #254)
* Added `RawJson()` to insert pregenerated JSON portions (issue #259)
v5.1.1
------
* Removed `String` duplication when one replaces a value in a `JsonObject` (PR #232 by @ulion)
v5.1.0
------
* Added support of `long long` (issue #171)
* Moved all build settings to `ArduinoJson/Configuration.hpp`
**BREAKING CHANGE**:
If you defined `ARDUINOJSON_ENABLE_STD_STREAM`, you now need to define it to `1`.
v5.0.8
------
* Made the library compatible with [PlatformIO](http://platformio.org/) (issue #181)
* Fixed `JsonVariant::is<bool>()` that was incorrectly returning false (issue #214)
v5.0.7
------
* Made library easier to use from a CMake project: simply `add_subdirectory(ArduinoJson/src)`
* Changed `String` to be a `typedef` of `std::string` (issues #142 and #161)
**BREAKING CHANGES**:
- `JsonVariant(true).as<String>()` now returns `"true"` instead of `"1"`
- `JsonVariant(false).as<String>()` now returns `"false"` instead of `"0"`
v5.0.6
------
* Added parameter to `DynamicJsonBuffer` constructor to set initial size (issue #152)
* Fixed warning about library category in Arduino 1.6.6 (issue #147)
* Examples: Added a loop to wait for serial port to be ready (issue #156)
v5.0.5
------
* Added overload `JsonObjectSuscript::set(value, decimals)` (issue #143)
* Use `float` instead of `double` to reduce the size of `JsonVariant` (issue #134)
v5.0.4
------
* Fixed ambiguous overload with `JsonArraySubscript` and `JsonObjectSubscript` (issue #122)
v5.0.3
------
* Fixed `printTo(String)` which wrote numbers instead of strings (issue #120)
* Fixed return type of `JsonArray::is<T>()` and some others (issue #121)
v5.0.2
------
* Fixed segmentation fault in `parseObject(String)` and `parseArray(String)`, when the
`StaticJsonBuffer` is too small to hold a copy of the string
* Fixed Clang warning "register specifier is deprecated" (issue #102)
* Fixed GCC warning "declaration shadows a member" (issue #103)
* Fixed memory alignment, which made ESP8266 crash (issue #104)
* Fixed compilation on Visual Studio 2010 and 2012 (issue #107)
v5.0.1
------
* Fixed compilation with Arduino 1.0.6 (issue #99)
v5.0.0
------
* Added support of `String` class (issues #55, #56, #70, #77)
* Added `JsonBuffer::strdup()` to make a copy of a string (issues #10, #57)
* Implicitly call `strdup()` for `String` but not for `char*` (issues #84, #87)
* Added support of non standard JSON input (issue #44)
* Added support of comments in JSON input (issue #88)
* Added implicit cast between numerical types (issues #64, #69, #93)
* Added ability to read number values as string (issue #90)
* Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66)
* Switched to new the library layout (requires Arduino 1.0.6 or above)
**BREAKING CHANGES**:
- `JsonObject::add()` was renamed to `set()`
- `JsonArray::at()` and `JsonObject::at()` were renamed to `get()`
- Number of digits of floating point value are now set with `double_with_n_digits()`
**Personal note about the `String` class**:
Support of the `String` class has been added to the library because many people use it in their programs.
However, you should not see this as an invitation to use the `String` class.
The `String` class is **bad** because it uses dynamic memory allocation.
Compared to static allocation, it compiles to a bigger, slower program, and is less predictable.
You certainly don't want that in an embedded environment!
v4.6
----
* Fixed segmentation fault in `DynamicJsonBuffer` when memory allocation fails (issue #92)
v4.5
----
* Fixed buffer overflow when input contains a backslash followed by a terminator (issue #81)
**Upgrading is recommended** since previous versions contain a potential security risk.
Special thanks to [Giancarlo Canales Barreto](https://github.com/gcanalesb) for finding this nasty bug.
v4.4
----
* Added `JsonArray::measureLength()` and `JsonObject::measureLength()` (issue #75)
v4.3
----
* Added `JsonArray::removeAt()` to remove an element of an array (issue #58)
* Fixed stack-overflow in `DynamicJsonBuffer` when parsing huge JSON files (issue #65)
* Fixed wrong return value of `parseArray()` and `parseObject()` when allocation fails (issue #68)
v4.2
----
* Switched back to old library layout (issues #39, #43 and #45)
* Removed global new operator overload (issue #40, #45 and #46)
* Added an example with EthernetServer
v4.1
----
@ -47,14 +299,14 @@ v3.1
Old generator API:
JsonObject<3> root;
JsonObject<3> root;
root.add("sensor", "gps");
root.add("time", 1351824120);
root.add("data", array);
New generator API:
JsonObject<3> root;
JsonObject<3> root;
root["sensor"] = "gps";
root["time"] = 1351824120;
root["data"] = array;
@ -111,7 +363,7 @@ v1.1
* Example: changed `char* json` into `char[] json` so that the bytes are not write protected
* Fixed parsing bug when the JSON contains multi-dimensional arrays
v1.0
v1.0
----
Initial release
Initial release

View File

@ -1,4 +1,11 @@
cmake_minimum_required(VERSION 2.8.4)
# Copyright Benoit Blanchon 2014-2016
# MIT License
#
# Arduino JSON library
# https://github.com/bblanchon/ArduinoJson
# If you like this project, please add a star!
cmake_minimum_required(VERSION 3.0)
project(ArduinoJson)
enable_testing()
@ -7,14 +14,8 @@ 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(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS -W4)
endif()
if(${COVERAGE})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage")
set(CMAKE_CXX_FLAGS "-g -O0 -fprofile-arcs -ftest-coverage")
endif()
add_subdirectory(src)
add_subdirectory(test)
add_subdirectory(test)

View File

@ -1,10 +1,10 @@
The MIT License (MIT)
---------------------
Copyright © 2014 Benoit BLANCHON
Copyright © 2014-2016 Benoit BLANCHON
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

114
README.md
View File

@ -1,81 +1,133 @@
Arduino JSON library
====================
[![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)
[![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)
*An elegant and efficient JSON library for embedded systems.*
It's design to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc).
It's designed to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc).
It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project.
Features
--------
* JSON decoding
* JSON decoding (comments are supported)
* JSON encoding (with optional indentation)
* Elegant API, very easy to use
* Fixed memory allocation (no malloc)
* Elegant API, very easy to use
* Fixed memory allocation (zero malloc)
* No data duplication (zero copy)
* Portable (written in C++98)
* Self-contained (no external dependency)
* Small footprint
* Header-only library
* MIT License
Works on
--------
* All Arduino boards (Uno, Due, Mini, Micro, Yun...)
* ESP8266
* Teensy
* Intel Edison and Galileo
* PlatformIO
* Energia
* RedBearLab boards (BLE Nano...)
* Computers (Windows, Linux, OSX...)
See [FAQ: Compatibility issues](https://github.com/bblanchon/ArduinoJson/wiki/Compatibility-issues)
Quick start
-----------
#### Decoding / Parsing
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
StaticJsonBuffer<200> jsonBuffer;
```c++
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
JsonObject& root = jsonBuffer.parseObject(json);
StaticJsonBuffer<200> jsonBuffer;
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
JsonObject& root = jsonBuffer.parseObject(json);
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
```
#### Encoding / Generating
StaticJsonBuffer<200> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "gps";
root["time"] = 1351824120;
```c++
StaticJsonBuffer<200> jsonBuffer;
JsonArray& data = root.createNestedArray("data");
data.add(48.756080, 6); // 6 is the number of decimals to print
data.add(2.302038, 6); // if not specified, 2 digits are printed
JsonObject& root = jsonBuffer.createObject();
root["sensor"] = "gps";
root["time"] = 1351824120;
root.printTo(Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
JsonArray& data = root.createNestedArray("data");
data.add(48.756080, 6); // 6 is the number of decimals to print
data.add(2.302038, 6); // if not specified, 2 digits are printed
root.printTo(Serial);
// This prints:
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
```
Documentation
-------------
The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)
The documentation is available online in the [Arduino JSON wiki](https://github.com/bblanchon/ArduinoJson/wiki)
Testimonials
------------
From Arduino's Forum user `jflaplante`:
> I tried aJson json-arduino before trying your library. I always ran into memory problem after a while.
> I tried aJson json-arduino before trying your library. I always ran into memory problem after a while.
> I have no such problem so far with your library. It is working perfectly with my web services.
From Arduino's Forum user `gbathree`:
> Thanks so much - this is an awesome library! If you want to see what we're doing with it - the project is located at www.photosynq.org.
From StackOverflow user `thegreendroid`:
> It has a really elegant, simple API and it works like a charm on embedded and Windows/Linux platforms. We recently started using this on an embedded project and I can vouch for its quality.
From GitHub user `zacsketches`:
> Thanks for a great library!!!
> I've been watching you consistently develop this library over the past six months, and I used it today for a publish and subscribe architecture designed to help hobbyists move into more advanced robotics. Your library allowed me to implement remote subscription in order to facilitate multi-processor robots.
> ArduinoJson saved me a week's worth of time!!
[From Reddit user `erm_what_`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusjk8c):
> This is a great library and I wouldn't be able to do the project I'm doing without it. I completely recommend it.
[From Reddit user `makerhacks`](https://www.reddit.com/r/arduino/comments/3jj6ep/announcing_arduinojson_50/cusqg7b):
> I am just starting an ESP8266 clock project and now I can output JSON from my server script and interpret it painlessly.
[From Twitter user `@hemalchevli`](https://twitter.com/hemalchevli/status/715788439397011456):
> ArduinoJson library should be used as a benchmark/reference for making libraries. Truly elegant.
[From GitHub user `sticilface`](https://github.com/bblanchon/ArduinoJson/issues/381#issuecomment-260203594):
> its a great lib:) and i use it in everything!
Donators
--------
Special thanks to the following persons and companies who made generous donations to the library author:
* Robert Murphy <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Surge Communications <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Alex Scott <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
* Firepick Services LLC <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* A B Doodkorte <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Scott Smith <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Johann Stieger <img alt='Austria' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e6-1f1f9.svg' width='18' height='18'>
* Gustavo Donizeti Gini <img alt='Brazil' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1e7-1f1f7.svg' width='18' height='18'>
* Charles-Henri Hallard <img alt='France' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1eb-1f1f7.svg' width='18' height='18'>
* Martijn van den Burg <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Nick Koumaris <img alt='Greece' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1f7.svg' width='18' height='18'>
* Jon Williams <img alt='USA' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1fa-1f1f8.svg' width='18' height='18'>
* Kestutis Liaugminas <img alt='Lithuania' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f1-1f1f9.svg' width='18' height='18'>
* Darlington Adibe <img alt='Nigeria' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1ec.svg' width='18' height='18'>
* Yoeri Kroon <img alt='Netherlands' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1f3-1f1f1.svg' width='18' height='18'>
* Andrew Melvin <img alt='United Kingdom' src='https://cdnjs.cloudflare.com/ajax/libs/emojione/2.1.4/assets/svg/1f1ec-1f1e7.svg' width='18' height='18'>
---
Found this library useful? [Help me back with a donation!](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate%40benoitblanchon%2efr&lc=GB&item_name=Benoit%20Blanchon&item_number=Arduino%20JSON&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :smile:
Found this library useful? Please star this project or [help me back with a donation!](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate%40benoitblanchon%2efr&lc=GB&item_name=Benoit%20Blanchon&item_number=Arduino%20JSON&currency_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :smile:

18
appveyor.yml Normal file
View File

@ -0,0 +1,18 @@
version: 5.7.2.{build}
environment:
matrix:
- CMAKE_GENERATOR: Visual Studio 14 2015
- CMAKE_GENERATOR: Visual Studio 12 2013
- CMAKE_GENERATOR: Visual Studio 11 2012
- CMAKE_GENERATOR: Visual Studio 10 2010
# - CMAKE_GENERATOR: MinGW Makefiles
# Note: Disabled because of unexplicated error -1073741511
# This used to work fine with GCC 4.8.2 then failed after they upgraded to GCC 4.9.3
configuration: Debug
before_build:
- set PATH=C:\MinGW\bin;%PATH:C:\Program Files\Git\usr\bin;=% # Workaround for CMake not wanting sh.exe on PATH for MinGW
- cmake -DCMAKE_BUILD_TYPE=%CONFIGURATION% -G "%CMAKE_GENERATOR%" .
build_script:
- cmake --build . --config %CONFIGURATION%
test_script:
- ctest -V .

View File

@ -1,7 +1,9 @@
/*
* Arduino JSON library - IndentedPrint example
* Benoit Blanchon 2014 - MIT License
*/
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
@ -9,6 +11,9 @@ using namespace ArduinoJson::Internals;
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
IndentedPrint serial(Serial);
serial.setTabSize(4);
@ -27,4 +32,4 @@ void setup() {
void loop() {
// not used in this example
}
}

View File

@ -1,23 +1,51 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
// Memory pool for JSON object tree.
//
// Inside the brackets, 200 is the size of the pool in bytes.
// If the JSON object is more complex, you need to increase that value.
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer allocates memory on the stack, it can be
// replaced by DynamicJsonBuffer which allocates in the heap.
// It's simpler but less efficient.
//
// DynamicJsonBuffer jsonBuffer;
// Create the root of the object tree.
//
// It's a reference to the JsonObject, the actual bytes are inside the
// JsonBuffer with all the other nodes of the object tree.
// Memory is freed when jsonBuffer goes out of scope.
JsonObject& root = jsonBuffer.createObject();
// Add values in the object
//
// Most of the time, you can rely on the implicit casts.
// In other case, you can do root.set<long>("time", 1351824120);
root["sensor"] = "gps";
root["time"] = 1351824120;
// Add a nested array.
//
// It's also possible to create the array separately and add it to the
// JsonObject but it's less efficient.
JsonArray& data = root.createNestedArray("data");
data.add(48.756080, 6); // 6 is the number of decimals to print
data.add(2.302038, 6); // if not specified, 2 digits are printed
data.add(double_with_n_digits(48.756080, 6));
data.add(double_with_n_digits(2.302038, 6));
root.printTo(Serial);
// This prints:
@ -39,4 +67,4 @@ void setup() {
void loop() {
// not used in this example
}
}

View File

@ -0,0 +1,195 @@
// Sample Arduino Json Web Client
// Downloads and parse http://jsonplaceholder.typicode.com/users/1
//
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>
EthernetClient client;
const char* server = "jsonplaceholder.typicode.com"; // server's address
const char* resource = "/users/1"; // http resource
const unsigned long BAUD_RATE = 9600; // serial connection speed
const unsigned long HTTP_TIMEOUT = 10000; // max respone time from server
const size_t MAX_CONTENT_SIZE = 512; // max size of the HTTP response
// The type of data that we want to extract from the page
struct UserData {
char name[32];
char company[32];
};
// ARDUINO entry point #1: runs once when you press reset or power the board
void setup() {
initSerial();
initEthernet();
}
// ARDUINO entry point #2: runs over and over again forever
void loop() {
if (connect(server)) {
if (sendRequest(server, resource) && skipResponseHeaders()) {
char response[MAX_CONTENT_SIZE];
readReponseContent(response, sizeof(response));
UserData userData;
if (parseUserData(response, &userData)) {
printUserData(&userData);
}
}
disconnect();
}
wait();
}
// Initialize Serial port
void initSerial() {
Serial.begin(BAUD_RATE);
while (!Serial) {
; // wait for serial port to initialize
}
Serial.println("Serial ready");
}
// Initialize Ethernet library
void initEthernet() {
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
if (!Ethernet.begin(mac)) {
Serial.println("Failed to configure Ethernet");
return;
}
Serial.println("Ethernet ready");
delay(1000);
}
// Open connection to the HTTP server
bool connect(const char* hostName) {
Serial.print("Connect to ");
Serial.println(hostName);
bool ok = client.connect(hostName, 80);
Serial.println(ok ? "Connected" : "Connection Failed!");
return ok;
}
// Send the HTTP GET request to the server
bool sendRequest(const char* host, const char* resource) {
Serial.print("GET ");
Serial.println(resource);
client.print("GET ");
client.print(resource);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(server);
client.println("Connection: close");
client.println();
return true;
}
// Skip HTTP headers so that we are at the beginning of the response's body
bool skipResponseHeaders() {
// HTTP headers end with an empty line
char endOfHeaders[] = "\r\n\r\n";
client.setTimeout(HTTP_TIMEOUT);
bool ok = client.find(endOfHeaders);
if (!ok) {
Serial.println("No response or invalid response!");
}
return ok;
}
// Read the body of the response from the HTTP server
void readReponseContent(char* content, size_t maxSize) {
size_t length = client.readBytes(content, maxSize);
content[length] = 0;
Serial.println(content);
}
// Parse the JSON from the input string and extract the interesting values
// Here is the JSON we need to parse
// {
// "id": 1,
// "name": "Leanne Graham",
// "username": "Bret",
// "email": "Sincere@april.biz",
// "address": {
// "street": "Kulas Light",
// "suite": "Apt. 556",
// "city": "Gwenborough",
// "zipcode": "92998-3874",
// "geo": {
// "lat": "-37.3159",
// "lng": "81.1496"
// }
// },
// "phone": "1-770-736-8031 x56442",
// "website": "hildegard.org",
// "company": {
// "name": "Romaguera-Crona",
// "catchPhrase": "Multi-layered client-server neural-net",
// "bs": "harness real-time e-markets"
// }
// }
bool parseUserData(char* content, struct UserData* userData) {
// Compute optimal size of the JSON buffer according to what we need to parse.
// This is only required if you use StaticJsonBuffer.
const size_t BUFFER_SIZE =
JSON_OBJECT_SIZE(8) // the root object has 8 elements
+ JSON_OBJECT_SIZE(5) // the "address" object has 5 elements
+ JSON_OBJECT_SIZE(2) // the "geo" object has 2 elements
+ JSON_OBJECT_SIZE(3); // the "company" object has 3 elements
// Allocate a temporary memory pool on the stack
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
// If the memory pool is too big for the stack, use this instead:
// DynamicJsonBuffer jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(content);
if (!root.success()) {
Serial.println("JSON parsing failed!");
return false;
}
// Here were copy the strings we're interested in
strcpy(userData->name, root["name"]);
strcpy(userData->company, root["company"]["name"]);
// It's not mandatory to make a copy, you could just use the pointers
// Since, they are pointing inside the "content" buffer, so you need to make
// sure it's still in memory when you read the string
return true;
}
// Print the data extracted from the JSON
void printUserData(const struct UserData* userData) {
Serial.print("Name = ");
Serial.println(userData->name);
Serial.print("Company = ");
Serial.println(userData->company);
}
// Close the connection with the HTTP server
void disconnect() {
Serial.println("Disconnect");
client.stop();
}
// Pause for a 1 minute
void wait() {
Serial.println("Wait 60 seconds");
delay(60000);
}

View File

@ -1,31 +1,61 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include <ArduinoJson.h>
void setup() {
Serial.begin(9600);
while (!Serial) {
// wait serial port initialization
}
// Memory pool for JSON object tree.
//
// Inside the brackets, 200 is the size of the pool in bytes,
// If the JSON object is more complex, you need to increase that value.
StaticJsonBuffer<200> jsonBuffer;
// StaticJsonBuffer allocates memory on the stack, it can be
// replaced by DynamicJsonBuffer which allocates in the heap.
// It's simpler but less efficient.
//
// DynamicJsonBuffer jsonBuffer;
// JSON input string.
//
// It's better to use a char[] as shown here.
// If you use a const char* or a String, ArduinoJson will
// have to make a copy of the input in the JsonBuffer.
char json[] =
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
// Root of the object tree.
//
// It's a reference to the JsonObject, the actual bytes are inside the
// JsonBuffer with all the other nodes of the object tree.
// Memory is freed when jsonBuffer goes out of scope.
JsonObject& root = jsonBuffer.parseObject(json);
// Test if parsing succeeds.
if (!root.success()) {
Serial.println("parseObject() failed");
return;
}
// Fetch values.
//
// Most of the time, you can rely on the implicit casts.
// In other case, you can do root["time"].as<long>();
const char* sensor = root["sensor"];
long time = root["time"];
double latitude = root["data"][0];
double longitude = root["data"][1];
// Print values.
Serial.println(sensor);
Serial.println(time);
Serial.println(latitude, 6);
@ -34,4 +64,4 @@ void setup() {
void loop() {
// not used in this example
}
}

View File

@ -0,0 +1,74 @@
// Sample Arduino Json Web Server
// Created by Benoit Blanchon.
// Heavily inspired by "Web Server" from David A. Mellis and Tom Igoe
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress ip(192, 168, 0, 177);
EthernetServer server(80);
bool readRequest(EthernetClient& client) {
bool currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
if (c == '\n' && currentLineIsBlank) {
return true;
} else if (c == '\n') {
currentLineIsBlank = true;
} else if (c != '\r') {
currentLineIsBlank = false;
}
}
}
return false;
}
JsonObject& prepareResponse(JsonBuffer& jsonBuffer) {
JsonObject& root = jsonBuffer.createObject();
JsonArray& analogValues = root.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(pin);
analogValues.add(value);
}
JsonArray& digitalValues = root.createNestedArray("digital");
for (int pin = 0; pin < 14; pin++) {
int value = digitalRead(pin);
digitalValues.add(value);
}
return root;
}
void writeResponse(EthernetClient& client, JsonObject& json) {
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: application/json");
client.println("Connection: close");
client.println();
json.prettyPrintTo(client);
}
void setup() {
Ethernet.begin(mac, ip);
server.begin();
}
void loop() {
EthernetClient client = server.available();
if (client) {
bool success = readRequest(client);
if (success) {
StaticJsonBuffer<500> jsonBuffer;
JsonObject& json = prepareResponse(jsonBuffer);
writeResponse(client, json);
}
delay(1);
client.stop();
}
}

View File

@ -0,0 +1,55 @@
// Send a JSON object on UDP at regular interval
//
// You can easily test this program with netcat:
// $ nc -ulp 8888
//
// by Benoit Blanchon, MIT License 2015-2016
#include <SPI.h>
#include <Ethernet.h>
#include <ArduinoJson.h>
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};
IPAddress localIp(192, 168, 0, 177);
IPAddress remoteIp(192, 168, 0, 109);
unsigned int remotePort = 8888;
unsigned localPort = 8888;
EthernetUDP udp;
JsonObject& buildJson(JsonBuffer& jsonBuffer) {
JsonObject& root = jsonBuffer.createObject();
JsonArray& analogValues = root.createNestedArray("analog");
for (int pin = 0; pin < 6; pin++) {
int value = analogRead(pin);
analogValues.add(value);
}
JsonArray& digitalValues = root.createNestedArray("digital");
for (int pin = 0; pin < 14; pin++) {
int value = digitalRead(pin);
digitalValues.add(value);
}
return root;
}
void sendJson(JsonObject& json) {
udp.beginPacket(remoteIp, remotePort);
json.printTo(udp);
udp.println();
udp.endPacket();
}
void setup() {
Ethernet.begin(mac, localIp);
udp.begin(localPort);
}
void loop() {
delay(1000);
StaticJsonBuffer<300> jsonBuffer;
JsonObject& json = buildJson(jsonBuffer);
sendJson(json);
}

View File

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

View File

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

View File

@ -1,12 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#include "../include/ArduinoJson/DynamicJsonBuffer.hpp"
#include "../include/ArduinoJson/JsonArray.hpp"
#include "../include/ArduinoJson/JsonObject.hpp"
#include "../include/ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson.hpp"
using namespace ArduinoJson;

22
include/ArduinoJson.hpp Normal file
View File

@ -0,0 +1,22 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "ArduinoJson/DynamicJsonBuffer.hpp"
#include "ArduinoJson/JsonArray.hpp"
#include "ArduinoJson/JsonObject.hpp"
#include "ArduinoJson/StaticJsonBuffer.hpp"
#include "ArduinoJson/Internals/JsonParser.ipp"
#include "ArduinoJson/Internals/JsonSerializer.ipp"
#include "ArduinoJson/JsonArray.ipp"
#include "ArduinoJson/JsonBuffer.ipp"
#include "ArduinoJson/JsonObject.ipp"
#include "ArduinoJson/JsonVariant.ipp"
using namespace ArduinoJson;

View File

@ -1,31 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#pragma once
#ifndef ARDUINO
#include <stddef.h>
#include <stdint.h>
// This class reproduces Arduino's Print
class Print {
public:
virtual ~Print() {}
virtual size_t write(uint8_t) = 0;
size_t print(const char[]);
size_t print(double, int = 2);
size_t print(long);
size_t println();
};
#else
#include <Print.h>
#endif

View File

@ -0,0 +1,123 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifdef ARDUINO // assume this is an embedded platform
// store using float instead of double to reduce the memory usage (issue #134)
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 0
#endif
// store using a long because it usually match the size of a float.
#ifndef ARDUINOJSON_USE_LONG_LONG
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#ifndef ARDUINOJSON_USE_INT64
#define ARDUINOJSON_USE_INT64 0
#endif
// Arduino has its own implementation of String to replace std::string
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 1
#endif
// On AVR archiecture, we can use PROGMEM
#ifndef ARDUINOJSON_ENABLE_PROGMEM
#ifdef PROGMEM
#define ARDUINOJSON_ENABLE_PROGMEM 1
#else
#define ARDUINOJSON_ENABLE_PROGMEM 0
#endif
#endif
// Arduino doesn't have std::string
#ifndef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 0
#endif
// Arduino doesn't support STL stream
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 0
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
#ifdef ARDUINO_ARCH_AVR
// alignment isn't needed for 8-bit AVR
#define ARDUINOJSON_ENABLE_ALIGNMENT 0
#else
// but must processor needs pointer to be align on word size
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
#endif
// low value to prevent stack overflow
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 10
#endif
#else // assume this is a computer
// on a computer we have plenty of memory so we can use doubles
#ifndef ARDUINOJSON_USE_DOUBLE
#define ARDUINOJSON_USE_DOUBLE 1
#endif
// use long long when available
#ifndef ARDUINOJSON_USE_LONG_LONG
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1800)
#define ARDUINOJSON_USE_LONG_LONG 1
#else
#define ARDUINOJSON_USE_LONG_LONG 0
#endif
#endif
// use _int64 on old versions of Visual Studio
#ifndef ARDUINOJSON_USE_INT64
#if defined(_MSC_VER) && _MSC_VER <= 1700
#define ARDUINOJSON_USE_INT64 1
#else
#define ARDUINOJSON_USE_INT64 0
#endif
#endif
// on a computer, we can use std::string
#ifndef ARDUINOJSON_ENABLE_STD_STRING
#define ARDUINOJSON_ENABLE_STD_STRING 1
#endif
// on a computer, there is no reason to beleive Arduino String is available
#ifndef ARDUINOJSON_ENABLE_ARDUINO_STRING
#define ARDUINOJSON_ENABLE_ARDUINO_STRING 0
#endif
// PROGMEM is only available on AVR architecture
#ifndef ARDUINOJSON_ENABLE_PROGMEM
#define ARDUINOJSON_ENABLE_PROGMEM 0
#endif
// on a computer, we can assume that the STL is there
#ifndef ARDUINOJSON_ENABLE_STD_STREAM
#define ARDUINOJSON_ENABLE_STD_STREAM 1
#endif
#ifndef ARDUINOJSON_ENABLE_ALIGNMENT
// even if not required, most cpu's are faster with aligned pointers
#define ARDUINOJSON_ENABLE_ALIGNMENT 1
#endif
// on a computer, we should have a lot of space on the stack
#ifndef ARDUINOJSON_DEFAULT_NESTING_LIMIT
#define ARDUINOJSON_DEFAULT_NESTING_LIMIT 50
#endif
#endif
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
#endif

View File

@ -1,67 +1,18 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonBuffer.hpp"
#include "Internals/BlockJsonBuffer.hpp"
namespace ArduinoJson {
// Implements a JsonBuffer with dynamic memory allocation.
// You are strongly encouraged to consider using StaticJsonBuffer which is much
// more suitable for embedded systems.
class DynamicJsonBuffer : public JsonBuffer {
public:
DynamicJsonBuffer() : _next(NULL), _size(0) {}
~DynamicJsonBuffer() { delete _next; }
size_t size() const { return _size + (_next ? _next->size() : 0); }
size_t blockCount() const { return 1 + (_next ? _next->blockCount() : 0); }
static const size_t BLOCK_CAPACITY = 32;
protected:
virtual void* alloc(size_t bytes) {
if (canAllocInThisBlock(bytes))
return allocInThisBlock(bytes);
else if (canAllocInOtherBlocks(bytes))
return allocInOtherBlocks(bytes);
else
return NULL;
}
private:
bool canAllocInThisBlock(size_t bytes) const {
return _size + bytes <= BLOCK_CAPACITY;
}
void* allocInThisBlock(size_t bytes) {
void* p = _buffer + _size;
_size += bytes;
return p;
}
bool canAllocInOtherBlocks(size_t bytes) const {
// by design a DynamicJsonBuffer can't alloc a block bigger than
// BLOCK_CAPACITY
return bytes <= BLOCK_CAPACITY;
}
void* allocInOtherBlocks(size_t bytes) {
if (!_next) {
_next = new DynamicJsonBuffer();
if (!_next) return NULL;
}
return _next->alloc(bytes);
}
DynamicJsonBuffer* _next;
size_t _size;
uint8_t _buffer[BLOCK_CAPACITY];
};
typedef Internals::BlockJsonBuffer<Internals::DefaultAllocator>
DynamicJsonBuffer;
}

View File

@ -0,0 +1,115 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include <stdlib.h>
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
namespace Internals {
class DefaultAllocator {
public:
void* allocate(size_t size) {
return malloc(size);
}
void deallocate(void* pointer) {
free(pointer);
}
};
template <typename TAllocator>
class BlockJsonBuffer : public JsonBuffer {
struct Block;
struct EmptyBlock {
Block* next;
size_t capacity;
size_t size;
};
struct Block : EmptyBlock {
uint8_t data[1];
};
public:
BlockJsonBuffer(size_t initialSize = 256)
: _head(NULL), _nextBlockSize(initialSize) {}
~BlockJsonBuffer() {
Block* currentBlock = _head;
while (currentBlock != NULL) {
Block* nextBlock = currentBlock->next;
_allocator.deallocate(currentBlock);
currentBlock = nextBlock;
}
}
size_t size() const {
size_t total = 0;
for (const Block* b = _head; b; b = b->next) total += b->size;
return total;
}
virtual void* alloc(size_t bytes) {
return canAllocInHead(bytes) ? allocInHead(bytes) : allocInNewBlock(bytes);
}
private:
bool canAllocInHead(size_t bytes) const {
return _head != NULL && _head->size + bytes <= _head->capacity;
}
void* allocInHead(size_t bytes) {
void* p = _head->data + _head->size;
_head->size += round_size_up(bytes);
return p;
}
void* allocInNewBlock(size_t bytes) {
size_t capacity = _nextBlockSize;
if (bytes > capacity) capacity = bytes;
if (!addNewBlock(capacity)) return NULL;
_nextBlockSize *= 2;
return allocInHead(bytes);
}
bool addNewBlock(size_t capacity) {
size_t bytes = sizeof(EmptyBlock) + capacity;
Block* block = static_cast<Block*>(_allocator.allocate(bytes));
if (block == NULL) return false;
block->capacity = capacity;
block->size = 0;
block->next = _head;
_head = block;
return true;
}
TAllocator _allocator;
Block* _head;
size_t _nextBlockSize;
};
}
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -0,0 +1,56 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
inline const char *skipCStyleComment(const char *ptr) {
ptr += 2;
for (;;) {
if (ptr[0] == '\0') return ptr;
if (ptr[0] == '*' && ptr[1] == '/') return ptr + 2;
ptr++;
}
}
inline const char *skipCppStyleComment(const char *ptr) {
ptr += 2;
for (;;) {
if (ptr[0] == '\0' || ptr[0] == '\n') return ptr;
ptr++;
}
}
inline const char *skipSpacesAndComments(const char *ptr) {
for (;;) {
switch (ptr[0]) {
case ' ':
case '\t':
case '\r':
case '\n':
ptr++;
continue;
case '/':
switch (ptr[1]) {
case '*':
ptr = skipCStyleComment(ptr);
break;
case '/':
ptr = skipCppStyleComment(ptr);
break;
default:
return ptr;
}
break;
default:
return ptr;
}
}
}
}
}

View File

@ -0,0 +1,21 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
// A dummy Print implementation used in JsonPrintable::measureLength()
class DummyPrint : public Print {
public:
virtual size_t write(uint8_t) { return 1; }
};
}
}

View File

@ -0,0 +1,33 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
#include "StringFuncs.hpp"
namespace ArduinoJson {
namespace Internals {
// A Print implementation that allows to write in a String
template <typename TString>
class DynamicStringBuilder : public Print {
public:
DynamicStringBuilder(TString &str) : _str(str) {}
virtual size_t write(uint8_t c) {
StringFuncs<TString>::append(_str, static_cast<char>(c));
return 1;
}
private:
DynamicStringBuilder &operator=(const DynamicStringBuilder &);
TString &_str;
};
}
}

View File

@ -0,0 +1,42 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
class Encoding {
public:
// Optimized for code size on a 8-bit AVR
static char escapeChar(char c) {
const char *p = escapeTable(false);
while (p[0] && p[1] != c) {
p += 2;
}
return p[0];
}
// Optimized for code size on a 8-bit AVR
static char unescapeChar(char c) {
const char *p = escapeTable(true);
for (;;) {
if (p[0] == '\0') return c;
if (p[0] == c) return p[1];
p += 2;
}
}
private:
static const char *escapeTable(bool excludeIdenticals) {
return &"\"\"\\\\b\bf\fn\nr\rt\t"[excludeIdenticals ? 4 : 0];
}
};
}
}

View File

@ -1,12 +1,13 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Arduino/Print.hpp"
#include "../Print.hpp"
namespace ArduinoJson {
namespace Internals {
@ -22,7 +23,13 @@ class IndentedPrint : public Print {
isNewLine = true;
}
virtual size_t write(uint8_t);
virtual size_t write(uint8_t c) {
size_t n = 0;
if (isNewLine) n += writeTabs();
n += sink->write(c);
isNewLine = c == '\n';
return n;
}
// Adds one level of indentation
void indent() {
@ -45,7 +52,11 @@ class IndentedPrint : public Print {
uint8_t tabSize : 3;
bool isNewLine : 1;
size_t writeTabs();
size_t writeTabs() {
size_t n = 0;
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
return n;
}
static const int MAX_LEVEL = 15; // because it's only 4 bits
static const int MAX_TAB_SIZE = 7; // because it's only 3 bits

View File

@ -0,0 +1,25 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
namespace ArduinoJson {
namespace Internals {
class JsonBufferAllocated {
public:
void *operator new(size_t n, JsonBuffer *jsonBuffer) throw() {
if (!jsonBuffer) return NULL;
return jsonBuffer->alloc(n);
}
void operator delete(void *, JsonBuffer *) throw() {}
};
}
}

View File

@ -0,0 +1,21 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
namespace ArduinoJson {
namespace Internals {
#if ARDUINOJSON_USE_DOUBLE
typedef double JsonFloat;
#else
typedef float JsonFloat;
#endif
}
}

View File

@ -0,0 +1,26 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
namespace ArduinoJson {
namespace Internals {
#if ARDUINOJSON_USE_LONG_LONG
typedef long long JsonInteger;
typedef unsigned long long JsonUInt;
#elif ARDUINOJSON_USE_INT64
typedef __int64 JsonInteger;
typedef unsigned _int64 JsonUInt;
#else
typedef long JsonInteger;
typedef unsigned long JsonUInt;
#endif
}
}

View File

@ -1,8 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -18,24 +19,47 @@ namespace Internals {
class JsonParser {
public:
JsonParser(JsonBuffer *buffer, char *json, uint8_t nestingLimit)
: _buffer(buffer), _ptr(json), _nestingLimit(nestingLimit) {}
: _buffer(buffer),
_readPtr(json ? json : ""),
_writePtr(json),
_nestingLimit(nestingLimit) {}
JsonArray &parseArray();
JsonObject &parseObject();
JsonVariant parseVariant() {
JsonVariant result;
parseAnythingTo(&result);
return result;
}
private:
bool skip(char charToSkip);
bool skip(const char *wordToSkip);
void skipSpaces();
void parseAnythingTo(JsonVariant &destination);
inline void parseBooleanTo(JsonVariant &destination);
inline void parseNullTo(JsonVariant &destination);
inline void parseNumberTo(JsonVariant &destination);
inline const char *parseString();
const char *parseString();
bool parseAnythingTo(JsonVariant *destination);
FORCE_INLINE bool parseAnythingToUnsafe(JsonVariant *destination);
inline bool parseArrayTo(JsonVariant *destination);
inline bool parseObjectTo(JsonVariant *destination);
inline bool parseStringTo(JsonVariant *destination);
static inline bool isInRange(char c, char min, char max) {
return min <= c && c <= max;
}
static inline bool isLetterOrNumber(char c) {
return isInRange(c, '0', '9') || isInRange(c, 'a', 'z') ||
isInRange(c, 'A', 'Z') || c == '+' || c == '-' || c == '.';
}
static inline bool isQuote(char c) {
return c == '\'' || c == '\"';
}
JsonBuffer *_buffer;
char *_ptr;
const char *_readPtr;
char *_writePtr;
uint8_t _nestingLimit;
};
}

View File

@ -0,0 +1,191 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Comments.hpp"
#include "JsonParser.hpp"
inline bool ArduinoJson::Internals::JsonParser::skip(char charToSkip) {
const char *ptr = skipSpacesAndComments(_readPtr);
if (*ptr != charToSkip) return false;
ptr++;
_readPtr = skipSpacesAndComments(ptr);
return true;
}
inline bool ArduinoJson::Internals::JsonParser::parseAnythingTo(
JsonVariant *destination) {
if (_nestingLimit == 0) return false;
_nestingLimit--;
bool success = parseAnythingToUnsafe(destination);
_nestingLimit++;
return success;
}
inline bool ArduinoJson::Internals::JsonParser::parseAnythingToUnsafe(
JsonVariant *destination) {
_readPtr = skipSpacesAndComments(_readPtr);
switch (*_readPtr) {
case '[':
return parseArrayTo(destination);
case '{':
return parseObjectTo(destination);
default:
return parseStringTo(destination);
}
}
inline ArduinoJson::JsonArray &
ArduinoJson::Internals::JsonParser::parseArray() {
// Create an empty array
JsonArray &array = _buffer->createArray();
// Check opening braket
if (!skip('[')) goto ERROR_MISSING_BRACKET;
if (skip(']')) goto SUCCESS_EMPTY_ARRAY;
// Read each value
for (;;) {
// 1 - Parse value
JsonVariant value;
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
if (!array.add(value)) goto ERROR_NO_MEMORY;
// 2 - More values?
if (skip(']')) goto SUCCES_NON_EMPTY_ARRAY;
if (!skip(',')) goto ERROR_MISSING_COMMA;
}
SUCCESS_EMPTY_ARRAY:
SUCCES_NON_EMPTY_ARRAY:
return array;
ERROR_INVALID_VALUE:
ERROR_MISSING_BRACKET:
ERROR_MISSING_COMMA:
ERROR_NO_MEMORY:
return JsonArray::invalid();
}
inline bool ArduinoJson::Internals::JsonParser::parseArrayTo(
JsonVariant *destination) {
JsonArray &array = parseArray();
if (!array.success()) return false;
*destination = array;
return true;
}
inline ArduinoJson::JsonObject &
ArduinoJson::Internals::JsonParser::parseObject() {
// Create an empty object
JsonObject &object = _buffer->createObject();
// Check opening brace
if (!skip('{')) goto ERROR_MISSING_BRACE;
if (skip('}')) goto SUCCESS_EMPTY_OBJECT;
// Read each key value pair
for (;;) {
// 1 - Parse key
const char *key = parseString();
if (!key) goto ERROR_INVALID_KEY;
if (!skip(':')) goto ERROR_MISSING_COLON;
// 2 - Parse value
JsonVariant value;
if (!parseAnythingTo(&value)) goto ERROR_INVALID_VALUE;
if (!object.set(key, value)) goto ERROR_NO_MEMORY;
// 3 - More keys/values?
if (skip('}')) goto SUCCESS_NON_EMPTY_OBJECT;
if (!skip(',')) goto ERROR_MISSING_COMMA;
}
SUCCESS_EMPTY_OBJECT:
SUCCESS_NON_EMPTY_OBJECT:
return object;
ERROR_INVALID_KEY:
ERROR_INVALID_VALUE:
ERROR_MISSING_BRACE:
ERROR_MISSING_COLON:
ERROR_MISSING_COMMA:
ERROR_NO_MEMORY:
return JsonObject::invalid();
}
inline bool ArduinoJson::Internals::JsonParser::parseObjectTo(
JsonVariant *destination) {
JsonObject &object = parseObject();
if (!object.success()) return false;
*destination = object;
return true;
}
inline const char *ArduinoJson::Internals::JsonParser::parseString() {
const char *readPtr = _readPtr;
char *writePtr = _writePtr;
char c = *readPtr;
if (isQuote(c)) { // quotes
char stopChar = c;
for (;;) {
c = *++readPtr;
if (c == '\0') break;
if (c == stopChar) {
readPtr++;
break;
}
if (c == '\\') {
// replace char
c = Encoding::unescapeChar(*++readPtr);
if (c == '\0') break;
}
*writePtr++ = c;
}
} else { // no quotes
for (;;) {
if (!isLetterOrNumber(c)) break;
*writePtr++ = c;
c = *++readPtr;
}
}
// end the string here
*writePtr++ = '\0';
const char *startPtr = _writePtr;
// update end ptr
_readPtr = readPtr;
_writePtr = writePtr;
// return pointer to unquoted string
return startPtr;
}
inline bool ArduinoJson::Internals::JsonParser::parseStringTo(
JsonVariant *destination) {
bool hasQuotes = isQuote(_readPtr[0]);
const char *value = parseString();
if (value == NULL) return false;
if (hasQuotes) {
*destination = value;
} else {
*destination = RawJson(value);
}
return true;
}

View File

@ -1,15 +1,25 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
#include "../TypeTraits/EnableIf.hpp"
#include "DummyPrint.hpp"
#include "DynamicStringBuilder.hpp"
#include "IndentedPrint.hpp"
#include "JsonSerializer.hpp"
#include "JsonWriter.hpp"
#include "Prettyfier.hpp"
#include "StringBuilder.hpp"
#include "StaticStringBuilder.hpp"
#if ARDUINOJSON_ENABLE_STD_STREAM
#include "StreamPrintAdapter.hpp"
#endif
namespace ArduinoJson {
namespace Internals {
@ -23,12 +33,27 @@ class JsonPrintable {
public:
size_t printTo(Print &print) const {
JsonWriter writer(print);
downcast().writeTo(writer);
JsonSerializer::serialize(downcast(), writer);
return writer.bytesWritten();
}
#if ARDUINOJSON_ENABLE_STD_STREAM
std::ostream &printTo(std::ostream &os) const {
StreamPrintAdapter adapter(os);
printTo(adapter);
return os;
}
#endif
size_t printTo(char *buffer, size_t bufferSize) const {
StringBuilder sb(buffer, bufferSize);
StaticStringBuilder sb(buffer, bufferSize);
return printTo(sb);
}
template <typename TString>
typename TypeTraits::EnableIf<StringFuncs<TString>::has_append, size_t>::type
printTo(TString &str) const {
DynamicStringBuilder<TString> sb(str);
return printTo(sb);
}
@ -38,7 +63,7 @@ class JsonPrintable {
}
size_t prettyPrintTo(char *buffer, size_t bufferSize) const {
StringBuilder sb(buffer, bufferSize);
StaticStringBuilder sb(buffer, bufferSize);
return prettyPrintTo(sb);
}
@ -47,8 +72,34 @@ class JsonPrintable {
return prettyPrintTo(indentedPrint);
}
template <typename TString>
typename TypeTraits::EnableIf<StringFuncs<TString>::has_append, size_t>::type
prettyPrintTo(TString &str) const {
DynamicStringBuilder<TString> sb(str);
return prettyPrintTo(sb);
}
size_t measureLength() const {
DummyPrint dp;
return printTo(dp);
}
size_t measurePrettyLength() const {
DummyPrint dp;
return prettyPrintTo(dp);
}
private:
const T &downcast() const { return *static_cast<const T *>(this); }
const T &downcast() const {
return *static_cast<const T *>(this);
}
};
#if ARDUINOJSON_ENABLE_STD_STREAM
template <typename T>
inline std::ostream &operator<<(std::ostream &os, const JsonPrintable<T> &v) {
return v.printTo(os);
}
#endif
}
}

View File

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

View File

@ -0,0 +1,101 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonArray.hpp"
#include "../JsonArraySubscript.hpp"
#include "../JsonObject.hpp"
#include "../JsonObjectSubscript.hpp"
#include "../JsonVariant.hpp"
#include "JsonSerializer.hpp"
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonArray& array, JsonWriter& writer) {
writer.beginArray();
JsonArray::const_iterator it = array.begin();
while (it != array.end()) {
serialize(*it, writer);
++it;
if (it == array.end()) break;
writer.writeComma();
}
writer.endArray();
}
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonArraySubscript& arraySubscript, JsonWriter& writer) {
serialize(arraySubscript.as<JsonVariant>(), writer);
}
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonObject& object, JsonWriter& writer) {
writer.beginObject();
JsonObject::const_iterator it = object.begin();
while (it != object.end()) {
writer.writeString(it->key);
writer.writeColon();
serialize(it->value, writer);
++it;
if (it == object.end()) break;
writer.writeComma();
}
writer.endObject();
}
template <typename TKey>
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonObjectSubscript<TKey>& objectSubscript, JsonWriter& writer) {
serialize(objectSubscript.template as<JsonVariant>(), writer);
}
inline void ArduinoJson::Internals::JsonSerializer::serialize(
const JsonVariant& variant, JsonWriter& writer) {
switch (variant._type) {
case JSON_UNDEFINED:
return;
case JSON_ARRAY:
serialize(*variant._content.asArray, writer);
return;
case JSON_OBJECT:
serialize(*variant._content.asObject, writer);
return;
case JSON_STRING:
writer.writeString(variant._content.asString);
return;
case JSON_UNPARSED:
writer.writeRaw(variant._content.asString);
return;
case JSON_NEGATIVE_INTEGER:
writer.writeRaw('-');
case JSON_POSITIVE_INTEGER:
writer.writeInteger(variant._content.asInteger);
return;
case JSON_BOOLEAN:
writer.writeBoolean(variant._content.asInteger != 0);
return;
default:
uint8_t decimals =
static_cast<uint8_t>(variant._type - JSON_FLOAT_0_DECIMALS);
writer.writeFloat(variant._content.asFloat, decimals);
}
}

View File

@ -0,0 +1,45 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
// A metafunction that returns the type of the value returned by
// JsonVariant::as<T>()
template <typename T>
struct JsonVariantAs {
typedef T type;
};
template <>
struct JsonVariantAs<char*> {
typedef const char* type;
};
template <>
struct JsonVariantAs<JsonArray> {
typedef JsonArray& type;
};
template <>
struct JsonVariantAs<const JsonArray> {
typedef const JsonArray& type;
};
template <>
struct JsonVariantAs<JsonObject> {
typedef JsonObject& type;
};
template <>
struct JsonVariantAs<const JsonObject> {
typedef const JsonObject& type;
};
}
}

View File

@ -1,11 +1,15 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonFloat.hpp"
#include "JsonInteger.hpp"
namespace ArduinoJson {
// Forward declarations
@ -13,13 +17,11 @@ class JsonArray;
class JsonObject;
namespace Internals {
// A union that defines the actual content of a JsonVariant.
// The enum JsonVariantType determines which member is in use.
union JsonVariantContent {
bool asBoolean;
double asDouble; // asDouble is also used for float
long asLong; // asLong is also used for char, short and int
JsonFloat asFloat; // used for double and float
JsonUInt asInteger; // used for bool, char, short, int and longs
const char* asString; // asString can be null
JsonArray* asArray; // asArray cannot be null
JsonObject* asObject; // asObject cannot be null

View File

@ -0,0 +1,26 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace Internals {
template <typename T>
struct JsonVariantDefault {
static T get() {
return T();
}
};
template <typename T>
struct JsonVariantDefault<const T> : JsonVariantDefault<T> {};
template <typename T>
struct JsonVariantDefault<T&> : JsonVariantDefault<T> {};
}
}

View File

@ -1,32 +1,38 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
class JsonArray;
class JsonObject;
namespace Internals {
// Enumerated type to know the current type of a JsonVariant.
// The value determines which member of JsonVariantContent is used.
enum JsonVariantType {
JSON_INVALID, // a special state for JsonVariant::invalid()
JSON_UNDEFINED, // the JsonVariant has not been initialized
JSON_ARRAY, // the JsonVariant stores a pointer to a JsonArray
JSON_OBJECT, // the JsonVariant stores a pointer to a JsonObject
JSON_BOOLEAN, // the JsonVariant stores a bool
JSON_STRING, // the JsonVariant stores a const char*
JSON_LONG, // the JsonVariant stores a long
JSON_UNDEFINED, // JsonVariant has not been initialized
JSON_UNPARSED, // JsonVariant contains an unparsed string
JSON_STRING, // JsonVariant stores a const char*
JSON_BOOLEAN, // JsonVariant stores a bool
JSON_POSITIVE_INTEGER, // JsonVariant stores an unsigned long
JSON_NEGATIVE_INTEGER, // JsonVariant stores an unsigned long that must be
// negated
JSON_ARRAY, // JsonVariant stores a pointer to a JsonArray
JSON_OBJECT, // JsonVariant stores a pointer to a JsonObject
// The following values are reserved for double values
// The following values are reserved for float values
// Multiple values are used for double, depending on the number of decimal
// digits that must be printed in the JSON output.
// This little trick allow to save one extra member in JsonVariant
JSON_DOUBLE_0_DECIMALS
// JSON_DOUBLE_1_DECIMAL
// JSON_DOUBLE_2_DECIMALS
JSON_FLOAT_0_DECIMALS
// JSON_FLOAT_1_DECIMAL
// JSON_FLOAT_2_DECIMALS
// ...
};
}

View File

@ -1,13 +1,19 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Arduino/Print.hpp"
#include "QuotedString.hpp"
#include "../Polyfills/attributes.hpp"
#include "../Polyfills/math.hpp"
#include "../Polyfills/normalize.hpp"
#include "../Print.hpp"
#include "Encoding.hpp"
#include "JsonFloat.hpp"
#include "JsonInteger.hpp"
namespace ArduinoJson {
namespace Internals {
@ -26,39 +32,153 @@ class JsonWriter {
// Returns the number of bytes sent to the Print implementation.
// This is very handy for implementations of printTo() that must return the
// number of bytes written.
size_t bytesWritten() { return _length; }
void beginArray() { write('['); }
void endArray() { write(']'); }
void beginObject() { write('{'); }
void endObject() { write('}'); }
void writeColon() { write(':'); }
void writeComma() { write(','); }
void writeString(const char *value) {
_length += QuotedString::printTo(value, _sink);
size_t bytesWritten() const {
return _length;
}
void writeLong(long value) { _length += _sink.print(value); }
void beginArray() {
writeRaw('[');
}
void endArray() {
writeRaw(']');
}
void beginObject() {
writeRaw('{');
}
void endObject() {
writeRaw('}');
}
void writeColon() {
writeRaw(':');
}
void writeComma() {
writeRaw(',');
}
void writeBoolean(bool value) {
_length += _sink.print(value ? "true" : "false");
writeRaw(value ? "true" : "false");
}
void writeDouble(double value, uint8_t decimals) {
_length += _sink.print(value, decimals);
void writeString(const char *value) {
if (!value) {
writeRaw("null");
} else {
writeRaw('\"');
while (*value) writeChar(*value++);
writeRaw('\"');
}
}
void writeChar(char c) {
char specialChar = Encoding::escapeChar(c);
if (specialChar) {
writeRaw('\\');
writeRaw(specialChar);
} else {
writeRaw(c);
}
}
void writeFloat(JsonFloat value, uint8_t digits = 2) {
if (Polyfills::isNaN(value)) return writeRaw("NaN");
if (value < 0.0) {
writeRaw('-');
value = -value;
}
if (Polyfills::isInfinity(value)) return writeRaw("Infinity");
short powersOf10;
if (value > 1000 || value < 0.001) {
powersOf10 = Polyfills::normalize(value);
} else {
powersOf10 = 0;
}
// Round up last digit (so that print(1.999, 2) prints as "2.00")
value += getRoundingBias(digits);
// Extract the integer part of the value and print it
JsonUInt int_part = static_cast<JsonUInt>(value);
JsonFloat remainder = value - static_cast<JsonFloat>(int_part);
writeInteger(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
writeRaw('.');
}
// Extract digits from the remainder one at a time
while (digits-- > 0) {
// Extract digit
remainder *= 10.0;
char currentDigit = char(remainder);
remainder -= static_cast<JsonFloat>(currentDigit);
// Print
writeRaw(char('0' + currentDigit));
}
if (powersOf10 < 0) {
writeRaw("e-");
writeInteger(-powersOf10);
}
if (powersOf10 > 0) {
writeRaw('e');
writeInteger(powersOf10);
}
}
void writeInteger(JsonUInt value) {
char buffer[22];
char *ptr = buffer + sizeof(buffer) - 1;
*ptr = 0;
do {
*--ptr = static_cast<char>(value % 10 + '0');
value /= 10;
} while (value);
writeRaw(ptr);
}
void writeRaw(const char *s) {
_length += _sink.print(s);
}
void writeRaw(char c) {
_length += _sink.write(c);
}
protected:
void write(char c) { _length += _sink.write(c); }
void write(const char *s) { _length += _sink.print(s); }
Print &_sink;
size_t _length;
private:
JsonWriter &operator=(const JsonWriter &); // cannot be assigned
static JsonFloat getLastDigit(uint8_t digits) {
// Designed as a compromise between code size and speed
switch (digits) {
case 0:
return 1e-0;
case 1:
return 1e-1;
case 2:
return 1e-2;
case 3:
return 1e-3;
default:
return getLastDigit(uint8_t(digits - 4)) * 1e-4;
}
}
FORCE_INLINE static JsonFloat getRoundingBias(uint8_t digits) {
return 0.5 * getLastDigit(digits);
}
};
}
}

View File

@ -1,15 +1,15 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include "ListConstIterator.hpp"
#include "ListIterator.hpp"
#include "PlacementNew.hpp"
namespace ArduinoJson {
namespace Internals {
@ -36,36 +36,56 @@ class List {
// Would return false in the following situation:
// - the memory allocation failed (StaticJsonBuffer was too small)
// - the JSON parsing failed
bool success() const { return _buffer != NULL; }
bool success() const {
return _buffer != NULL;
}
// Returns the numbers of elements in the list.
// For a JsonObject, it would return the number of key-value pairs
int size() const;
iterator begin() { return iterator(_firstNode); }
iterator end() { return iterator(NULL); }
const_iterator begin() const { return const_iterator(_firstNode); }
const_iterator end() const { return const_iterator(NULL); }
protected:
node_type *createNode() {
if (!_buffer) return NULL;
void *ptr = _buffer->alloc(sizeof(node_type));
return ptr ? new (ptr) node_type() : NULL;
size_t size() const {
size_t nodeCount = 0;
for (node_type *node = _firstNode; node; node = node->next) nodeCount++;
return nodeCount;
}
void addNode(node_type *nodeToAdd) {
iterator begin() {
return iterator(_firstNode);
}
iterator end() {
return iterator(NULL);
}
const_iterator begin() const {
return const_iterator(_firstNode);
}
const_iterator end() const {
return const_iterator(NULL);
}
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 = nodeToAdd;
lastNode->next = newNode;
} else {
_firstNode = nodeToAdd;
_firstNode = newNode;
}
return newNode;
}
void removeNode(node_type *nodeToRemove);
void removeNode(node_type *nodeToRemove) {
if (!nodeToRemove) return;
if (nodeToRemove == _firstNode) {
_firstNode = nodeToRemove->next;
} else {
for (node_type *node = _firstNode; node; node = node->next)
if (node->next == nodeToRemove) node->next = nodeToRemove->next;
}
}
JsonBuffer *_buffer;
node_type *_firstNode;

View File

@ -1,8 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once

View File

@ -1,8 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once

View File

@ -1,23 +1,26 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include <stddef.h> // for NULL
#include "JsonBufferAllocated.hpp"
namespace ArduinoJson {
namespace Internals {
// A node for a singly-linked list.
// Used by List<T> and its iterators.
template <typename T>
struct ListNode {
struct ListNode : public Internals::JsonBufferAllocated {
ListNode() : next(NULL) {}
ListNode<T>* next;
ListNode<T> *next;
T content;
};
}

View File

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

View File

@ -1,19 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#pragma once
#ifdef ARDUINO
// Declares the placement new as in <new>.
// This is required for Arduino IDE because it doesn't include the <new> header.
inline void *operator new(size_t, void *p) throw() { return p; }
#else
#include <new>
#endif

View File

@ -1,8 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -19,24 +20,107 @@ class Prettyfier : public Print {
_inString = false;
}
virtual size_t write(uint8_t);
virtual size_t write(uint8_t c) {
size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
_previousChar = c;
return n;
}
private:
Prettyfier& operator=(const Prettyfier&); // cannot be assigned
bool inEmptyBlock() { return _previousChar == '{' || _previousChar == '['; }
bool inEmptyBlock() {
return _previousChar == '{' || _previousChar == '[';
}
size_t handleStringChar(uint8_t);
size_t handleMarkupChar(uint8_t);
size_t handleStringChar(uint8_t c) {
bool isQuote = c == '"' && _previousChar != '\\';
size_t handleBlockClose(uint8_t);
size_t handleBlockOpen(uint8_t);
size_t handleColumn();
size_t handleComma();
size_t handleQuoteOpen();
size_t handleNormalChar(uint8_t);
size_t indentIfNeeded();
size_t unindentIfNeeded();
if (isQuote) _inString = false;
return _sink.write(c);
}
size_t handleMarkupChar(uint8_t c) {
switch (c) {
case '{':
case '[':
return writeBlockOpen(c);
case '}':
case ']':
return writeBlockClose(c);
case ':':
return writeColon();
case ',':
return writeComma();
case '"':
return writeQuoteOpen();
default:
return writeNormalChar(c);
}
}
size_t writeBlockClose(uint8_t c) {
size_t n = 0;
n += unindentIfNeeded();
n += _sink.write(c);
return n;
}
size_t writeBlockOpen(uint8_t c) {
size_t n = 0;
n += indentIfNeeded();
n += _sink.write(c);
return n;
}
size_t writeColon() {
size_t n = 0;
n += _sink.write(':');
n += _sink.write(' ');
return n;
}
size_t writeComma() {
size_t n = 0;
n += _sink.write(',');
n += _sink.println();
return n;
}
size_t writeQuoteOpen() {
_inString = true;
size_t n = 0;
n += indentIfNeeded();
n += _sink.write('"');
return n;
}
size_t writeNormalChar(uint8_t c) {
size_t n = 0;
n += indentIfNeeded();
n += _sink.write(c);
return n;
}
size_t indentIfNeeded() {
if (!inEmptyBlock()) return 0;
_sink.indent();
return _sink.println();
}
size_t unindentIfNeeded() {
if (inEmptyBlock()) return 0;
_sink.unindent();
return _sink.println();
}
uint8_t _previousChar;
IndentedPrint& _sink;

View File

@ -1,29 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#pragma once
#include "../Arduino/Print.hpp"
namespace ArduinoJson {
namespace Internals {
// An helper class to print and extract doubly-quoted strings
class QuotedString {
public:
// Writes a doubly-quote string to a Print implementation.
// It adds the double quotes (") at the beginning and the end of the string.
// It escapes the special characters as required by the JSON specifications.
static size_t printTo(const char *, Print &);
// Reads a doubly-quoted string from a buffer.
// It removes the double quotes (").
// It unescapes the special character as required by the JSON specification,
// with the exception of the Unicode characters (\u0000).
static char *extractFrom(char *input, char **end);
};
}
}

View File

@ -1,8 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once

View File

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

@ -0,0 +1,39 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
#if ARDUINOJSON_ENABLE_STD_STREAM
#include "../Print.hpp"
#include <ostream>
namespace ArduinoJson {
namespace Internals {
class StreamPrintAdapter : public Print {
public:
explicit StreamPrintAdapter(std::ostream& os) : _os(os) {}
virtual size_t write(uint8_t c) {
_os << static_cast<char>(c);
return 1;
}
private:
// cannot be assigned
StreamPrintAdapter& operator=(const StreamPrintAdapter&);
std::ostream& _os;
};
}
}
#endif // ARDUINOJSON_ENABLE_STD_STREAM

View File

@ -1,30 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#pragma once
#include "../Arduino/Print.hpp"
namespace ArduinoJson {
namespace Internals {
// A Print implementation that allows to write in a char[]
class StringBuilder : public Print {
public:
StringBuilder(char *buf, int size)
: buffer(buf), capacity(size - 1), length(0) {
buffer[0] = '\0';
}
virtual size_t write(uint8_t c);
private:
char *buffer;
int capacity;
int length;
};
}
}

View File

@ -0,0 +1,121 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
#include <WString.h>
#endif
#if ARDUINOJSON_ENABLE_STD_STRING
#include <string>
#endif
namespace ArduinoJson {
namespace Internals {
template <typename TString>
struct StringFuncs {};
template <typename TString>
struct StringFuncs<const TString> : StringFuncs<TString> {};
template <typename TString>
struct StringFuncs<TString&> : StringFuncs<TString> {};
struct CharPtrFuncs {
static bool equals(const char* str, const char* expected) {
return strcmp(str, expected) == 0;
}
template <typename Buffer>
static char* duplicate(const char* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen(str) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy(dup, str, size);
return static_cast<char*>(dup);
}
static const bool has_append = false;
static const bool has_equals = true;
static const bool should_duplicate = false;
};
template <>
struct StringFuncs<const char*> : CharPtrFuncs {};
template <>
struct StringFuncs<char*> : CharPtrFuncs {};
template <size_t N>
struct StringFuncs<char[N]> : CharPtrFuncs {};
template <size_t N>
struct StringFuncs<const char[N]> : CharPtrFuncs {};
template <typename TString>
struct StdStringFuncs {
template <typename Buffer>
static char* duplicate(const TString& str, Buffer* buffer) {
if (!str.c_str()) return NULL; // <- Arduino string can return NULL
size_t size = str.length() + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy(dup, str.c_str(), size);
return static_cast<char*>(dup);
}
static bool equals(const TString& str, const char* expected) {
return str == expected;
}
static void append(TString& str, char c) {
str += c;
}
static const bool has_append = true;
static const bool has_equals = true;
static const bool should_duplicate = true;
};
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
template <>
struct StringFuncs<String> : StdStringFuncs<String> {};
template <>
struct StringFuncs<StringSumHelper> : StdStringFuncs<StringSumHelper> {};
#endif
#if ARDUINOJSON_ENABLE_STD_STRING
template <>
struct StringFuncs<std::string> : StdStringFuncs<std::string> {};
#endif
#if ARDUINOJSON_ENABLE_PROGMEM
template <>
struct StringFuncs<const __FlashStringHelper*> {
static bool equals(const __FlashStringHelper* str, const char* expected) {
return strcmp_P(expected, (PGM_P)str) == 0;
}
template <typename Buffer>
static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) {
if (!str) return NULL;
size_t size = strlen_P((PGM_P)str) + 1;
void* dup = buffer->alloc(size);
if (dup != NULL) memcpy_P(dup, (PGM_P)str, size);
return static_cast<char*>(dup);
}
static const bool has_append = false;
static const bool has_equals = true;
static const bool should_duplicate = true;
};
#endif
}
}

View File

@ -0,0 +1,41 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../JsonBuffer.hpp"
#include "../JsonVariant.hpp"
#include "../TypeTraits/EnableIf.hpp"
#include "StringFuncs.hpp"
namespace ArduinoJson {
namespace Internals {
template <typename TSource, typename Enable = void>
struct ValueSetter {
template <typename TDestination>
static bool set(JsonBuffer*, TDestination& destination,
const TSource& source) {
destination = source;
return true;
}
};
template <typename TSource>
struct ValueSetter<TSource, typename TypeTraits::EnableIf<
StringFuncs<TSource>::should_duplicate>::type> {
template <typename TDestination>
static bool set(JsonBuffer* buffer, TDestination& destination,
const TSource& source) {
const char* copy = buffer->strdup(source);
if (!copy) return false;
destination = copy;
return true;
}
};
}
}

View File

@ -1,15 +1,23 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/JsonBufferAllocated.hpp"
#include "Internals/JsonPrintable.hpp"
#include "Internals/List.hpp"
#include "Internals/ReferenceType.hpp"
#include "Internals/StringFuncs.hpp"
#include "Internals/ValueSetter.hpp"
#include "JsonVariant.hpp"
#include "TypeTraits/ConstRefOrConstPtr.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsSame.hpp"
// Returns the size (in bytes) of an array with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
@ -21,6 +29,7 @@ namespace ArduinoJson {
// Forward declarations
class JsonObject;
class JsonBuffer;
class JsonArraySubscript;
// An array of JsonVariant.
//
@ -30,36 +39,94 @@ class JsonBuffer;
// It can also be deserialized from a JSON string via JsonBuffer::parseArray().
class JsonArray : public Internals::JsonPrintable<JsonArray>,
public Internals::ReferenceType,
public Internals::List<JsonVariant> {
// JsonBuffer is a friend because it needs to call the private constructor.
friend class JsonBuffer;
public Internals::List<JsonVariant>,
public Internals::JsonBufferAllocated {
public:
// Returns the JsonVariant at the specified index (synonym for operator[])
JsonVariant &at(int index) const;
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not call this constructor directly.
// Instead, use JsonBuffer::createArray() or JsonBuffer::parseArray().
explicit JsonArray(JsonBuffer *buffer)
: Internals::List<JsonVariant>(buffer) {}
// Returns the JsonVariant at the specified index (synonym for at())
JsonVariant &operator[](int index) const { return at(index); }
// Adds an uninitialized JsonVariant at the end of the array.
// Return a reference or JsonVariant::invalid() if allocation fails.
JsonVariant &add();
// Adds the specified value at the end of the array.
template <typename T>
void add(T value) {
add().set(value);
// Gets the value at the specified index
JsonVariant operator[](size_t index) const {
return get<JsonVariant>(index);
}
// Adds the specified double value at the end of the array.
// The value will be printed with the specified number of decimal digits.
void add(double value, uint8_t decimals) { add().set(value, decimals); }
// Gets or sets the value at specified index
JsonArraySubscript operator[](size_t index);
// Adds a reference to the specified JsonArray at the end of the array.
void add(JsonArray &array) { add().set(array); }
// Adds the specified value at the end of the array.
//
// bool add(bool);
// bool add(char);
// bool add(long);
// bool add(int);
// bool add(short);
// bool add(float value);
// bool add(double value);
// bool add(const char*);
// bool add(const char[]);
// bool add(const char[N]);
// bool add(RawJson);
// bool add(const std::string&)
// bool add(const String&)
// bool add(const JsonVariant&);
// bool add(JsonArray&);
// bool add(JsonObject&);
template <typename T>
bool add(const T &value) {
// reduce the number of template function instanciation to reduce code size
return addNodeImpl<typename TypeTraits::ConstRefOrConstPtr<T>::type>(value);
}
// bool add(float value, uint8_t decimals);
// bool add(double value, uint8_t decimals);
template <typename T>
bool add(T value, uint8_t decimals) {
return add(JsonVariant(value, decimals));
}
// Adds a reference to the specified JsonObject at the end of the array.
void add(JsonObject &obejct) { add().set(obejct); }
// Sets the value at specified index.
//
// bool set(size_t index, bool value);
// bool set(size_t index, long value);
// bool set(size_t index, int value);
// bool set(size_t index, short value);
// bool set(size_t index, const std::string&)
// bool set(size_t index, const String&)
// bool set(size_t index, const JsonVariant&);
// bool set(size_t index, JsonArray&);
// bool set(size_t index, JsonObject&);
template <typename T>
bool set(size_t index, const T &value) {
// reduce the number of template function instanciation to reduce code size
return setNodeAt<typename TypeTraits::ConstRefOrConstPtr<T>::type>(index,
value);
}
// bool set(size_t index, float value, uint8_t decimals = 2);
// bool set(size_t index, double value, uint8_t decimals = 2);
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
set(size_t index, T value, uint8_t decimals) {
return set(index, JsonVariant(value, decimals));
}
// Gets the value at the specified index.
template <typename T>
typename Internals::JsonVariantAs<T>::type get(size_t index) const {
node_type *node = getNodeAt(index);
return node ? node->content.as<T>()
: Internals::JsonVariantDefault<T>::get();
;
}
// Check the type of the value at specified index.
template <typename T>
bool is(size_t index) const {
node_type *node = getNodeAt(index);
return node ? node->content.is<T>() : false;
}
// Creates a JsonArray and adds a reference at the end of the array.
// It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
@ -69,20 +136,95 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>,
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
JsonObject &createNestedObject();
// Removes element at specified index.
void removeAt(size_t index) {
removeNode(getNodeAt(index));
}
// Returns a reference an invalid JsonArray.
// This object is meant to replace a NULL pointer.
// This is used when memory allocation or JSON parsing fail.
static JsonArray &invalid() { return _invalid; }
static JsonArray &invalid() {
static JsonArray instance(NULL);
return instance;
}
// Serialize the array to the specified JsonWriter.
void writeTo(Internals::JsonWriter &writer) const;
// Imports a 1D array
template <typename T, size_t N>
bool copyFrom(T (&array)[N]) {
return copyFrom(array, N);
}
// Imports a 1D array
template <typename T>
bool copyFrom(T *array, size_t len) {
bool ok = true;
for (size_t i = 0; i < len; i++) {
ok &= add(array[i]);
}
return ok;
}
// Imports a 2D array
template <typename T, size_t N1, size_t N2>
bool copyFrom(T (&array)[N1][N2]) {
bool ok = true;
for (size_t i = 0; i < N1; i++) {
JsonArray &nestedArray = createNestedArray();
for (size_t j = 0; j < N2; j++) {
ok &= nestedArray.add(array[i][j]);
}
}
return ok;
}
// Exports a 1D array
template <typename T, size_t N>
size_t copyTo(T (&array)[N]) const {
return copyTo(array, N);
}
// Exports a 1D array
template <typename T>
size_t copyTo(T *array, size_t len) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < len; ++it)
array[i++] = *it;
return i;
}
// Exports a 2D array
template <typename T, size_t N1, size_t N2>
void copyTo(T (&array)[N1][N2]) const {
size_t i = 0;
for (const_iterator it = begin(); it != end() && i < N1; ++it) {
it->asArray().copyTo(array[i++]);
}
}
private:
// Create an empty JsonArray attached to the specified JsonBuffer.
explicit JsonArray(JsonBuffer *buffer)
: Internals::List<JsonVariant>(buffer) {}
node_type *getNodeAt(size_t index) const {
node_type *node = _firstNode;
while (node && index--) node = node->next;
return node;
}
// The instance returned by JsonArray::invalid()
static JsonArray _invalid;
template <typename TValueRef>
bool setNodeAt(size_t index, TValueRef value) {
node_type *node = getNodeAt(index);
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
value);
}
template <typename TValueRef>
bool addNodeImpl(TValueRef value) {
node_type *node = addNewNode();
if (!node) return false;
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content,
value);
}
};
}

View File

@ -0,0 +1,62 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonArray.hpp"
#include "JsonArraySubscript.hpp"
#include "JsonObject.hpp"
namespace ArduinoJson {
inline JsonVariant::JsonVariant(const JsonArray &array) {
if (array.success()) {
_type = Internals::JSON_ARRAY;
_content.asArray = const_cast<JsonArray *>(&array);
} else {
_type = Internals::JSON_UNDEFINED;
}
}
inline JsonVariant::JsonVariant(const JsonObject &object) {
if (object.success()) {
_type = Internals::JSON_OBJECT;
_content.asObject = const_cast<JsonObject *>(&object);
} else {
_type = Internals::JSON_UNDEFINED;
}
}
namespace Internals {
template <>
struct JsonVariantDefault<JsonArray> {
static JsonArray &get() {
return JsonArray::invalid();
}
};
}
inline JsonArray &JsonVariant::asArray() const {
if (_type == Internals::JSON_ARRAY) return *_content.asArray;
return JsonArray::invalid();
}
inline JsonArray &JsonArray::createNestedArray() {
if (!_buffer) return JsonArray::invalid();
JsonArray &array = _buffer->createArray();
add(array);
return array;
}
template <typename TString>
inline JsonArray &JsonObject::createNestedArray(const TString &key) {
if (!_buffer) return JsonArray::invalid();
JsonArray &array = _buffer->createArray();
set(key, array);
return array;
}
}

View File

@ -0,0 +1,80 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#include "JsonVariantBase.hpp"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4522)
#endif
namespace ArduinoJson {
class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
public:
FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index)
: _array(array), _index(index) {}
FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& src) {
_array.set(_index, src);
return *this;
}
template <typename T>
FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
_array.set(_index, src);
return *this;
}
FORCE_INLINE bool success() const {
return _index < _array.size();
}
template <typename T>
FORCE_INLINE typename Internals::JsonVariantAs<T>::type as() const {
return _array.get<T>(_index);
}
template <typename T>
FORCE_INLINE bool is() const {
return _array.is<T>(_index);
}
template <typename TValue>
FORCE_INLINE void set(const TValue& value) {
_array.set(_index, value);
}
private:
JsonArray& _array;
const size_t _index;
};
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream& operator<<(std::ostream& os,
const JsonArraySubscript& source) {
return source.printTo(os);
}
#endif
inline JsonArraySubscript JsonArray::operator[](size_t index) {
return JsonArraySubscript(*this, index);
}
template <typename TImplem>
inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[](
int index) const {
return asArray()[index];
}
} // namespace ArduinoJson
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View File

@ -1,13 +1,27 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include <stddef.h> // for size_t
#include <stdint.h> // for uint8_t
#include <string.h>
#include "JsonVariant.hpp"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
class JsonArray;
@ -43,11 +57,19 @@ class JsonBuffer {
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
// The second argument set the nesting limit
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
JsonArray &parseArray(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
JsonArray &parseArray(
char *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT);
// With this overload, the JsonBuffer will make a copy of the string
template <typename TString>
JsonArray &parseArray(const TString &json,
uint8_t nesting = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return parseArray(strdup(json), nesting);
}
// Allocates and populate a JsonObject from a JSON string.
//
@ -55,27 +77,59 @@ class JsonBuffer {
// writable
// because the parser will insert null-terminators and replace escaped chars.
//
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
// The second argument set the nesting limit
//
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
// allocation fails.
JsonObject &parseObject(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
JsonObject &parseObject(
char *json, uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT);
// With this overload, the JsonBuffer will make a copy of the string
template <typename TString>
JsonObject &parseObject(const TString &json,
uint8_t nesting = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return parseObject(strdup(json), nesting);
}
// Generalized version of parseArray() and parseObject(), also works for
// integral types.
JsonVariant parse(char *json,
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT);
// With this overload, the JsonBuffer will make a copy of the string
template <typename TString>
JsonVariant parse(const TString &json,
uint8_t nesting = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
return parse(strdup(json), nesting);
}
// Duplicate a string
template <typename TString>
char *strdup(const TString &src) {
return Internals::StringFuncs<TString>::duplicate(src, this);
}
// Allocates n bytes in the JsonBuffer.
// Return a pointer to the allocated memory or NULL if allocation fails.
virtual void *alloc(size_t size) = 0;
// Default value of nesting limit of parseArray() and parseObject().
//
// The nesting limit is a contain on the level of nesting allowed in the JSON
// string.
// If set to 0, only a flat array or objects can be parsed.
// If set to 1, the object can contain nested arrays or objects but only 1
// level deep.
// And bigger values will allow more level of nesting.
//
// The purpose of this feature is to prevent stack overflow that could lead to
// a security risk.
static const uint8_t DEFAULT_LIMIT = 10;
protected:
// Preserve aligment if nessary
static FORCE_INLINE size_t round_size_up(size_t bytes) {
#if ARDUINOJSON_ENABLE_ALIGNMENT
const size_t x = sizeof(void *) - 1;
return (bytes + x) & ~x;
#else
return bytes;
#endif
}
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -0,0 +1,38 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/JsonParser.hpp"
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::createArray() {
JsonArray *ptr = new (this) JsonArray(this);
return ptr ? *ptr : JsonArray::invalid();
}
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::createObject() {
JsonObject *ptr = new (this) JsonObject(this);
return ptr ? *ptr : JsonObject::invalid();
}
inline ArduinoJson::JsonArray &ArduinoJson::JsonBuffer::parseArray(
char *json, uint8_t nestingLimit) {
Internals::JsonParser parser(this, json, nestingLimit);
return parser.parseArray();
}
inline ArduinoJson::JsonObject &ArduinoJson::JsonBuffer::parseObject(
char *json, uint8_t nestingLimit) {
Internals::JsonParser parser(this, json, nestingLimit);
return parser.parseObject();
}
inline ArduinoJson::JsonVariant ArduinoJson::JsonBuffer::parse(
char *json, uint8_t nestingLimit) {
Internals::JsonParser parser(this, json, nestingLimit);
return parser.parseVariant();
}

View File

@ -1,15 +1,23 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/JsonBufferAllocated.hpp"
#include "Internals/JsonPrintable.hpp"
#include "Internals/List.hpp"
#include "Internals/ReferenceType.hpp"
#include "Internals/StringFuncs.hpp"
#include "Internals/ValueSetter.hpp"
#include "JsonPair.hpp"
#include "TypeTraits/ConstRefOrConstPtr.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsSame.hpp"
// Returns the size (in bytes) of an object with n elements.
// Can be very handy to determine the size of a StaticJsonBuffer.
@ -30,76 +38,131 @@ class JsonBuffer;
// It can also be deserialized from a JSON string via JsonBuffer::parseObject().
class JsonObject : public Internals::JsonPrintable<JsonObject>,
public Internals::ReferenceType,
public Internals::List<JsonPair> {
// JsonBuffer is a friend because it needs to call the private constructor.
friend class JsonBuffer;
public Internals::List<JsonPair>,
public Internals::JsonBufferAllocated {
public:
typedef const char *key_type;
typedef JsonPair value_type;
// Create an empty JsonArray attached to the specified JsonBuffer.
// You should not use this constructor directly.
// Instead, use JsonBuffer::createObject() or JsonBuffer.parseObject().
explicit JsonObject(JsonBuffer* buffer) : Internals::List<JsonPair>(buffer) {}
// Gets the JsonVariant associated with the specified key.
// Returns a reference or JsonVariant::invalid() if not found.
JsonVariant &at(key_type key);
// Gets or sets the value associated with the specified key.
template <typename TString>
JsonObjectSubscript<TString> operator[](const TString& key);
// Gets the JsonVariant associated with the specified key.
// Returns a constant reference or JsonVariant::invalid() if not found.
const JsonVariant &at(key_type key) const;
// Gets or create the JsonVariant associated with the specified key.
// Returns a reference or JsonVariant::invalid() if allocation failed.
JsonVariant &operator[](key_type key);
// Gets the JsonVariant associated with the specified key.
// Returns a constant reference or JsonVariant::invalid() if not found.
const JsonVariant &operator[](key_type key) const { return at(key); }
// Adds an uninitialized JsonVariant associated with the specified key.
// Return a reference or JsonVariant::invalid() if allocation fails.
JsonVariant &add(key_type key) { return (*this)[key]; }
// Adds the specified key with the specified value.
template <typename T>
void add(key_type key, T value) {
add(key).set(value);
// Gets the value associated with the specified key.
template <typename TString>
JsonVariant operator[](const TString& key) const {
return get<JsonVariant>(key);
}
// Adds the specified key with a reference to the specified JsonArray.
void add(key_type key, JsonArray &array) { add(key).set(array); }
// Sets the specified key with the specified value.
// bool set(TKey key, bool value);
// bool set(TKey key, char value);
// bool set(TKey key, long value);
// bool set(TKey key, int value);
// bool set(TKey key, short value);
// bool set(TKey key, float value);
// bool set(TKey key, double value);
// bool set(TKey key, const char* value);
// bool set(TKey key, RawJson value);
// bool set(Key, String&);
// bool set(Key, JsonArray&);
// bool set(Key, JsonObject&);
// bool set(Key, JsonVariant&);
template <typename TValue, typename TString>
bool set(const TString& key, const TValue& value) {
// reduce the number of template function instanciation to reduce code size
return setNodeAt<typename TypeTraits::ConstRefOrConstPtr<TString>::type,
typename TypeTraits::ConstRefOrConstPtr<TValue>::type>(
key, value);
}
// bool set(Key, float value, uint8_t decimals);
// bool set(Key, double value, uint8_t decimals);
template <typename TValue, typename TString>
typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value,
bool>::type
set(const TString& key, TValue value, uint8_t decimals) {
return set(key, JsonVariant(value, decimals));
}
// Adds the specified key with a reference to the specified JsonObject.
void add(key_type key, JsonObject &object) { add(key).set(object); }
// Gets the value associated with the specified key.
template <typename TValue, typename TString>
typename Internals::JsonVariantAs<TValue>::type get(
const TString& key) const {
node_type* node = getNodeAt(key);
return node ? node->content.value.as<TValue>()
: Internals::JsonVariantDefault<TValue>::get();
}
// Checks the type of the value associated with the specified key.
template <typename TValue, typename TString>
bool is(const TString& key) const {
node_type* node = getNodeAt(key);
return node ? node->content.value.is<TValue>() : false;
}
// Creates and adds a JsonArray.
// This is a shortcut for JsonBuffer::createArray() and JsonObject::add().
JsonArray &createNestedArray(key_type key);
template <typename TString>
JsonArray& createNestedArray(const TString& key);
// Creates and adds a JsonObject.
// This is a shortcut for JsonBuffer::createObject() and JsonObject::add().
JsonObject &createNestedObject(key_type key);
template <typename TString>
JsonObject& createNestedObject(const TString& key);
// Tells weither the specified key is present and associated with a value.
bool containsKey(key_type key) const { return at(key).success(); }
template <typename TString>
bool containsKey(const TString& key) const {
return getNodeAt(key) != NULL;
}
// Removes the specified key and the associated value.
void remove(key_type key);
template <typename TString>
void remove(const TString& key) {
removeNode(getNodeAt(key));
}
// Returns a reference an invalid JsonObject.
// This object is meant to replace a NULL pointer.
// This is used when memory allocation or JSON parsing fail.
static JsonObject &invalid() { return _invalid; }
// Serialize the object to the specified JsonWriter
void writeTo(Internals::JsonWriter &writer) const;
static JsonObject& invalid() {
static JsonObject instance(NULL);
return instance;
}
private:
// Create an empty JsonArray attached to the specified JsonBuffer.
explicit JsonObject(JsonBuffer *buffer) : Internals::List<JsonPair>(buffer) {}
// Returns the list node that matches the specified key.
node_type *getNodeAt(key_type key) const;
template <typename TString>
node_type* getNodeAt(const TString& key) const {
// reduce the number of template function instanciation to reduce code size
return getNodeAtImpl<
typename TypeTraits::ConstRefOrConstPtr<TString>::type>(key);
}
// The instance returned by JsonObject::invalid()
static JsonObject _invalid;
template <typename TStringRef>
node_type* getNodeAtImpl(TStringRef key) const {
for (node_type* node = _firstNode; node; node = node->next) {
if (Internals::StringFuncs<TStringRef>::equals(key, node->content.key))
return node;
}
return NULL;
}
template <typename TStringRef, typename TValueRef>
bool setNodeAt(TStringRef key, TValueRef value) {
node_type* node = getNodeAtImpl<TStringRef>(key);
if (!node) {
node = addNewNode();
if (!node) return false;
bool key_ok = Internals::ValueSetter<TStringRef>::set(
_buffer, node->content.key, key);
if (!key_ok) return false;
}
return Internals::ValueSetter<TValueRef>::set(_buffer, node->content.value,
value);
}
};
}

View File

@ -0,0 +1,44 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonArray.hpp"
#include "JsonObject.hpp"
#include "JsonObjectSubscript.hpp"
namespace ArduinoJson {
namespace Internals {
template <>
struct JsonVariantDefault<JsonObject> {
static JsonObject &get() {
return JsonObject::invalid();
}
};
}
inline JsonObject &JsonVariant::asObject() const {
if (_type == Internals::JSON_OBJECT) return *_content.asObject;
return JsonObject::invalid();
}
template <typename TString>
inline JsonObject &JsonObject::createNestedObject(const TString &key) {
if (!_buffer) return JsonObject::invalid();
JsonObject &object = _buffer->createObject();
set(key, object);
return object;
}
inline JsonObject &JsonArray::createNestedObject() {
if (!_buffer) return JsonObject::invalid();
JsonObject &object = _buffer->createObject();
add(object);
return object;
}
}

View File

@ -0,0 +1,91 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#include "JsonVariantBase.hpp"
#include "TypeTraits/ConstRefOrConstPtr.hpp"
#include "TypeTraits/EnableIf.hpp"
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4522)
#endif
namespace ArduinoJson {
template <typename TString>
class JsonObjectSubscript
: public JsonVariantBase<JsonObjectSubscript<TString> > {
// const String&
// const std::string&
// const char*
typedef typename TypeTraits::ConstRefOrConstPtr<TString>::type TStringRef;
public:
FORCE_INLINE JsonObjectSubscript(JsonObject& object, TStringRef key)
: _object(object), _key(key) {}
FORCE_INLINE JsonObjectSubscript<TString>& operator=(
const JsonObjectSubscript<TString>& src) {
_object.set(_key, src);
return *this;
}
template <typename T>
FORCE_INLINE JsonObjectSubscript<TString>& operator=(const T& src) {
_object.set(_key, src);
return *this;
}
FORCE_INLINE bool success() const {
return _object.containsKey(_key);
}
template <typename TValue>
FORCE_INLINE typename Internals::JsonVariantAs<TValue>::type as() const {
return _object.get<TValue, TStringRef>(_key);
}
template <typename TValue>
FORCE_INLINE bool is() const {
return _object.is<TValue>(_key);
}
template <typename TValue>
FORCE_INLINE bool set(const TValue& value) {
return _object.set(_key, value);
}
template <typename TValue>
FORCE_INLINE bool set(const TValue& value, uint8_t decimals) {
return _object.set(_key, value, decimals);
}
private:
JsonObject& _object;
TStringRef _key;
};
#if ARDUINOJSON_ENABLE_STD_STREAM
template <typename TString>
inline std::ostream& operator<<(std::ostream& os,
const JsonObjectSubscript<TString>& source) {
return source.printTo(os);
}
#endif
template <typename TString>
inline JsonObjectSubscript<TString> JsonObject::operator[](const TString& key) {
return JsonObjectSubscript<TString>(*this, key);
}
} // namespace ArduinoJson
#ifdef _MSC_VER
#pragma warning(pop)
#endif

View File

@ -1,8 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once

View File

@ -1,8 +1,9 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
@ -11,7 +12,18 @@
#include "Internals/JsonPrintable.hpp"
#include "Internals/JsonVariantContent.hpp"
#include "Internals/JsonVariantDefault.hpp"
#include "Internals/JsonVariantType.hpp"
#include "JsonVariantBase.hpp"
#include "RawJson.hpp"
#include "TypeTraits/EnableIf.hpp"
#include "TypeTraits/IsFloatingPoint.hpp"
#include "TypeTraits/IsIntegral.hpp"
#include "TypeTraits/IsSame.hpp"
#include "TypeTraits/IsSignedIntegral.hpp"
#include "TypeTraits/IsUnsignedIntegral.hpp"
#include "TypeTraits/RemoveConst.hpp"
#include "TypeTraits/RemoveReference.hpp"
namespace ArduinoJson {
@ -26,152 +38,304 @@ class JsonObject;
// - a char, short, int or a long (signed or unsigned)
// - a string (const char*)
// - a reference to a JsonArray or JsonObject
class JsonVariant : public Internals::JsonPrintable<JsonVariant> {
class JsonVariant : public JsonVariantBase<JsonVariant> {
friend void Internals::JsonSerializer::serialize(const JsonVariant &,
JsonWriter &);
public:
// Creates an uninitialized JsonVariant
JsonVariant() : _type(Internals::JSON_UNDEFINED) {}
// Initializes a JsonVariant with the specified value.
template <typename T>
explicit JsonVariant(T value) {
set(value);
}
// Tells weither the variant is valid.
bool success() const {
return _type != Internals::JSON_INVALID &&
_type != Internals::JSON_UNDEFINED;
}
// Sets the variant to a boolean value.
// Create a JsonVariant containing a boolean value.
// It will be serialized as "true" or "false" in JSON.
void set(bool value);
JsonVariant(bool value) {
using namespace Internals;
_type = JSON_BOOLEAN;
_content.asInteger = static_cast<JsonInteger>(value);
}
// Sets the variant to a floating point value.
// Create a JsonVariant containing a floating point value.
// The second argument specifies the number of decimal digits to write in
// the JSON string.
void set(double value, uint8_t decimals = 2);
// Sets the variant to be an integer value.
void set(signed long value);
void set(signed char value) { set(static_cast<long>(value)); }
void set(signed int value) { set(static_cast<long>(value)); }
void set(signed short value) { set(static_cast<long>(value)); }
void set(unsigned char value) { set(static_cast<long>(value)); }
void set(unsigned int value) { set(static_cast<long>(value)); }
void set(unsigned long value) { set(static_cast<long>(value)); }
void set(unsigned short value) { set(static_cast<long>(value)); }
// Sets the variant to be a string.
void set(const char *value);
// Sets the variant to be a reference to an array.
void set(JsonArray &array);
// Sets the variant to be a reference to an object.
void set(JsonObject &object);
// Sets the variant to the specified value.
// JsonVariant(double value, uint8_t decimals);
// JsonVariant(float value, uint8_t decimals);
template <typename T>
JsonVariant &operator=(T value) {
set(value);
return *this;
JsonVariant(T value, uint8_t decimals = 2,
typename TypeTraits::EnableIf<
TypeTraits::IsFloatingPoint<T>::value>::type * = 0) {
using namespace Internals;
_type = static_cast<JsonVariantType>(JSON_FLOAT_0_DECIMALS + decimals);
_content.asFloat = static_cast<JsonFloat>(value);
}
// Sets the variant to be a reference to an array.
JsonVariant &operator=(JsonArray &array) {
set(array);
return *this;
// Create a JsonVariant containing an integer value.
// JsonVariant(signed short)
// JsonVariant(signed int)
// JsonVariant(signed long)
template <typename T>
JsonVariant(T value,
typename TypeTraits::EnableIf<
TypeTraits::IsSignedIntegral<T>::value>::type * = 0) {
using namespace Internals;
if (value >= 0) {
_type = JSON_POSITIVE_INTEGER;
_content.asInteger = static_cast<JsonUInt>(value);
} else {
_type = JSON_NEGATIVE_INTEGER;
_content.asInteger = static_cast<JsonUInt>(-value);
}
}
// JsonVariant(unsigned short)
// JsonVariant(unsigned int)
// JsonVariant(unsigned long)
template <typename T>
JsonVariant(T value,
typename TypeTraits::EnableIf<
TypeTraits::IsUnsignedIntegral<T>::value>::type * = 0) {
using namespace Internals;
_type = JSON_POSITIVE_INTEGER;
_content.asInteger = static_cast<JsonUInt>(value);
}
// Sets the variant to be a reference to an object.
JsonVariant &operator=(JsonObject &object) {
set(object);
return *this;
// Create a JsonVariant containing a string.
JsonVariant(const char *value) {
_type = Internals::JSON_STRING;
_content.asString = value;
}
// Gets the variant as a boolean value.
// Returns false if the variant is not a boolean value.
operator bool() const;
// Create a JsonVariant containing an unparsed string
JsonVariant(RawJson value) {
_type = Internals::JSON_UNPARSED;
_content.asString = value;
}
// Gets the variant as a floating-point value.
// Returns 0.0 if the variant is not a floating-point value
operator double() const;
operator float() const { return static_cast<float>(as<double>()); }
// Create a JsonVariant containing a reference to an array.
// CAUTION: we are lying about constness, because the array can be modified if
// the variant is converted back to a JsonArray&
JsonVariant(const JsonArray &array);
// Gets the variant as an integer value.
// Returns 0 if the variant is not an integer value.
operator signed long() const;
operator signed char() const { return cast_long_to<signed char>(); }
operator signed int() const { return cast_long_to<signed int>(); }
operator signed short() const { return cast_long_to<signed short>(); }
operator unsigned char() const { return cast_long_to<unsigned char>(); }
operator unsigned int() const { return cast_long_to<unsigned int>(); }
operator unsigned long() const { return cast_long_to<unsigned long>(); }
operator unsigned short() const { return cast_long_to<unsigned short>(); }
// Gets the variant as a string.
// Returns NULL if variant is not a string.
operator const char *() const;
const char *asString() const { return as<const char *>(); }
// Gets the variant as an array.
// Returns a reference to the JsonArray or JsonArray::invalid() if the variant
// is not an array.
operator JsonArray &() const;
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.
operator JsonObject &() const;
JsonObject &asObject() const { return as<JsonObject &>(); }
// Create a JsonVariant containing a reference to an object.
// CAUTION: we are lying about constness, because the object can be modified
// if the variant is converted back to a JsonObject&
JsonVariant(const JsonObject &object);
// Get the variant as the specified type.
// See cast operators for details.
//
// short as<signed short>() const;
// int as<signed int>() const;
// long as<signed long>() const;
template <typename T>
T as() const {
return static_cast<T>(*this);
const typename TypeTraits::EnableIf<TypeTraits::IsSignedIntegral<T>::value,
T>::type
as() const {
return static_cast<T>(asInteger());
}
//
// short as<unsigned short>() const;
// int as<unsigned int>() const;
// long as<unsigned long>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsUnsignedIntegral<T>::value,
T>::type
as() const {
return static_cast<T>(asUnsignedInteger());
}
//
// double as<double>() const;
// float as<float>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
T>::type
as() const {
return static_cast<T>(asFloat());
}
//
// const char* as<const char*>() const;
// const char* as<char*>() const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
TypeTraits::IsSame<T, char *>::value,
const char *>::type
as() const {
return asString();
}
//
// std::string as<std::string>() const;
// String as<String>() const;
template <typename T>
typename TypeTraits::EnableIf<Internals::StringFuncs<T>::has_append, T>::type
as() const {
const char *cstr = asString();
if (cstr) return T(cstr);
T s;
printTo(s);
return s;
}
//
// const bool as<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
T>::type
as() const {
return asInteger() != 0;
}
//
// JsonArray& as<JsonArray> const;
// JsonArray& as<JsonArray&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
JsonArray>::value,
JsonArray &>::type
as() const {
return asArray();
}
//
// const JsonArray& as<const JsonArray&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
const JsonArray>::value,
const JsonArray &>::type
as() const {
return asArray();
}
//
// JsonObject& as<JsonObject> const;
// JsonObject& as<JsonObject&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
JsonObject>::value,
JsonObject &>::type
as() const {
return asObject();
}
//
// JsonObject& as<const JsonObject> const;
// JsonObject& as<const JsonObject&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<typename TypeTraits::RemoveReference<T>::type,
const JsonObject>::value,
const JsonObject &>::type
as() const {
return asObject();
}
//
// JsonVariant as<JsonVariant> const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, JsonVariant>::value,
T>::type
as() const {
return *this;
}
// Tells weither the variant has the specified type.
// Returns true if the variant has type type T, false otherwise.
//
// short as<short>() const;
// int as<int>() const;
// long as<long>() const;
template <typename T>
bool is() const {
return false;
const typename TypeTraits::EnableIf<TypeTraits::IsIntegral<T>::value &&
!TypeTraits::IsSame<T, bool>::value,
bool>::type
is() const {
return isInteger();
}
//
// double is<double>() const;
// float is<float>() const;
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<T>::value,
bool>::type
is() const {
return isFloat();
}
//
// const bool is<bool>() const
template <typename T>
const typename TypeTraits::EnableIf<TypeTraits::IsSame<T, bool>::value,
bool>::type
is() const {
return isBoolean();
}
//
// bool is<const char*>() const;
// bool is<char*>() const;
template <typename T>
typename TypeTraits::EnableIf<TypeTraits::IsSame<T, const char *>::value ||
TypeTraits::IsSame<T, char *>::value,
bool>::type
is() const {
return isString();
}
//
// bool is<JsonArray> const;
// bool is<JsonArray&> const;
// bool is<const JsonArray&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<
typename TypeTraits::RemoveConst<
typename TypeTraits::RemoveReference<T>::type>::type,
JsonArray>::value,
bool>::type
is() const {
return isArray();
}
//
// bool is<JsonObject> const;
// bool is<JsonObject&> const;
// bool is<const JsonObject&> const;
template <typename T>
typename TypeTraits::EnableIf<
TypeTraits::IsSame<
typename TypeTraits::RemoveConst<
typename TypeTraits::RemoveReference<T>::type>::type,
JsonObject>::value,
bool>::type
is() const {
return isObject();
}
// Returns an invalid variant.
// This is meant to replace a NULL pointer.
static JsonVariant &invalid() { return _invalid; }
// Returns true if the variant has a value
bool success() const {
return _type != Internals::JSON_UNDEFINED;
}
// Serialize the variant to a JsonWriter
void writeTo(Internals::JsonWriter &writer) const;
// DEPRECATED: use as<char*>() instead
const char *asString() const;
// 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;
// DEPRECATED: use as<JsonArray>() instead
JsonArray &asArray() const;
// Mimics an array.
// Returns the element at specified index if the variant is an array.
// Returns JsonVariant::invalid() if the variant is not an array.
JsonVariant &operator[](int index);
// Mimics an object.
// Returns the value associated with the specified key if the variant is an
// object.
// Return JsonVariant::invalid() if the variant is not an object.
JsonVariant &operator[](const char *key);
// DEPRECATED: use as<JsonObject>() instead
JsonObject &asObject() const;
private:
// Special constructor used only to create _invalid.
explicit JsonVariant(Internals::JsonVariantType type) : _type(type) {}
// Helper for interger cast operators
// It's not allowed to store a char
template <typename T>
T cast_long_to() const {
return static_cast<T>(as<long>());
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 {
return _type == Internals::JSON_ARRAY;
}
bool isObject() const {
return _type == Internals::JSON_OBJECT;
}
bool isString() const {
return _type == Internals::JSON_STRING ||
(_type == Internals::JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString));
}
// The current type of the variant
@ -179,108 +343,13 @@ class JsonVariant : public Internals::JsonPrintable<JsonVariant> {
// The various alternatives for the value of the variant.
Internals::JsonVariantContent _content;
// The instance returned by JsonVariant::invalid()
static JsonVariant _invalid;
};
template <>
inline bool JsonVariant::is<long>() const {
return _type == Internals::JSON_LONG;
inline JsonVariant float_with_n_digits(float value, uint8_t digits) {
return JsonVariant(value, digits);
}
template <>
inline bool JsonVariant::is<double>() const {
return _type >= Internals::JSON_DOUBLE_0_DECIMALS;
}
template <>
inline bool JsonVariant::is<bool>() const {
return _type == Internals::JSON_BOOLEAN;
}
template <>
inline bool JsonVariant::is<const char *>() const {
return _type == Internals::JSON_STRING;
}
template <>
inline bool JsonVariant::is<JsonArray &>() const {
return _type == Internals::JSON_ARRAY;
}
template <>
inline bool JsonVariant::is<const JsonArray &>() const {
return _type == Internals::JSON_ARRAY;
}
template <>
inline bool JsonVariant::is<JsonObject &>() const {
return _type == Internals::JSON_OBJECT;
}
template <>
inline bool JsonVariant::is<const JsonObject &>() const {
return _type == Internals::JSON_OBJECT;
}
template <typename T>
inline bool operator==(const JsonVariant &left, T right) {
return left.as<T>() == right;
}
template <typename T>
inline bool operator==(T left, const JsonVariant &right) {
return left == right.as<T>();
}
template <typename T>
inline bool operator!=(const JsonVariant &left, T right) {
return left.as<T>() != right;
}
template <typename T>
inline bool operator!=(T left, const JsonVariant &right) {
return left != right.as<T>();
}
template <typename T>
inline bool operator<=(const JsonVariant &left, T right) {
return left.as<T>() <= right;
}
template <typename T>
inline bool operator<=(T left, const JsonVariant &right) {
return left <= right.as<T>();
}
template <typename T>
inline bool operator>=(const JsonVariant &left, T right) {
return left.as<T>() >= right;
}
template <typename T>
inline bool operator>=(T left, const JsonVariant &right) {
return left >= right.as<T>();
}
template <typename T>
inline bool operator<(const JsonVariant &left, T right) {
return left.as<T>() < right;
}
template <typename T>
inline bool operator<(T left, const JsonVariant &right) {
return left < right.as<T>();
}
template <typename T>
inline bool operator>(const JsonVariant &left, T right) {
return left.as<T>() > right;
}
template <typename T>
inline bool operator>(T left, const JsonVariant &right) {
return left > right.as<T>();
inline JsonVariant double_with_n_digits(double value, uint8_t digits) {
return JsonVariant(value, digits);
}
}

View File

@ -0,0 +1,131 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Configuration.hpp"
#include "Internals/Parse.hpp"
#include "JsonArray.hpp"
#include "JsonObject.hpp"
#include "JsonVariant.hpp"
#include <errno.h> // for errno
#include <stdlib.h> // for strtol, strtod
#include <string.h> // for strcmp
namespace ArduinoJson {
inline Internals::JsonInteger JsonVariant::asInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return _content.asInteger;
case JSON_NEGATIVE_INTEGER:
return -static_cast<Internals::JsonInteger>(_content.asInteger);
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonInteger>(_content.asString);
default:
return static_cast<Internals::JsonInteger>(_content.asFloat);
}
}
inline Internals::JsonUInt JsonVariant::asUnsignedInteger() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
case JSON_NEGATIVE_INTEGER:
return _content.asInteger;
case JSON_STRING:
case JSON_UNPARSED:
if (!_content.asString) return 0;
if (!strcmp("true", _content.asString)) return 1;
return parse<Internals::JsonUInt>(_content.asString);
default:
return static_cast<Internals::JsonUInt>(_content.asFloat);
}
}
inline const char *JsonVariant::asString() const {
using namespace Internals;
if (_type == JSON_UNPARSED && _content.asString &&
!strcmp("null", _content.asString))
return NULL;
if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString;
return NULL;
}
inline Internals::JsonFloat JsonVariant::asFloat() const {
using namespace Internals;
switch (_type) {
case JSON_UNDEFINED:
return 0;
case JSON_POSITIVE_INTEGER:
case JSON_BOOLEAN:
return static_cast<JsonFloat>(_content.asInteger);
case JSON_NEGATIVE_INTEGER:
return -static_cast<JsonFloat>(_content.asInteger);
case JSON_STRING:
case JSON_UNPARSED:
return _content.asString ? parse<JsonFloat>(_content.asString) : 0;
default:
return _content.asFloat;
}
}
inline bool JsonVariant::isBoolean() const {
using namespace Internals;
if (_type == JSON_BOOLEAN) return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
return !strcmp(_content.asString, "true") ||
!strcmp(_content.asString, "false");
}
inline bool JsonVariant::isInteger() const {
using namespace Internals;
if (_type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER)
return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtol(_content.asString, &end, 10);
return *end == '\0' && errno == 0;
}
inline bool JsonVariant::isFloat() const {
using namespace Internals;
if (_type >= JSON_FLOAT_0_DECIMALS) return true;
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
char *end;
errno = 0;
strtod(_content.asString, &end);
return *end == '\0' && errno == 0 && !is<long>();
}
#if ARDUINOJSON_ENABLE_STD_STREAM
inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) {
return source.printTo(os);
}
#endif
} // namespace ArduinoJson

View File

@ -0,0 +1,152 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "Internals/JsonVariantAs.hpp"
#include "Polyfills/attributes.hpp"
namespace ArduinoJson {
// Forward declarations.
class JsonArraySubscript;
template <typename TKey>
class JsonObjectSubscript;
template <typename TImpl>
class JsonVariantBase : public Internals::JsonPrintable<TImpl> {
public:
// DEPRECATED: use as<char*>() instead
FORCE_INLINE const char *asString() const {
return as<const char *>();
}
// Gets the variant as an array.
// Returns a reference to the JsonArray or JsonArray::invalid() if the
// variant
// is not an array.
FORCE_INLINE operator JsonArray &() const {
return as<JsonArray &>();
}
// DEPRECATED: use as<JsonArray>() instead
FORCE_INLINE JsonArray &asArray() const {
return as<JsonArray &>();
}
// Gets the variant as an object.
// Returns a reference to the JsonObject or JsonObject::invalid() if the
// variant is not an object.
FORCE_INLINE operator JsonObject &() const {
return as<JsonObject &>();
}
// DEPRECATED: use as<JsonObject>() instead
FORCE_INLINE JsonObject &asObject() const {
return as<JsonObject &>();
}
template <typename T>
FORCE_INLINE operator T() const {
return as<T>();
}
template <typename T>
FORCE_INLINE const typename Internals::JsonVariantAs<T>::type as() const {
return impl()->template as<T>();
}
// Mimics an array or an object.
// Returns the size of the array or object if the variant has that type.
// Returns 0 if the variant is neither an array nor an object
size_t size() const {
return asArray().size() + asObject().size();
}
// Mimics an array.
// Returns the element at specified index if the variant is an array.
// Returns JsonVariant::invalid() if the variant is not an array.
FORCE_INLINE const JsonArraySubscript operator[](int index) const;
// Mimics an object.
// Returns the value associated with the specified key if the variant is
// an object.
// Return JsonVariant::invalid() if the variant is not an object.
template <typename TString>
FORCE_INLINE
typename TypeTraits::EnableIf<Internals::StringFuncs<TString>::has_equals,
const JsonObjectSubscript<TString> >::type
operator[](const TString &key) const {
return asObject()[key];
}
private:
const TImpl *impl() const {
return static_cast<const TImpl *>(this);
}
};
template <typename TImpl, typename TComparand>
inline bool operator==(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() == right;
}
template <typename TImpl, typename TComparand>
inline bool operator==(TComparand left, const JsonVariantBase<TImpl> &right) {
return left == right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator!=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() != right;
}
template <typename TImpl, typename TComparand>
inline bool operator!=(TComparand left, const JsonVariantBase<TImpl> &right) {
return left != right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator<=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() <= right;
}
template <typename TImpl, typename TComparand>
inline bool operator<=(TComparand left, const JsonVariantBase<TImpl> &right) {
return left <= right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>=(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() >= right;
}
template <typename TImpl, typename TComparand>
inline bool operator>=(TComparand left, const JsonVariantBase<TImpl> &right) {
return left >= right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator<(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() < right;
}
template <typename TImpl, typename TComparand>
inline bool operator<(TComparand left, const JsonVariantBase<TImpl> &right) {
return left < right.template as<TComparand>();
}
template <typename TImpl, typename TComparand>
inline bool operator>(const JsonVariantBase<TImpl> &left, TComparand right) {
return left.template as<TComparand>() > right;
}
template <typename TImpl, typename TComparand>
inline bool operator>(TComparand left, const JsonVariantBase<TImpl> &right) {
return left > right.template as<TComparand>();
}
}

View File

@ -0,0 +1,16 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#ifdef _MSC_VER
#define FORCE_INLINE __forceinline
#define NO_INLINE __declspec(noinline)
#else
#define FORCE_INLINE __attribute__((always_inline))
#define NO_INLINE __attribute__((noinline))
#endif

View File

@ -0,0 +1,111 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
// If Visual Studo <= 2012
#if defined(_MSC_VER) && _MSC_VER <= 1700
#include <float.h>
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
bool isNaN(T x) {
return _isnan(x) != 0;
}
template <typename T>
bool isInfinity(T x) {
return !_finite(x);
}
}
}
#else
#include <math.h>
// GCC warning: "conversion to 'float' from 'double' may alter its value"
#ifdef __GNUC__
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
#pragma GCC diagnostic ignored "-Wfloat-conversion"
#else
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#endif
// Workaround for libs that #undef isnan or isinf
// https://github.com/bblanchon/ArduinoJson/issues/284
#if !defined(isnan) || !defined(isinf)
namespace std {}
#endif
namespace ArduinoJson {
namespace Polyfills {
template <typename T>
bool isNaN(T x) {
// Workaround for libs that #undef isnan
// https://github.com/bblanchon/ArduinoJson/issues/284
#ifndef isnan
using namespace std;
#endif
return isnan(x);
}
#if defined(_GLIBCXX_HAVE_ISNANL) && _GLIBCXX_HAVE_ISNANL
template <>
inline bool isNaN<double>(double x) {
return isnanl(x);
}
#endif
#if defined(_GLIBCXX_HAVE_ISNANF) && _GLIBCXX_HAVE_ISNANF
template <>
inline bool isNaN<float>(float x) {
return isnanf(x);
}
#endif
template <typename T>
bool isInfinity(T x) {
// Workaround for libs that #undef isinf
// https://github.com/bblanchon/ArduinoJson/issues/284
#ifndef isinf
using namespace std;
#endif
return isinf(x);
}
#if defined(_GLIBCXX_HAVE_ISINFL) && _GLIBCXX_HAVE_ISINFL
template <>
inline bool isInfinity<double>(double x) {
return isinfl(x);
}
#endif
#if defined(_GLIBCXX_HAVE_ISINFF) && _GLIBCXX_HAVE_ISINFF
template <>
inline bool isInfinity<float>(float x) {
return isinff(x);
}
#endif
#if defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif
}
}
#endif

View File

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

View File

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

View File

@ -0,0 +1,23 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
// A special type of data that can be used to insert pregenerated JSON portions.
class RawJson {
public:
explicit RawJson(const char* str) : _str(str) {}
operator const char*() const {
return _str;
}
private:
const char* _str;
};
}

View File

@ -1,13 +1,24 @@
// Copyright Benoit Blanchon 2014
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "JsonBuffer.hpp"
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic push
#endif
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
#endif
namespace ArduinoJson {
// Implements a JsonBuffer with fixed memory allocation.
@ -18,14 +29,17 @@ class StaticJsonBuffer : public JsonBuffer {
public:
explicit StaticJsonBuffer() : _size(0) {}
size_t capacity() const { return CAPACITY; }
size_t size() const { return _size; }
size_t capacity() const {
return CAPACITY;
}
size_t size() const {
return _size;
}
protected:
virtual void* alloc(size_t bytes) {
if (_size + bytes > CAPACITY) return NULL;
void* p = &_buffer[_size];
_size += bytes;
_size += round_size_up(bytes);
return p;
}
@ -34,3 +48,11 @@ class StaticJsonBuffer : public JsonBuffer {
size_t _size;
};
}
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)
#pragma GCC diagnostic pop
#endif
#endif

View File

@ -0,0 +1,31 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that return the type T without the const modifier
template <typename T>
struct ConstRefOrConstPtr {
typedef const T& type;
};
template <typename T>
struct ConstRefOrConstPtr<T*> {
typedef const T* type;
};
template <typename T>
struct ConstRefOrConstPtr<T[]> {
typedef const T* type;
};
template <typename T, size_t N>
struct ConstRefOrConstPtr<T[N]> {
typedef const T* type;
};
}
}

View File

@ -0,0 +1,22 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that return the type T if Condition is true.
template <bool Condition, typename T = void>
struct EnableIf {};
template <typename T>
struct EnableIf<true, T> {
typedef T type;
};
}
}

View File

@ -0,0 +1,21 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "IsSame.hpp"
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that returns true if T is a floating point type
template <typename T>
struct IsFloatingPoint {
static const bool value = IsSame<T, float>::value || IsSame<T, double>::value;
};
}
}

View File

@ -0,0 +1,29 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "IsSame.hpp"
#include "IsSignedIntegral.hpp"
#include "IsUnsignedIntegral.hpp"
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that returns true if T is an integral type.
template <typename T>
struct IsIntegral {
static const bool value = TypeTraits::IsSignedIntegral<T>::value ||
TypeTraits::IsUnsignedIntegral<T>::value ||
TypeTraits::IsSame<T, char>::value ||
TypeTraits::IsSame<T, bool>::value;
};
template <typename T>
struct IsIntegral<const T> : IsIntegral<T> {};
}
}

View File

@ -0,0 +1,24 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that returns true if types T and U are the same.
template <typename T, typename U>
struct IsSame {
static const bool value = false;
};
template <typename T>
struct IsSame<T, T> {
static const bool value = true;
};
}
}

View File

@ -0,0 +1,33 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
#include "IsSame.hpp"
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that returns true if T is an integral type.
template <typename T>
struct IsSignedIntegral {
static const bool value = TypeTraits::IsSame<T, signed char>::value ||
TypeTraits::IsSame<T, signed short>::value ||
TypeTraits::IsSame<T, signed int>::value ||
TypeTraits::IsSame<T, signed long>::value ||
#if ARDUINOJSON_USE_LONG_LONG
TypeTraits::IsSame<T, signed long long>::value ||
#endif
#if ARDUINOJSON_USE_INT64
TypeTraits::IsSame<T, signed __int64>::value ||
#endif
false;
};
}
}

View File

@ -0,0 +1,33 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
#include "../Configuration.hpp"
#include "IsSame.hpp"
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that returns true if T is an integral type.
template <typename T>
struct IsUnsignedIntegral {
static const bool value = TypeTraits::IsSame<T, unsigned char>::value ||
TypeTraits::IsSame<T, unsigned short>::value ||
TypeTraits::IsSame<T, unsigned int>::value ||
TypeTraits::IsSame<T, unsigned long>::value ||
#if ARDUINOJSON_USE_LONG_LONG
TypeTraits::IsSame<T, unsigned long long>::value ||
#endif
#if ARDUINOJSON_USE_INT64
TypeTraits::IsSame<T, unsigned __int64>::value ||
#endif
false;
};
}
}

View File

@ -0,0 +1,23 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that return the type T without the const modifier
template <typename T>
struct RemoveConst {
typedef T type;
};
template <typename T>
struct RemoveConst<const T> {
typedef T type;
};
}
}

View File

@ -0,0 +1,23 @@
// Copyright Benoit Blanchon 2014-2016
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// If you like this project, please add a star!
#pragma once
namespace ArduinoJson {
namespace TypeTraits {
// A meta-function that return the type T without the reference modifier.
template <typename T>
struct RemoveReference {
typedef T type;
};
template <typename T>
struct RemoveReference<T&> {
typedef T type;
};
}
}

View File

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

View File

@ -1,17 +1,22 @@
{
"name": "Json",
"name": "ArduinoJson",
"keywords": "json, rest, http, web",
"description": "An elegant and efficient JSON library for embedded systems",
"repository":
{
"repository": {
"type": "git",
"url": "https://github.com/bblanchon/ArduinoJson.git"
},
"authors":
{
"version": "5.7.2",
"authors": {
"name": "Benoit Blanchon",
"url": "http://blog.benoitblanchon.fr"
},
"exclude": [
"scripts",
"src/ArduinoJson.h",
"test",
"third-party"
],
"frameworks": "arduino",
"platforms": "atmelavr"
}
"platforms": "*"
}

View File

@ -1,8 +1,9 @@
name=ArduinoJson
version=4.0
author=Benoit Blanchon <http://blog.benoitblanchon.fr/>
maintainer=Benoit Blanchon <http://blog.benoitblanchon.fr/>
sentence=An efficient and elegant JSON library for Arduino
paragraph=Supports JSON parsing and formatting. Uses fixed memory allocation.
version=5.7.2
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
architectures=*
architectures=*

View File

@ -1,21 +1,20 @@
#!/bin/bash
ZIP="C:\Program Files\7-Zip\7z.exe"
TAG=$(git describe)
OUTPUT="ArduinoJson-$TAG.zip"
cd ../..
# remove existing file
rm -f $OUTPUT
# create zip
"$ZIP" a $OUTPUT \
ArduinoJson/CHANGELOG.md \
ArduinoJson/examples \
ArduinoJson/include \
ArduinoJson/keywords.txt \
ArduinoJson/library.properties \
ArduinoJson/LICENSE.md \
ArduinoJson/README.md \
ArduinoJson/src
#!/bin/bash
TAG=$(git describe)
OUTPUT="ArduinoJson-$TAG.zip"
cd $(dirname $0)/../..
# remove existing file
rm -f $OUTPUT
# create zip
7z a $OUTPUT \
ArduinoJson/CHANGELOG.md \
ArduinoJson/examples \
ArduinoJson/include \
ArduinoJson/keywords.txt \
ArduinoJson/library.properties \
ArduinoJson/LICENSE.md \
ArduinoJson/README.md \
ArduinoJson/ArduinoJson.h

View File

@ -20,10 +20,10 @@ build-env()
if [[ $(uname) == MINGW* ]]
then
build-env "Make" "MinGW Makefiles"
build-env "SublimeText" "Sublime Text 2 - MinGW Makefiles"
build-env "VisualStudio" "Visual Studio 12 2013"
build-env "SublimeText" "Sublime Text 2 - Ninja"
build-env "VisualStudio" "Visual Studio 14 2015"
else
build-env "SublimeText" "Sublime Text 2 - Unix Makefiles"
build-env "SublimeText" "Sublime Text 2 - Ninja"
build-env "Make" "Unix Makefiles"
build-env "Xcode" "Xcode"
fi
fi

42
scripts/create-size-graph.sh Executable file
View File

@ -0,0 +1,42 @@
#!/bin/bash
set -eu
OUTPUT="$(pwd)/sizes.csv"
echo "Tag;Date;Parser;Generator" > $OUTPUT
cd $(dirname $(dirname $0))
git tag | while read TAG
do
git checkout -q tags/$TAG
DATE=$(git log -1 --date=short --pretty=format:%cd)
PARSER_SIZE=$(arduino --verify examples/JsonParserExample/JsonParserExample.ino 2>/dev/null | grep -e 'Sketch uses' | sed 's/.*uses \([0-9]*\).\([0-9]\+\).*/\1\2/')
if [ -e 'examples/JsonGeneratorExample/JsonGeneratorExample.ino' ]; then
GENERATOR_SIZE=$(arduino --verify examples/JsonGeneratorExample/JsonGeneratorExample.ino 2>/dev/null | grep -e 'Sketch uses' | sed 's/.*uses \([0-9]*\).\([0-9]\+\).*/\1\2/')
else
GENERATOR_SIZE=""
fi
echo $TAG
if [ ! -z "$PARSER_SIZE" ]
then
echo "JsonParserExample = $PARSER_SIZE bytes"
else
echo "JsonParserExample compilation failed."
fi
if [ ! -z "$GENERATOR_SIZE" ]
then
echo "JsonGeneratorExample = $GENERATOR_SIZE bytes"
else
echo "JsonGeneratorExample compilation failed."
fi
echo "$TAG;$DATE;$PARSER_SIZE;$GENERATOR_SIZE" >> $OUTPUT
done

16
scripts/travis/arduino.sh Executable file
View File

@ -0,0 +1,16 @@
#!/bin/sh -eux
/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16
sleep 3
export DISPLAY=:1.0
mkdir -p /tmp/arduino
curl -sS http://downloads.arduino.cc/arduino-$VERSION-linux64.tar.xz | tar xJ -C /tmp/arduino --strip 1 ||
curl -sS http://downloads.arduino.cc/arduino-$VERSION-linux64.tgz | tar xz -C /tmp/arduino --strip 1
export PATH=$PATH:/tmp/arduino/
ln -s $PWD /tmp/arduino/libraries/ArduinoJson
for EXAMPLE in $PWD/examples/*/*.ino; do
arduino --verify --board $BOARD $EXAMPLE
done

9
scripts/travis/cmake-osx.sh Executable file
View File

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

9
scripts/travis/cmake.sh Executable file
View File

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

10
scripts/travis/coverage.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh -eux
curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1
/tmp/bin/cmake -DCOVERAGE=true .
make
make test
pip install --user cpp-coveralls
coveralls --exclude third-party --gcov-options '\-lp'; fi

10
scripts/travis/platformio.sh Executable file
View File

@ -0,0 +1,10 @@
#!/bin/sh -eux
pip install --user platformio
rm -r test
for EXAMPLE in JsonParserExample JsonGeneratorExample
do
platformio ci examples/$EXAMPLE/$EXAMPLE.ino -l '.' -b $BOARD
done

View File

@ -1,35 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#ifndef ARDUINO
#include "../../include/ArduinoJson/Arduino/Print.hpp"
#include <stdio.h> // for sprintf
size_t Print::print(const char s[]) {
size_t n = 0;
while (*s) {
n += write(*s++);
}
return n;
}
size_t Print::print(double value, int digits) {
char tmp[32];
sprintf(tmp, "%.*f", digits, value);
return print(tmp);
}
size_t Print::print(long value) {
char tmp[32];
sprintf(tmp, "%ld", value);
return print(tmp);
}
size_t Print::println() { return write('\r') + write('\n'); }
#endif

View File

@ -1,13 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
// About this file
// ---------------
// This file is here to please the Arduino IDE. It must be present in the src/
// for the IDE to find it. Feel free to ignore this file if your working in
// another environment
#include "../include/ArduinoJson.h"

View File

@ -1,47 +0,0 @@
file(GLOB_RECURSE INC_FILES ../include/*.hpp)
file(GLOB_RECURSE SRC_FILES *.cpp)
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
add_definitions(
-fno-exceptions
-pedantic
-Wall
-Wcast-align
-Wcast-qual
-Wconversion
-Wctor-dtor-privacy
-Wdisabled-optimization
-Werror
-Wextra
-Wformat=2
-Winit-self
-Wmissing-include-dirs
-Wno-parentheses
-Wno-sign-conversion
-Wno-unused
-Wno-variadic-macros
-Wold-style-cast
-Woverloaded-virtual
-Wredundant-decls
-Wshadow
-Wsign-promo
-Wstrict-overflow=5
-Wundef
)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU)")
add_definitions(
-Wlogical-op
-Wnoexcept
-Wstrict-null-sentinel
)
endif()
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_definitions(
-Wc++11-compat
)
endif()
add_library(ArduinoJson ${SRC_FILES} ${INC_FILES})

View File

@ -1,29 +0,0 @@
// Copyright Benoit Blanchon 2014
// MIT License
//
// Arduino JSON library
// https://github.com/bblanchon/ArduinoJson
#include "../../include/ArduinoJson/Internals/IndentedPrint.hpp"
using namespace ArduinoJson::Internals;
size_t IndentedPrint::write(uint8_t c) {
size_t n = 0;
if (isNewLine) n += writeTabs();
n += sink->write(c);
isNewLine = c == '\n';
return n;
}
inline size_t IndentedPrint::writeTabs() {
size_t n = 0;
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
return n;
}

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