forked from bblanchon/ArduinoJson
Compare commits
404 Commits
Author | SHA1 | Date | |
---|---|---|---|
24d21467dd | |||
41651136bf | |||
5e5f060fc0 | |||
29ab5fc9c2 | |||
80913b8044 | |||
02960f28e4 | |||
8db338ba14 | |||
dadd8986dc | |||
e2016cf65b | |||
1b214a60fa | |||
8560583ee7 | |||
2932c4ee43 | |||
e8c127a894 | |||
d7ac7ff9a3 | |||
aef7e43c48 | |||
d855b0f98c | |||
c726506b47 | |||
c32e306be9 | |||
13e907c894 | |||
d19a34152f | |||
19cce08b2b | |||
3cd6f66067 | |||
ada588c112 | |||
0d57fe5a7e | |||
5a74beb7e2 | |||
e2d591b9ff | |||
8082185ac4 | |||
85ebc8a1ec | |||
9ca32e664e | |||
566b76121a | |||
562080f22d | |||
bb8bddc758 | |||
9eb8842dda | |||
97558abc29 | |||
160ce092ff | |||
d6974127b4 | |||
092660db52 | |||
348357eb04 | |||
69f6967ad4 | |||
4e3f554b68 | |||
79f6f0dd86 | |||
02f6fab025 | |||
a61fc5b836 | |||
f3a84857d9 | |||
95eb16233c | |||
33654a480b | |||
c296f27640 | |||
4f55f63a77 | |||
a66299a936 | |||
a2cbb68a40 | |||
4163debdd9 | |||
c92ff81ddd | |||
783add8357 | |||
3b77dbbed7 | |||
160ff0961e | |||
06909c451f | |||
b7d8b45e5a | |||
88bfaac7e6 | |||
3c51017e4a | |||
33f6376122 | |||
2beb87136b | |||
f6f8a63b99 | |||
e0ce711eb4 | |||
0911d8d796 | |||
99e5ff78f3 | |||
5236de1433 | |||
0c9451fd5f | |||
dfac1cf71a | |||
1e20e6ef77 | |||
a7b366e74f | |||
3cfd36a5ce | |||
3919f07890 | |||
12e374d0da | |||
36ee4876c6 | |||
05db56760f | |||
e94089ca56 | |||
dc1d0ca698 | |||
627d85ce23 | |||
f6133f2d36 | |||
d8dbfe6e6d | |||
1c450fd3aa | |||
2e47d546b2 | |||
01f13c1b11 | |||
9dc7c2a031 | |||
fe779dace4 | |||
6eef52cc9c | |||
d38131d495 | |||
b4b475d692 | |||
fe17706b6c | |||
d7bad3d70b | |||
5a56ec0636 | |||
35a95f00d9 | |||
93397880ca | |||
8c4c3d8fda | |||
49025d322f | |||
9d2ee6ce63 | |||
70aabca0f7 | |||
dfd59f644b | |||
ee520d1ff5 | |||
ee580f1968 | |||
5179aa0d4f | |||
a7b78fadb0 | |||
d94bcbf249 | |||
086e99efb4 | |||
7b8aba46cc | |||
579c9359df | |||
885e35e892 | |||
e7864c9566 | |||
6e67bc442f | |||
ac9b776aa1 | |||
d8e595907b | |||
1e02fabdec | |||
79bfe731af | |||
a3425a6306 | |||
2e4dd2d591 | |||
f360cc664c | |||
ce6f839153 | |||
01949f7da0 | |||
08de76e2ba | |||
cb97e1fa19 | |||
95e564bfb6 | |||
342b079133 | |||
8138c64116 | |||
64b4e15ce6 | |||
e722fc50b1 | |||
a9f4f611d4 | |||
0fb4fa8f86 | |||
7d73e63c78 | |||
ebb591ef28 | |||
31dea656d5 | |||
768312e870 | |||
5d0e326bfd | |||
8ac4346fd5 | |||
bafec6f1a3 | |||
c6d11294e4 | |||
6ce2497879 | |||
782b178f4e | |||
64529bb1a3 | |||
01dc0d6268 | |||
289b5333d6 | |||
4a17e8c34b | |||
c4cda780d5 | |||
e5669577df | |||
97768ec176 | |||
e25eaed75a | |||
09f6d059a7 | |||
699292b058 | |||
d9cc259df3 | |||
43ad37e7ce | |||
bb816037d6 | |||
04cde11a04 | |||
2f8fde6772 | |||
f224408c07 | |||
21e073a3b4 | |||
f9ea82a2af | |||
1ce6d663af | |||
c1c63067d4 | |||
a8d3e9997e | |||
7cdf7b1769 | |||
429d5011b4 | |||
54f9bd9572 | |||
2a60c96baf | |||
f26f4263ea | |||
507f809da0 | |||
ad83820257 | |||
cd773e3f37 | |||
9da7dce310 | |||
825ab0357e | |||
fead9b50b1 | |||
98463ea168 | |||
74b4544560 | |||
2b5b8fb4c5 | |||
d35b680481 | |||
ca0fbf00f9 | |||
5443e90baf | |||
a5dbb397ca | |||
889f059758 | |||
45a8ed6531 | |||
4c204840e9 | |||
c3001e9ea9 | |||
5cf744dbac | |||
ba2b142c8a | |||
10ab95522d | |||
61218f12fd | |||
852256c1af | |||
8988cb4761 | |||
e0980292ef | |||
cdf3777aa8 | |||
618a54579f | |||
9f69fabe20 | |||
e748ce32bc | |||
fdeedabfd7 | |||
582216e004 | |||
1f6cd8e56e | |||
68fb03577c | |||
bbef8931a6 | |||
8071434515 | |||
7f22a1ab39 | |||
55b0eab3e6 | |||
e85f27c0f3 | |||
e3b4f5038d | |||
b43da1e421 | |||
5c8283b3e4 | |||
3dc533fca0 | |||
d38cbd374a | |||
9175046f35 | |||
888fdc1d54 | |||
d83f1a6319 | |||
ff5f3f3a2c | |||
e4779512e6 | |||
8947a6c9de | |||
fa805b4998 | |||
451c0ee70d | |||
40ac60b941 | |||
7e98d136f4 | |||
c800948342 | |||
7fbc3cb6a6 | |||
d842e246c9 | |||
9946abf731 | |||
1e0464f5b4 | |||
5aefc7d652 | |||
743381de6d | |||
d70ff26164 | |||
316d036785 | |||
c82e6d747b | |||
04330a7a47 | |||
cfbe50057a | |||
9c1b6b80aa | |||
0daf82eee2 | |||
074c39ca5b | |||
1abb8ac6ae | |||
b19a37538c | |||
fc4faacfec | |||
bbc2aa4f2a | |||
1f6bd5c04d | |||
32ffb75394 | |||
7df73824aa | |||
9c32ae2300 | |||
b15dac7edf | |||
2a62132bf0 | |||
a0a82c0f4e | |||
24b46af48a | |||
fed79bfd81 | |||
7dbaac1070 | |||
58d2c4a62f | |||
b847576bb4 | |||
58f155e135 | |||
241ca79114 | |||
3d92531ad3 | |||
c61ee09d26 | |||
c59ddd8a9d | |||
086d07151f | |||
a1cb9c9399 | |||
f265b6ed11 | |||
5db34580f2 | |||
beb49a9446 | |||
ee205971e9 | |||
ded6364e1d | |||
5b6b38564f | |||
31c1a3d804 | |||
81f3460806 | |||
081b345e7c | |||
f468db6757 | |||
c7dcf864cc | |||
6d39bfa703 | |||
4ee1ac015f | |||
b2e2556ef6 | |||
8f74e4e44e | |||
be891daa5a | |||
95a2d6714e | |||
3ce5e53323 | |||
f8c3cdf2ff | |||
88aed98447 | |||
3ae90b66c6 | |||
10c0a8ba70 | |||
d192a14e2e | |||
b49aa22c65 | |||
dae0dc5ebb | |||
35eaa55b3a | |||
bf2d726746 | |||
0dce0022d3 | |||
1bff34a204 | |||
24c60619d5 | |||
b0e12e8852 | |||
f7fa9e9467 | |||
09b6f71853 | |||
e28119f03b | |||
7a40711af3 | |||
b6799dc231 | |||
31c9ea9b28 | |||
6330ab1271 | |||
c35a0fadc3 | |||
bbe034222c | |||
305944e907 | |||
f0754aed53 | |||
99a785179d | |||
21259bc61a | |||
4c67d0579a | |||
cb3c59ec07 | |||
e725b756a6 | |||
dbe6f89ed8 | |||
84e34d2a27 | |||
4d2d535a03 | |||
b0e43f7538 | |||
d66a7adc22 | |||
1a98fd5dfc | |||
57400cee14 | |||
c99bdbf4b9 | |||
a665fa1dec | |||
78048d1d92 | |||
065fe57a7c | |||
f251563af1 | |||
c1ab55f9d9 | |||
27a4d57f7c | |||
22e36bbe9c | |||
d2e1b241be | |||
3d9e40a3a8 | |||
9f85368cce | |||
3243f2dc58 | |||
6b2705769a | |||
ab2587f089 | |||
d3cf568d07 | |||
e417c137fc | |||
d549070fd3 | |||
42ce5ab31f | |||
e190b20ae1 | |||
ce788d96c4 | |||
cc19266470 | |||
18f93b4eb6 | |||
e682ed5a1e | |||
bc44c36385 | |||
bcc8cece24 | |||
a7ff04db0e | |||
a9a51ec1e2 | |||
0495297c6c | |||
75588946c6 | |||
5fa446d3f5 | |||
71fd2de675 | |||
a2fc188526 | |||
166bdd6919 | |||
4d4119e589 | |||
91649df593 | |||
890e811e80 | |||
bb887f94e7 | |||
6e45f7c790 | |||
5580adb4a6 | |||
60a5d72367 | |||
4cfb0ab84d | |||
a1b6c2df75 | |||
feb6060887 | |||
49d2b4b2a2 | |||
286a514fbe | |||
9d3b522e7b | |||
c32642e130 | |||
7a3fa35bd8 | |||
0154fc15cb | |||
24d173c3b9 | |||
d4c1b6f2c2 | |||
58c051f564 | |||
763aa7fe37 | |||
cd88fb0882 | |||
ec843659d8 | |||
2997a405a0 | |||
57f28c2017 | |||
b3b70b78cf | |||
48018bd6e6 | |||
61952a9bcd | |||
602cc104f9 | |||
d71a39211d | |||
f77a8b02e3 | |||
aa2cd0db00 | |||
f127ef6019 | |||
3ae7327687 | |||
23e61cc0f7 | |||
b5002265cf | |||
e48ea94789 | |||
6539c6982c | |||
d877d77b63 | |||
1df6cde026 | |||
fafae8181b | |||
151fc52c1c | |||
ea79340dc7 | |||
9e88514700 | |||
752378a8cb | |||
8465cc0c83 | |||
2ddf8f1619 | |||
f7aa0f89e3 | |||
3d322fdb28 | |||
981adf1989 | |||
dbc3bee3a0 | |||
3f2b7b706a | |||
c243417585 | |||
514a6c0879 | |||
76f9ecce75 | |||
410ca55e88 | |||
66c05041e8 | |||
aafabd8e8d | |||
eb1a774778 | |||
75c89e7b35 | |||
e31a2136fc | |||
380722402f | |||
030c8542e7 | |||
1f25d4434e | |||
f29904e217 |
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
*.sdf
|
||||
*.user
|
||||
*.suo
|
||||
Debug
|
||||
ipch
|
||||
*.opensdf
|
||||
.DS_Store
|
||||
/.idea
|
||||
/build
|
||||
/bin
|
||||
/lib
|
||||
|
12
.travis.yml
Normal file
12
.travis.yml
Normal file
@ -0,0 +1,12 @@
|
||||
language: c++
|
||||
compiler:
|
||||
- gcc
|
||||
- clang
|
||||
before_install:
|
||||
- sudo pip install cpp-coveralls
|
||||
before_script:
|
||||
- cmake -DCOVERAGE=true .
|
||||
script:
|
||||
- make && make test
|
||||
after_success:
|
||||
- coveralls --exclude test --exclude third-party --gcov-options '\-lp'
|
23
ArduinoJson.cpp
Normal file
23
ArduinoJson.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
// This file is here to help the Arduino IDE find the other files.
|
||||
|
||||
#include "src/Arduino/Print.cpp"
|
||||
#include "src/Internals/IndentedPrint.cpp"
|
||||
#include "src/Internals/JsonParser.cpp"
|
||||
#include "src/Internals/List.cpp"
|
||||
#include "src/Internals/Prettyfier.cpp"
|
||||
#include "src/Internals/QuotedString.cpp"
|
||||
#include "src/Internals/StringBuilder.cpp"
|
||||
#include "src/JsonArray.cpp"
|
||||
#include "src/JsonBuffer.cpp"
|
||||
#include "src/JsonObject.cpp"
|
||||
#include "src/JsonVariant.cpp"
|
||||
|
||||
#endif
|
13
ArduinoJson.h
Normal file
13
ArduinoJson.h
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
// This file is here to help the Arduino IDE find the other files.
|
||||
|
||||
#include "include/ArduinoJson.h"
|
||||
|
||||
#endif
|
@ -1,40 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.21005.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonGeneratorTests", "JsonGeneratorTests\JsonGeneratorTests.vcxproj", "{B9545D97-E084-4A19-8E48-929157064360}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonParserTests", "JsonParserTests\JsonParserTests.vcxproj", "{4DD596EF-0185-4AB4-A3C2-F20C496F7806}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonParser", "JsonParser\JsonParser.vcxproj", "{C15274DE-2695-4DFE-8520-4424223FE6DA}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonGenerator", "JsonGenerator\JsonGenerator.vcxproj", "{C6536D27-738D-4CEB-A2BC-E13C8897D894}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B9545D97-E084-4A19-8E48-929157064360}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{B9545D97-E084-4A19-8E48-929157064360}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{B9545D97-E084-4A19-8E48-929157064360}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{B9545D97-E084-4A19-8E48-929157064360}.Release|Win32.Build.0 = Release|Win32
|
||||
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Release|Win32.Build.0 = Release|Win32
|
||||
{C15274DE-2695-4DFE-8520-4424223FE6DA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C15274DE-2695-4DFE-8520-4424223FE6DA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C15274DE-2695-4DFE-8520-4424223FE6DA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C15274DE-2695-4DFE-8520-4424223FE6DA}.Release|Win32.Build.0 = Release|Win32
|
||||
{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
ZIP="C:\Program Files\7-Zip\7z.exe"
|
||||
|
||||
TAG=$(git describe)
|
||||
OUTPUT="ArduinoJson-$TAG.zip"
|
||||
|
||||
cd ..
|
||||
|
||||
INPUT=$(find ArduinoJson -regex ".*\.\(cpp\|h\|md\|txt\|ino\)$" -not -regex ".*Tests/.*")
|
||||
|
||||
rm -f $OUTPUT
|
||||
"$ZIP" a $OUTPUT $INPUT
|
43
CHANGELOG.md
43
CHANGELOG.md
@ -1,6 +1,45 @@
|
||||
Arduino JSON: change log
|
||||
========================
|
||||
|
||||
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
|
||||
----
|
||||
|
||||
* Added DynamicJsonBuffer (issue #19)
|
||||
|
||||
v4.0
|
||||
----
|
||||
|
||||
* Unified parser and generator API (issue #23)
|
||||
* Updated library layout, now requires Arduino 1.0.6 or newer
|
||||
|
||||
**BREAKING CHANGE**: API changed significantly, see [Migrating code to the new API](https://github.com/bblanchon/ArduinoJson/wiki/Migrating-code-to-the-new-API).
|
||||
|
||||
|
||||
v3.4
|
||||
----
|
||||
|
||||
* Fixed escaped char parsing (issue #16)
|
||||
|
||||
|
||||
v3.3
|
||||
----
|
||||
|
||||
* Added indented output for the JSON generator (issue #11), see example bellow.
|
||||
* Added `IndentedPrint`, a decorator for `Print` to allow indented output
|
||||
|
||||
Example:
|
||||
|
||||
JsonOject<2> json;
|
||||
json["key"] = "value";
|
||||
json.prettyPrintTo(Serial);
|
||||
|
||||
v3.2
|
||||
----
|
||||
|
||||
@ -11,7 +50,7 @@ v3.1
|
||||
|
||||
* Calling `Generator::JsonObject::add()` twice with the same `key` now replaces the `value`
|
||||
* Added `Generator::JsonObject::operator[]`, see bellow the new API
|
||||
* Added `Generator::JsonObject::remove()`
|
||||
* Added `Generator::JsonObject::remove()` (issue #9)
|
||||
|
||||
Old generator API:
|
||||
|
||||
@ -32,7 +71,7 @@ v3.0
|
||||
|
||||
* New parser API, see bellow
|
||||
* Renamed `JsonHashTable` into `JsonObject`
|
||||
* Added iterators for `JsonArray` and `JsonObject`
|
||||
* Added iterators for `JsonArray` and `JsonObject` (issue #4)
|
||||
|
||||
Old parser API:
|
||||
|
||||
|
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 2.8.4)
|
||||
project(ArduinoJson)
|
||||
|
||||
enable_testing()
|
||||
|
||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin)
|
||||
|
||||
if(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")
|
||||
endif()
|
||||
|
||||
add_subdirectory(src)
|
||||
add_subdirectory(test)
|
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* malloc-free JSON parser for Arduino
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
// This file is here to help the Arduino IDE find the .cpp files
|
||||
|
||||
#include "JsonGenerator/EscapedString.cpp"
|
||||
#include "JsonGenerator/JsonArrayBase.cpp"
|
||||
#include "JsonGenerator/JsonObjectBase.cpp"
|
||||
#include "JsonGenerator/JsonValue.cpp"
|
||||
#include "JsonGenerator/StringBuilder.cpp"
|
@ -1,7 +0,0 @@
|
||||
/*
|
||||
* malloc-free JSON parser for Arduino
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonGenerator/JsonArray.h"
|
||||
#include "JsonGenerator/JsonObject.h"
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "EscapedString.h"
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
static inline char getSpecialChar(char c)
|
||||
{
|
||||
// Optimized for code size on a 8-bit AVR
|
||||
|
||||
const char* p = "\"\"\\\\\bb\ff\nn\rr\tt\0";
|
||||
|
||||
while (p[0] && p[0] != c)
|
||||
{
|
||||
p += 2;
|
||||
}
|
||||
|
||||
return p[1];
|
||||
}
|
||||
|
||||
static inline size_t printCharTo(char c, Print& p)
|
||||
{
|
||||
char specialChar = getSpecialChar(c);
|
||||
|
||||
return specialChar != 0
|
||||
? p.write('\\') + p.write(specialChar)
|
||||
: p.write(c);
|
||||
}
|
||||
|
||||
size_t EscapedString::printTo(const char* s, Print& p)
|
||||
{
|
||||
if (!s) return p.print("null");
|
||||
|
||||
size_t n = p.write('\"');
|
||||
|
||||
while (*s)
|
||||
{
|
||||
n += printCharTo(*s++, p);
|
||||
}
|
||||
|
||||
return n + p.write('\"');
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Internals
|
||||
{
|
||||
class EscapedString
|
||||
{
|
||||
public:
|
||||
static size_t printTo(const char*, Print&);
|
||||
};
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonArrayBase.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
template<int N>
|
||||
class JsonArray : public JsonArrayBase
|
||||
{
|
||||
public:
|
||||
JsonArray()
|
||||
: JsonArrayBase(items, N)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
JsonValue items[N];
|
||||
};
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonArrayBase.h"
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
size_t JsonArrayBase::printTo(Print& p) const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
n += p.write('[');
|
||||
|
||||
// NB: the code has been optimized for a small size on a 8-bit AVR
|
||||
|
||||
const JsonValue* current = items;
|
||||
for (int i = count; i > 0; i--)
|
||||
{
|
||||
n += current->printTo(p);
|
||||
current++;
|
||||
|
||||
if (i > 1)
|
||||
{
|
||||
n += p.write(',');
|
||||
}
|
||||
}
|
||||
|
||||
n += p.write(']');
|
||||
|
||||
return n;
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonPrintable.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
class JsonArrayBase : public JsonPrintable
|
||||
{
|
||||
public:
|
||||
JsonArrayBase(JsonValue* items, int capacity)
|
||||
: items(items), capacity(capacity), count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void add(const Printable& value)
|
||||
{
|
||||
addIfPossible<const Printable&>(value);
|
||||
}
|
||||
|
||||
void add(bool value)
|
||||
{
|
||||
addIfPossible<bool>(value);
|
||||
}
|
||||
|
||||
void add(int value)
|
||||
{
|
||||
addIfPossible<long>(value);
|
||||
}
|
||||
|
||||
void add(long value)
|
||||
{
|
||||
addIfPossible<long>(value);
|
||||
}
|
||||
|
||||
void add(double value)
|
||||
{
|
||||
addIfPossible<double>(value);
|
||||
}
|
||||
|
||||
void add(const char* value)
|
||||
{
|
||||
addIfPossible<const char*>(value);
|
||||
}
|
||||
|
||||
template<int DIGITS>
|
||||
void add(double value)
|
||||
{
|
||||
if (count >= capacity) return;
|
||||
|
||||
JsonValue& v = items[count++];
|
||||
v.set<DIGITS>(value);
|
||||
}
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
|
||||
using JsonPrintable::printTo;
|
||||
|
||||
private:
|
||||
JsonValue* items;
|
||||
int capacity, count;
|
||||
|
||||
template<typename T>
|
||||
void addIfPossible(T value)
|
||||
{
|
||||
if (count < capacity)
|
||||
items[count++] = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="EscapedString.h" />
|
||||
<ClInclude Include="JsonArray.h" />
|
||||
<ClInclude Include="JsonArrayBase.h" />
|
||||
<ClInclude Include="JsonObject.h" />
|
||||
<ClInclude Include="JsonObjectBase.h" />
|
||||
<ClInclude Include="JsonPrintable.h" />
|
||||
<ClInclude Include="JsonValue.h" />
|
||||
<ClInclude Include="Print.h" />
|
||||
<ClInclude Include="Printable.h" />
|
||||
<ClInclude Include="StringBuilder.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="EscapedString.cpp" />
|
||||
<ClCompile Include="JsonArrayBase.cpp" />
|
||||
<ClCompile Include="JsonObjectBase.cpp" />
|
||||
<ClCompile Include="JsonValue.cpp" />
|
||||
<ClCompile Include="Print.cpp" />
|
||||
<ClCompile Include="StringBuilder.cpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C6536D27-738D-4CEB-A2BC-E13C8897D894}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>JsonGenerator</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,69 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="EscapedString.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonArrayBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonPrintable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonValue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Print.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Printable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="StringBuilder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonObjectBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonObject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="EscapedString.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonArrayBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonValue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StringBuilder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Print.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonObjectBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonObjectBase.h"
|
||||
|
||||
#ifndef ARDUINO_JSON_NO_DEPRECATION_WARNING
|
||||
#ifdef __GNUC__
|
||||
#define DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define DEPRECATED __declspec(deprecated)
|
||||
#endif
|
||||
#else
|
||||
#define DEPRECATED
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
template <int N>
|
||||
class JsonObject : public JsonObjectBase
|
||||
{
|
||||
public:
|
||||
JsonObject()
|
||||
: JsonObjectBase(items, N)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
KeyValuePair items[N];
|
||||
};
|
||||
|
||||
|
||||
// Obsolete: use JsonObject instead
|
||||
template <int N>
|
||||
class DEPRECATED JsonHashTable : public JsonObject<N>
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonObjectBase.h"
|
||||
#include <string.h> // for strcmp
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
JsonValue JsonObjectBase::nullValue;
|
||||
|
||||
size_t JsonObjectBase::printTo(Print& p) const
|
||||
{
|
||||
size_t n = 0;
|
||||
|
||||
n += p.write('{');
|
||||
|
||||
// NB: the code has been optimized for a small size on a 8-bit AVR
|
||||
|
||||
const KeyValuePair* current = items;
|
||||
for (int i = count; i > 0; i--)
|
||||
{
|
||||
n += EscapedString::printTo(current->key, p);
|
||||
n += p.write(':');
|
||||
n += current->value.printTo(p);
|
||||
|
||||
current++;
|
||||
|
||||
if (i > 1)
|
||||
{
|
||||
n += p.write(',');
|
||||
}
|
||||
}
|
||||
|
||||
n += p.write('}');
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
JsonObjectBase::KeyValuePair* JsonObjectBase::getMatchingPair(JsonKey key) const
|
||||
{
|
||||
KeyValuePair* p = items;
|
||||
|
||||
for (int i = count; i > 0; --i)
|
||||
{
|
||||
if (!strcmp(p->key, key))
|
||||
return p;
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
JsonValue& JsonObjectBase::operator[](JsonKey key)
|
||||
{
|
||||
KeyValuePair* match = getMatchingPair(key);
|
||||
|
||||
if (match)
|
||||
return match->value;
|
||||
|
||||
JsonValue* value;
|
||||
|
||||
if (count < capacity)
|
||||
{
|
||||
items[count].key = key;
|
||||
value = &items[count].value;
|
||||
count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
value = &nullValue;
|
||||
}
|
||||
|
||||
value->reset();
|
||||
return *value;
|
||||
}
|
||||
|
||||
bool JsonObjectBase::containsKey(JsonKey key) const
|
||||
{
|
||||
return getMatchingPair(key) != 0;
|
||||
}
|
||||
|
||||
void JsonObjectBase::remove(JsonKey key)
|
||||
{
|
||||
KeyValuePair* match = getMatchingPair(key);
|
||||
if (match == 0) return;
|
||||
|
||||
*match = items[--count];
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonPrintable.h"
|
||||
#include "EscapedString.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
typedef const char* JsonKey;
|
||||
|
||||
class JsonObjectBase : public JsonPrintable
|
||||
{
|
||||
public:
|
||||
JsonValue& operator[](JsonKey);
|
||||
bool containsKey(JsonKey) const;
|
||||
void remove(JsonKey key);
|
||||
|
||||
template<typename T>
|
||||
void add(JsonKey key, T value)
|
||||
{
|
||||
operator[](key) = value;
|
||||
}
|
||||
|
||||
template<int DIGITS>
|
||||
void add(JsonKey key, double value)
|
||||
{
|
||||
operator[](key).set<DIGITS>(value);
|
||||
}
|
||||
|
||||
using JsonPrintable::printTo;
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
|
||||
protected:
|
||||
|
||||
struct KeyValuePair
|
||||
{
|
||||
JsonKey key;
|
||||
JsonValue value;
|
||||
};
|
||||
|
||||
JsonObjectBase(KeyValuePair* items, int capacity)
|
||||
: items(items), capacity(capacity), count(0)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
KeyValuePair* items;
|
||||
int capacity, count;
|
||||
static JsonValue nullValue;
|
||||
|
||||
KeyValuePair* getMatchingPair(JsonKey key) const;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include "Print.h"
|
||||
#include "Printable.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
class JsonPrintable : public Printable
|
||||
{
|
||||
public:
|
||||
|
||||
size_t printTo(char* buffer, size_t bufferSize)
|
||||
{
|
||||
using namespace Internals;
|
||||
|
||||
StringBuilder sb(buffer, bufferSize);
|
||||
return printTo(sb);
|
||||
}
|
||||
|
||||
virtual size_t printTo(Print& p) const = 0;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "EscapedString.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
size_t JsonValue::printBoolTo(const Content& c, Print& p)
|
||||
{
|
||||
return p.print(c.asBool ? "true" : "false");
|
||||
}
|
||||
|
||||
size_t JsonValue::printLongTo(const Content& c, Print& p)
|
||||
{
|
||||
return p.print(c.asLong);
|
||||
}
|
||||
|
||||
size_t JsonValue::printPrintableTo(const Content& c, Print& p)
|
||||
{
|
||||
if (c.asPrintable)
|
||||
return c.asPrintable->printTo(p);
|
||||
else
|
||||
return p.print("null");
|
||||
}
|
||||
|
||||
size_t JsonValue::printStringTo(const Content& c, Print& p)
|
||||
{
|
||||
return EscapedString::printTo(c.asString, p);
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "EscapedString.h"
|
||||
#include "Printable.h"
|
||||
#include "StringBuilder.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
class JsonValue
|
||||
{
|
||||
public:
|
||||
|
||||
void operator=(bool value)
|
||||
{
|
||||
printToImpl = &printBoolTo;
|
||||
content.asBool = value;
|
||||
}
|
||||
|
||||
void operator=(long value)
|
||||
{
|
||||
printToImpl = &printLongTo;
|
||||
content.asLong = value;
|
||||
}
|
||||
|
||||
void operator=(int value)
|
||||
{
|
||||
printToImpl = &printLongTo;
|
||||
content.asLong = value;
|
||||
}
|
||||
|
||||
void operator=(const Printable& value)
|
||||
{
|
||||
printToImpl = &printPrintableTo;
|
||||
content.asPrintable = &value;
|
||||
}
|
||||
|
||||
void operator=(const char* value)
|
||||
{
|
||||
printToImpl = &printStringTo;
|
||||
content.asString = value;
|
||||
}
|
||||
|
||||
void operator=(double value)
|
||||
{
|
||||
set<2>(value);
|
||||
}
|
||||
|
||||
template <int DIGITS>
|
||||
void set(double value)
|
||||
{
|
||||
printToImpl = &printDoubleTo < DIGITS > ;
|
||||
content.asDouble = value;
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return content.asBool;
|
||||
}
|
||||
|
||||
operator const char*()
|
||||
{
|
||||
return content.asString;
|
||||
}
|
||||
|
||||
operator double()
|
||||
{
|
||||
return content.asDouble;
|
||||
}
|
||||
|
||||
operator float()
|
||||
{
|
||||
return (float)content.asDouble;
|
||||
}
|
||||
|
||||
operator int()
|
||||
{
|
||||
return content.asLong;
|
||||
}
|
||||
|
||||
operator long()
|
||||
{
|
||||
return content.asLong;
|
||||
}
|
||||
|
||||
operator const Printable&()
|
||||
{
|
||||
return *content.asPrintable;
|
||||
}
|
||||
|
||||
size_t printTo(Print& p) const
|
||||
{
|
||||
// handmade polymorphism
|
||||
return printToImpl(content, p);
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
content.asDouble = 0;
|
||||
printToImpl = printStringTo;
|
||||
}
|
||||
|
||||
private:
|
||||
union Content
|
||||
{
|
||||
bool asBool;
|
||||
double asDouble;
|
||||
long asLong;
|
||||
const Printable* asPrintable;
|
||||
const char* asString;
|
||||
};
|
||||
|
||||
Content content;
|
||||
|
||||
size_t(*printToImpl)(const Content&, Print&);
|
||||
|
||||
static size_t printBoolTo(const Content&, Print&);
|
||||
static size_t printLongTo(const Content&, Print&);
|
||||
static size_t printPrintableTo(const Content&, Print&);
|
||||
static size_t printStringTo(const Content&, Print&);
|
||||
|
||||
template <int DIGITS>
|
||||
static size_t printDoubleTo(const Content& c, Print& p)
|
||||
{
|
||||
return p.print(c.asDouble, DIGITS);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
#include "Print.h"
|
||||
#include <cstdio>
|
||||
|
||||
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, "%.*lg", digits+1, value);
|
||||
return print(tmp);
|
||||
}
|
||||
|
||||
size_t Print::print(long value)
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%ld", value);
|
||||
return print(tmp);
|
||||
}
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
// This class reproduces Arduino's Print
|
||||
class Print
|
||||
{
|
||||
public:
|
||||
|
||||
virtual size_t write(uint8_t) = 0;
|
||||
|
||||
size_t print(const char[]);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(long);
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <Print.h>
|
||||
|
||||
#endif
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef ARDUINO
|
||||
|
||||
class Print;
|
||||
|
||||
class Printable
|
||||
{
|
||||
public:
|
||||
|
||||
virtual size_t printTo(Print& p) const = 0;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <Printable.h>
|
||||
|
||||
#endif
|
||||
|
@ -1,239 +0,0 @@
|
||||
Arduino JSON library - Generator
|
||||
================================
|
||||
|
||||
*An elegant and efficient JSON encoder 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 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
|
||||
--------
|
||||
|
||||
* Elegant API, very easy to use
|
||||
* Fixed memory allocation (no malloc)
|
||||
* Small footprint
|
||||
* Supports nested objects
|
||||
* Implements Arduino's `Printable interface
|
||||
* MIT License
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
JsonArray<2> array;
|
||||
array.add<6>(48.756080); // <6> specifies the number of digits in the output
|
||||
array.add<6>(2.302038); // (the default is 2)
|
||||
|
||||
JsonObject<3> root;
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
root["data"] = array;
|
||||
|
||||
Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
|
||||
|
||||
How to use?
|
||||
------------
|
||||
|
||||
### 1. Install the library
|
||||
|
||||
Download the library and extract it to:
|
||||
|
||||
<your Arduino Sketch folder>/libraries/ArduinoJson
|
||||
|
||||
### 2. Import in your sketch
|
||||
|
||||
Just add the following lines at the top of your `.ino` file:
|
||||
|
||||
#include <JsonGenerator.h>
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
|
||||
> ##### Having a namespace conflict?
|
||||
> To be able to use both `ArduinoJson::Generator` and `ArduinoJson::Parser` in the same file, you need to do one of the followings:
|
||||
>
|
||||
> * Put the `using` statements into different functions
|
||||
> * `using namespace ArduinoJson`, then prefix the type names by `Generator::` or `Parser::`
|
||||
> * Create aliases for the namespaces or the types (C++11 only)
|
||||
|
||||
### 3. Create object tree
|
||||
|
||||
In order to generate a JSON string, you need to build the equivalent object tree. You usually start by the root which can be either a JSON Array or a JSON Object.
|
||||
|
||||
#### JSON Array
|
||||
|
||||
You create an array with the following line:
|
||||
|
||||
JsonArray<8> array;
|
||||
|
||||
See the little `<8>`? It's a template parameter that gives the capacity of the array, it's the maximum number of elements you can put in it.
|
||||
|
||||
> ##### About the capacity
|
||||
> As stated in the feature list, this library works with a fixed memory allocation.
|
||||
> This means that the size of the object must be know at the compilation time, therefore you can **not** use a variable to set the capacity of the array.
|
||||
|
||||
Then you can add strings, integer, booleans, etc:
|
||||
|
||||
array.add("bazinga!");
|
||||
array.add(42);
|
||||
array.add(true);
|
||||
|
||||
There are two syntaxes for floating point values:
|
||||
|
||||
array.add<4>(3.1415); // 4 digits: "3.1415"
|
||||
array.add(3.14); // 2 digits: "3.14"
|
||||
|
||||
> ##### About floating point precision
|
||||
> The overload of `add()` with 2 parameters allows you to specify the number of decimals to save in the JSON string.
|
||||
> When you use the overload with one parameter, you use the default number of decimals which is two.
|
||||
> Note that this behavior is the exact same as Arduino's `Print::print(double,int);` which is implemented by `Serial`.
|
||||
> So you may already be familiar with it.
|
||||
|
||||
Finally you can add nested object to the array:
|
||||
|
||||
JsonArray<8> nestedArray;
|
||||
array.add(nestedArray);
|
||||
|
||||
or
|
||||
|
||||
JsonObject<8> nestedObject;
|
||||
array.add(nestedObject);
|
||||
|
||||
> ##### CAUTION! Nested objects must be in memory
|
||||
> Calling `add()` makes the `JsonArray` store a pointer to the nested object.
|
||||
> This is designed to avoid memory duplication.
|
||||
> But it can only work if the object is in memory when `printTo()` is executed.
|
||||
> For instance, don't do this:
|
||||
>
|
||||
> void addNestedObject()
|
||||
> {
|
||||
> JsonObject<2> nestedObject;
|
||||
> // ...
|
||||
> array.add(nestedObject); // <- DON'T !!
|
||||
>
|
||||
> // array now contains a pointer to a local variable that will be
|
||||
> // discarded as soon as the function exits
|
||||
> }
|
||||
>
|
||||
> For the same reason, don't do this either:
|
||||
>
|
||||
> for( int i=0; i<100; i++)
|
||||
> {
|
||||
> JsonObject<2> nestedObject;
|
||||
> // ...
|
||||
> array.add(nestedObject); // <- DON'T !!
|
||||
> }
|
||||
> // array now contains 100 pointers to the same a local variable
|
||||
> // that is out of the scope anyway
|
||||
|
||||
#### JSON Object
|
||||
|
||||
You create a JSON object (ie hash-table/dictionary) with the following line:
|
||||
|
||||
JsonObject<8> object;
|
||||
|
||||
Like with the array class, there is a template parameter that gives the capacity of the object.
|
||||
|
||||
Then you can add strings, integer, booleans, etc:
|
||||
|
||||
object["key1"] = "bazinga!";
|
||||
object["key2"] = 42;
|
||||
object["key3"] = true;
|
||||
|
||||
As for the arrays, there are two syntaxes for the floating point values:
|
||||
|
||||
object["key4"].set<4>(3.1415); // 4 digits "3.1415"
|
||||
object["key5"] = 3.1415; // default: 2 digits "3.14"
|
||||
|
||||
Finally you can add nested objects:
|
||||
|
||||
JsonArray<8> nestedArray;
|
||||
object["key6"] = nestedArray;
|
||||
|
||||
or
|
||||
|
||||
JsonObject<8> nestedObject;
|
||||
object["key7"] = nestedObject;
|
||||
|
||||
> ##### Other JsonObject functions
|
||||
> * `object.add(key, value)` is a synonym for `object[key] = value`
|
||||
> * `object.containsKey(key)` returns `true` is the `key` is present in `object`
|
||||
> * `object.remove(key)` removes the `value` associated with `key`
|
||||
|
||||
### 4. Get the JSON string
|
||||
|
||||
There are two ways tho get the resulting JSON string.
|
||||
|
||||
Depending on your project, you may need to dump the string in a classic `char[]` or send it to a stream like `Serial` or `EthernetClient `.
|
||||
|
||||
Both ways are the easy way :-)
|
||||
|
||||
#### Use a classic `char[]`
|
||||
|
||||
Whether you have a `JsonArray` or a `JsonObject`, simply call `printTo()` with the destination buffer, like so:
|
||||
|
||||
char buffer[256];
|
||||
array.printTo(buffer, sizeof(buffer));
|
||||
|
||||
#### Send to a stream
|
||||
|
||||
It's very likely that the generated JSON will end up in a stream like `Serial` or `EthernetClient `, so you can save some time and memory by doing this:
|
||||
|
||||
Serial.print(array);
|
||||
|
||||
or
|
||||
|
||||
array.printTo(Serial);
|
||||
|
||||
> ##### About the Printable interface
|
||||
> `JsonArray` and `JsonObject` implement Arduino's `Printable` interface.
|
||||
> This is why you can call `Serial.print()` like in the example above.
|
||||
> You can do the same with any other implementation of `Print`: `HardwareSerial`, `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`...
|
||||
|
||||
|
||||
Memory usage
|
||||
------------
|
||||
|
||||
Here are the size of the main classes of the library.
|
||||
|
||||
This table is for an 8-bit Arduino, types would be bigger on a 32-bit processor.
|
||||
|
||||
| Type | Size in bytes |
|
||||
| --------------------| ------------- |
|
||||
| JsonArray<N> | 8 + 6 x N |
|
||||
| JsonObject<N> | 8 + 8 x N |
|
||||
|
||||
|
||||
Code size
|
||||
---------
|
||||
|
||||
The following values has been obtained with Arduino IDE 1.0.5, targeting an Arduino Duelmilanove with an ATmega 328.
|
||||
|
||||
### Minimum setup
|
||||
|
||||
| Function | Size |
|
||||
| ----------------------------------- | ---- |
|
||||
| `JsonObjectBase::printTo()` | 234 |
|
||||
| `EscapedString::printTo()` | 196 |
|
||||
| `JsonArrayBase::printTo()` | 164 |
|
||||
| `Print::print(char const*)` | 146 |
|
||||
| `JsonObjectBase::operator[]` | 114 |
|
||||
| `JsonObjectBase::getMatchingPair()` | 72 |
|
||||
| `JsonValue::printPrintableTo()` | 40 |
|
||||
| `JsonValue::printStringTo()` | 12 |
|
||||
|
||||
### Additional space for integers
|
||||
|
||||
| Function | Size |
|
||||
| ---------------------------- | ---- |
|
||||
| `Print::print(long, int)` | 328 |
|
||||
| `JsonValue::printLongTo()` | 22 |
|
||||
|
||||
### Additional space for floating point
|
||||
|
||||
| Function | Size |
|
||||
| ------------------------------ | ---- |
|
||||
| `Print::print(double, int)` | 1548 |
|
||||
| `JsonValue::printDouleTo<2>()` | 22 |
|
@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "StringBuilder.h"
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
size_t StringBuilder::write(uint8_t c)
|
||||
{
|
||||
if (length >= capacity) return 0;
|
||||
|
||||
buffer[length++] = c;
|
||||
buffer[length] = 0;
|
||||
return 1;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Internals
|
||||
{
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "EscapedString.h"
|
||||
#include "StringBuilder.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(EscapedStringTests)
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t returnValue;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(Null)
|
||||
{
|
||||
whenInputIs(0);
|
||||
outputMustBe("null");
|
||||
}
|
||||
|
||||
TEST_METHOD(EmptyString)
|
||||
{
|
||||
whenInputIs("");
|
||||
outputMustBe("\"\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(QuotationMark)
|
||||
{
|
||||
whenInputIs("\"");
|
||||
outputMustBe("\"\\\"\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(ReverseSolidus)
|
||||
{
|
||||
whenInputIs("\\");
|
||||
outputMustBe("\"\\\\\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(Solidus)
|
||||
{
|
||||
whenInputIs("/");
|
||||
outputMustBe("\"/\""); // but the JSON format allows \/
|
||||
}
|
||||
|
||||
TEST_METHOD(Backspace)
|
||||
{
|
||||
whenInputIs("\b");
|
||||
outputMustBe("\"\\b\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(Formfeed)
|
||||
{
|
||||
whenInputIs("\f");
|
||||
outputMustBe("\"\\f\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(Newline)
|
||||
{
|
||||
whenInputIs("\n");
|
||||
outputMustBe("\"\\n\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(CarriageReturn)
|
||||
{
|
||||
whenInputIs("\r");
|
||||
outputMustBe("\"\\r\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(HorizontalTab)
|
||||
{
|
||||
whenInputIs("\t");
|
||||
outputMustBe("\"\\t\"");
|
||||
}
|
||||
|
||||
private:
|
||||
void whenInputIs(const char* input)
|
||||
{
|
||||
StringBuilder sb(buffer, sizeof(buffer));
|
||||
returnValue = EscapedString::printTo(input, sb);
|
||||
}
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
{
|
||||
Assert::AreEqual(expected, buffer);
|
||||
Assert::AreEqual(strlen(expected), returnValue);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(Issue10)
|
||||
{
|
||||
struct Person {
|
||||
int id;
|
||||
char name[32];
|
||||
};
|
||||
|
||||
Person persons[2];
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD_INITIALIZE(Initialize)
|
||||
{
|
||||
Person boss;
|
||||
boss.id = 1;
|
||||
strcpy(boss.name, "Jeff");
|
||||
Person employee;
|
||||
employee.id = 2;
|
||||
strcpy(employee.name, "John");
|
||||
persons[0] = boss;
|
||||
persons[1] = employee;
|
||||
}
|
||||
|
||||
TEST_METHOD(WrongWayToAddObjectInAnArray)
|
||||
{
|
||||
JsonArray<2> json;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
JsonObject<2> object;
|
||||
|
||||
object["id"] = persons[i].id;
|
||||
object["name"] = persons[i].name;
|
||||
|
||||
json.add(object); // <- Adding a reference to a temporary variable
|
||||
}
|
||||
|
||||
char buffer[256];
|
||||
json.printTo(buffer, sizeof(buffer));
|
||||
|
||||
// the same values are repeated, that's normal
|
||||
Assert::AreEqual("[{\"id\":2,\"name\":\"John\"},{\"id\":2,\"name\":\"John\"}]", buffer);
|
||||
}
|
||||
|
||||
TEST_METHOD(RightWayToAddObjectInAnArray)
|
||||
{
|
||||
JsonArray<2> json;
|
||||
JsonObject<2> object[2];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
object[i]["id"] = persons[i].id;
|
||||
object[i]["name"] = persons[i].name;
|
||||
|
||||
json.add(object[i]);
|
||||
}
|
||||
|
||||
char buffer[256];
|
||||
json.printTo(buffer, sizeof(buffer));
|
||||
|
||||
Assert::AreEqual("[{\"id\":1,\"name\":\"Jeff\"},{\"id\":2,\"name\":\"John\"}]", buffer);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,162 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonArrayTests)
|
||||
{
|
||||
JsonArray<2> array;
|
||||
char buffer[256];
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
outputMustBe("[]");
|
||||
}
|
||||
|
||||
TEST_METHOD(Null)
|
||||
{
|
||||
array.add((char*) 0);
|
||||
|
||||
outputMustBe("[null]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneString)
|
||||
{
|
||||
array.add("hello");
|
||||
|
||||
outputMustBe("[\"hello\"]");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
array.add("hello");
|
||||
array.add("world");
|
||||
|
||||
outputMustBe("[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneStringOverCapacity)
|
||||
{
|
||||
array.add("hello");
|
||||
array.add("world");
|
||||
array.add("lost");
|
||||
|
||||
outputMustBe("[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleDefaultDigits)
|
||||
{
|
||||
array.add(3.14159265358979323846);
|
||||
outputMustBe("[3.14]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleFourDigits)
|
||||
{
|
||||
array.add<4>(3.14159265358979323846);
|
||||
outputMustBe("[3.1416]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneInteger)
|
||||
{
|
||||
array.add(1);
|
||||
|
||||
outputMustBe("[1]");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoIntegers)
|
||||
{
|
||||
array.add(1);
|
||||
array.add(2);
|
||||
|
||||
outputMustBe("[1,2]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneIntegerOverCapacity)
|
||||
{
|
||||
array.add(1);
|
||||
array.add(2);
|
||||
array.add(3);
|
||||
|
||||
outputMustBe("[1,2]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneTrue)
|
||||
{
|
||||
array.add(true);
|
||||
|
||||
outputMustBe("[true]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneFalse)
|
||||
{
|
||||
array.add(false);
|
||||
|
||||
outputMustBe("[false]");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoBooleans)
|
||||
{
|
||||
array.add(false);
|
||||
array.add(true);
|
||||
|
||||
outputMustBe("[false,true]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneBooleanOverCapacity)
|
||||
{
|
||||
array.add(false);
|
||||
array.add(true);
|
||||
array.add(false);
|
||||
|
||||
outputMustBe("[false,true]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedArray)
|
||||
{
|
||||
JsonArray<1> nestedArray;
|
||||
|
||||
array.add(nestedArray);
|
||||
|
||||
outputMustBe("[[]]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedHash)
|
||||
{
|
||||
JsonObject<1> nestedObject;
|
||||
|
||||
array.add(nestedObject);
|
||||
|
||||
outputMustBe("[{}]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneNestedArrayWithOneInteger)
|
||||
{
|
||||
JsonArray<1> nestedArray;
|
||||
nestedArray.add(1);
|
||||
|
||||
array.add(nestedArray);
|
||||
|
||||
outputMustBe("[[1]]");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
{
|
||||
size_t n = array.printTo(buffer, sizeof(buffer));
|
||||
Assert::AreEqual(expected, buffer);
|
||||
Assert::AreEqual(strlen(expected), n);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B9545D97-E084-4A19-8E48-929157064360}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>JsonGeneratorTests</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)/../JsonGenerator;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(ProjectDir)/../JsonGenerator;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ARDUINO_JSON_NO_DEPRECATION_WARNING;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="EscapedStringTests.cpp" />
|
||||
<ClCompile Include="Issue10.cpp" />
|
||||
<ClCompile Include="JsonArrayTests.cpp" />
|
||||
<ClCompile Include="JsonObject_Indexer_Tests.cpp" />
|
||||
<ClCompile Include="JsonObject_PrintTo_Tests.cpp" />
|
||||
<ClCompile Include="JsonValue_Cast_Tests.cpp" />
|
||||
<ClCompile Include="JsonValue_PrintTo_Tests.cpp" />
|
||||
<ClCompile Include="StringBuilderTests.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\JsonGenerator\JsonGenerator.vcxproj">
|
||||
<Project>{c6536d27-738d-4ceb-a2bc-e13c8897d894}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,43 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="JsonArrayTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StringBuilderTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EscapedStringTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonObject_PrintTo_Tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonObject_Indexer_Tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonValue_PrintTo_Tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonValue_Cast_Tests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Issue10.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonObject_Indexer_Tests)
|
||||
{
|
||||
JsonObject<2> object;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
mustNotContain("key");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
|
||||
mustContain("key1", "value1");
|
||||
mustContain("key2", "value2");
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveFirst)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
object.remove("key1");
|
||||
|
||||
mustNotContain("key1");
|
||||
mustContain("key2", "value2");
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveLast)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
object.remove("key2");
|
||||
|
||||
mustContain("key1", "value1");
|
||||
mustNotContain("key2");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void mustContain(const char* key, const char* expected)
|
||||
{
|
||||
Assert::IsTrue(object.containsKey(key));
|
||||
|
||||
const char* actual = object[key];
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
void mustNotContain(const char* key)
|
||||
{
|
||||
Assert::IsFalse(object.containsKey(key));
|
||||
|
||||
const char* actual = object[key];
|
||||
Assert::IsNull(actual);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonObject_PrintTo_Tests)
|
||||
{
|
||||
JsonObject<2> object;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
outputMustBe("{}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneString)
|
||||
{
|
||||
object["key"] = "value";
|
||||
|
||||
outputMustBe("{\"key\":\"value\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
|
||||
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveFirst)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
object.remove("key1");
|
||||
|
||||
outputMustBe("{\"key2\":\"value2\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveLast)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
object.remove("key2");
|
||||
|
||||
outputMustBe("{\"key1\":\"value1\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(RemoveUnexistingKey)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
object.remove("key3");
|
||||
|
||||
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(ReplaceExistingKey)
|
||||
{
|
||||
object["key"] = "value1";
|
||||
object["key"] = "value2";
|
||||
|
||||
outputMustBe("{\"key\":\"value2\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneStringOverCapacity)
|
||||
{
|
||||
object["key1"] = "value1";
|
||||
object["key2"] = "value2";
|
||||
object["key3"] = "value3";
|
||||
|
||||
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneInteger)
|
||||
{
|
||||
object["key"] = 1;
|
||||
outputMustBe("{\"key\":1}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleFourDigits)
|
||||
{
|
||||
object["key"].set<4>(3.14159265358979323846);
|
||||
outputMustBe("{\"key\":3.1416}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleDefaultDigits)
|
||||
{
|
||||
object["key"] = 3.14159265358979323846;
|
||||
outputMustBe("{\"key\":3.14}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneNull)
|
||||
{
|
||||
object["key"] = (char*) 0;
|
||||
outputMustBe("{\"key\":null}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneTrue)
|
||||
{
|
||||
object["key"] = true;
|
||||
outputMustBe("{\"key\":true}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneFalse)
|
||||
{
|
||||
object["key"] = false;
|
||||
outputMustBe("{\"key\":false}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedArray)
|
||||
{
|
||||
auto nestedArray = JsonArray<1>();
|
||||
|
||||
object["key"] = nestedArray;
|
||||
|
||||
outputMustBe("{\"key\":[]}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedObject)
|
||||
{
|
||||
auto nestedObject = JsonObject<1>();
|
||||
|
||||
object["key"] = nestedObject;
|
||||
|
||||
outputMustBe("{\"key\":{}}");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
{
|
||||
char buffer[256];
|
||||
size_t result;
|
||||
|
||||
result = object.printTo(buffer, sizeof(buffer));
|
||||
|
||||
Assert::AreEqual(strlen(expected), result);
|
||||
Assert::AreEqual(expected, buffer);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "StringBuilder.h"
|
||||
#include "JsonValue.h"
|
||||
#include "JsonArray.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonValue_Cast_Tests)
|
||||
{
|
||||
JsonValue value;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(Bool)
|
||||
{
|
||||
setValueAndCheckCast(true);
|
||||
setValueAndCheckCast(false);
|
||||
}
|
||||
|
||||
TEST_METHOD(Double)
|
||||
{
|
||||
setValueAndCheckCast(3.14156);
|
||||
}
|
||||
|
||||
TEST_METHOD(Float)
|
||||
{
|
||||
setValueAndCheckCast(3.14f);
|
||||
}
|
||||
|
||||
TEST_METHOD(Integer)
|
||||
{
|
||||
setValueAndCheckCast(42);
|
||||
}
|
||||
|
||||
TEST_METHOD(Long)
|
||||
{
|
||||
setValueAndCheckCast(42L);
|
||||
}
|
||||
|
||||
TEST_METHOD(Array)
|
||||
{
|
||||
JsonArray<2> array;
|
||||
setValueAndCheckCast(array);
|
||||
}
|
||||
|
||||
TEST_METHOD(String)
|
||||
{
|
||||
setValueAndCheckCast("hello");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<typename T>
|
||||
void setValueAndCheckCast(T expected)
|
||||
{
|
||||
value = expected;
|
||||
T actual = value;
|
||||
Assert::AreEqual(expected, actual);
|
||||
}
|
||||
|
||||
template<int N>
|
||||
void setValueAndCheckCast(JsonArray<N>& expected)
|
||||
{
|
||||
value = expected;
|
||||
const Printable& actual = value;
|
||||
Assert::AreEqual((void*) &expected, (void*) &actual);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "StringBuilder.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonValue_PrintTo_Tests)
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t returnValue;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(String)
|
||||
{
|
||||
setValueTo("hello");
|
||||
outputMustBe("\"hello\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(Float)
|
||||
{
|
||||
setValueTo(3.1415f);
|
||||
outputMustBe("3.14");
|
||||
}
|
||||
|
||||
TEST_METHOD(DoubleZeroDigits)
|
||||
{
|
||||
setValueTo<0>(3.14159265358979323846);
|
||||
outputMustBe("3");
|
||||
}
|
||||
|
||||
TEST_METHOD(DoubleOneDigit)
|
||||
{
|
||||
setValueTo<1>(3.14159265358979323846);
|
||||
outputMustBe("3.1");
|
||||
}
|
||||
|
||||
TEST_METHOD(DoubleTwoDigits)
|
||||
{
|
||||
setValueTo<2>(3.14159265358979323846);
|
||||
outputMustBe("3.14");
|
||||
}
|
||||
|
||||
TEST_METHOD(Integer)
|
||||
{
|
||||
setValueTo(314);
|
||||
outputMustBe("314");
|
||||
}
|
||||
|
||||
TEST_METHOD(Char)
|
||||
{
|
||||
setValueTo('A');
|
||||
outputMustBe("65");
|
||||
}
|
||||
|
||||
TEST_METHOD(Short)
|
||||
{
|
||||
setValueTo((short)314);
|
||||
outputMustBe("314");
|
||||
}
|
||||
|
||||
TEST_METHOD(Long)
|
||||
{
|
||||
setValueTo(314159265L);
|
||||
outputMustBe("314159265");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<int DIGITS>
|
||||
void setValueTo(double value)
|
||||
{
|
||||
StringBuilder sb(buffer, sizeof(buffer));
|
||||
JsonValue jsonValue;
|
||||
jsonValue.set<DIGITS>(value);
|
||||
returnValue = jsonValue.printTo(sb);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void setValueTo(T value)
|
||||
{
|
||||
StringBuilder sb(buffer, sizeof(buffer));
|
||||
JsonValue jsonValue;
|
||||
jsonValue = value;
|
||||
returnValue = jsonValue.printTo(sb);
|
||||
}
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
{
|
||||
Assert::AreEqual(expected, buffer);
|
||||
Assert::AreEqual(strlen(expected), returnValue);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "StringBuilder.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(StringBuilderTests)
|
||||
{
|
||||
char buffer[20];
|
||||
Print* sb;
|
||||
size_t returnValue;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD_INITIALIZE(Initialize)
|
||||
{
|
||||
sb = new StringBuilder(buffer, sizeof(buffer));
|
||||
}
|
||||
|
||||
TEST_METHOD(InitialState)
|
||||
{
|
||||
outputMustBe("");
|
||||
}
|
||||
|
||||
TEST_METHOD(OverCapacity)
|
||||
{
|
||||
print("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
resultMustBe(19);
|
||||
|
||||
print("ABC");
|
||||
resultMustBe(0);
|
||||
|
||||
outputMustBe("ABCDEFGHIJKLMNOPQRS");
|
||||
}
|
||||
|
||||
TEST_METHOD(EmptyString)
|
||||
{
|
||||
print("");
|
||||
resultMustBe(0);
|
||||
outputMustBe("");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneString)
|
||||
{
|
||||
print("ABCD");
|
||||
resultMustBe(4);
|
||||
outputMustBe("ABCD");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
print("ABCD");
|
||||
resultMustBe(4);
|
||||
|
||||
print("EFGH");
|
||||
resultMustBe(4);
|
||||
|
||||
outputMustBe("ABCDEFGH");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void print(const char* value)
|
||||
{
|
||||
returnValue = sb->print(value);
|
||||
}
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
{
|
||||
Assert::AreEqual(expected, buffer);
|
||||
}
|
||||
|
||||
void resultMustBe(size_t expected)
|
||||
{
|
||||
Assert::AreEqual(expected, returnValue);
|
||||
}
|
||||
};
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
// This file is here to help the Arduino IDE find the .cpp files
|
||||
|
||||
#include "JsonParser/JsonArray.cpp"
|
||||
#include "JsonParser/JsonObject.cpp"
|
||||
#include "JsonParser/JsonParserBase.cpp"
|
||||
#include "JsonParser/JsonValue.cpp"
|
||||
#include "JsonParser/JsonToken.cpp"
|
||||
#include "JsonParser/jsmn.cpp"
|
@ -1,6 +0,0 @@
|
||||
/*
|
||||
* malloc-free JSON parser for Arduino
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonParser/JsonParser.h"
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
DEPRECATED JsonObject JsonArray::getHashTable(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include "JsonArrayIterator.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
class JsonObject;
|
||||
|
||||
// A JSON array
|
||||
class JsonArray : JsonValue
|
||||
{
|
||||
public:
|
||||
|
||||
// Create an invalid array
|
||||
JsonArray()
|
||||
{
|
||||
}
|
||||
|
||||
// Convert a JsonValue into a JsonArray
|
||||
JsonArray(JsonValue value)
|
||||
: JsonValue(value)
|
||||
{
|
||||
}
|
||||
|
||||
// Tell if the array is valid
|
||||
bool success()
|
||||
{
|
||||
return isArray();
|
||||
}
|
||||
|
||||
// Get the JsonValue at specified index
|
||||
JsonValue operator[](int index)
|
||||
{
|
||||
return JsonValue::operator[](index);
|
||||
}
|
||||
|
||||
// Get the size of the array
|
||||
int size()
|
||||
{
|
||||
return isArray() ? childrenCount() : 0;
|
||||
}
|
||||
|
||||
// Get an iterator pointing to the beginning of the array
|
||||
JsonArrayIterator begin()
|
||||
{
|
||||
return isArray() ? firstChild() : null();
|
||||
}
|
||||
|
||||
// Gets an iterator pointing to the end of the array
|
||||
JsonArrayIterator end()
|
||||
{
|
||||
return isArray() ? nextSibling() : null();
|
||||
}
|
||||
|
||||
// Obsolete: Use size() instead
|
||||
DEPRECATED int getLength()
|
||||
{
|
||||
return size();
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED JsonArray getArray(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED bool getBool(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED double getDouble(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED JsonObject getHashTable(int index);
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED long getLong(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED char* getString(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// An iterator for JsonArray
|
||||
class JsonArrayIterator : JsonToken
|
||||
{
|
||||
public:
|
||||
|
||||
// Create an iterator pointing at the specified JsonToken
|
||||
JsonArrayIterator(JsonToken token)
|
||||
: JsonToken(token)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Move iterator forward
|
||||
void operator++()
|
||||
{
|
||||
*this = JsonArrayIterator(nextSibling());
|
||||
}
|
||||
|
||||
// Get the value pointed by the iterator
|
||||
JsonValue operator*() const
|
||||
{
|
||||
return JsonValue(*this);
|
||||
}
|
||||
|
||||
// Test iterator equality
|
||||
bool operator!= (const JsonArrayIterator& other) const
|
||||
{
|
||||
return JsonToken::operator!=(other);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
DEPRECATED JsonArray JsonObject::getArray(const char* key)
|
||||
{
|
||||
return operator[](key);
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include "JsonObjectIterator.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
class JsonArray;
|
||||
|
||||
// A JSON Object (ie hash-table/dictionary)
|
||||
class JsonObject : JsonValue
|
||||
{
|
||||
public:
|
||||
|
||||
// Create an invalid JsonObject
|
||||
JsonObject()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Convert a JsonValue into a JsonObject
|
||||
JsonObject(JsonValue value)
|
||||
: JsonValue(value)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Tell if the object is valid
|
||||
bool success()
|
||||
{
|
||||
return isObject();
|
||||
}
|
||||
|
||||
// Get the value associated with the specified key.
|
||||
JsonValue operator[](const char* key)
|
||||
{
|
||||
return JsonValue::operator[](key);
|
||||
}
|
||||
|
||||
// Tell if the specified key exists in the object.
|
||||
bool containsKey(const char* key)
|
||||
{
|
||||
return operator[](key).success();
|
||||
}
|
||||
|
||||
// Get an iterator pointing at the beginning of the object
|
||||
JsonObjectIterator begin()
|
||||
{
|
||||
return isObject() ? firstChild() : null();
|
||||
}
|
||||
|
||||
// Get an iterator pointing at the end of the object
|
||||
JsonObjectIterator end()
|
||||
{
|
||||
return isObject() ? nextSibling() : null();
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED JsonArray getArray(const char* key);
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED bool getBool(const char* key)
|
||||
{
|
||||
return operator[](key);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED double getDouble(const char* key)
|
||||
{
|
||||
return operator[](key);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED JsonObject getHashTable(const char* key)
|
||||
{
|
||||
return operator[](key);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED long getLong(const char* key)
|
||||
{
|
||||
return operator[](key);
|
||||
}
|
||||
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED char* getString(const char* key)
|
||||
{
|
||||
return operator[](key);
|
||||
}
|
||||
};
|
||||
|
||||
// Obsolete: Use JsonObject instead
|
||||
DEPRECATED typedef JsonObject JsonHashTable;
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonValue.h"
|
||||
#include "JsonPair.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// An iterator for JsonObject
|
||||
class JsonObjectIterator : JsonToken
|
||||
{
|
||||
public:
|
||||
|
||||
// Create an iterator pointing at the specified token
|
||||
JsonObjectIterator(JsonToken token)
|
||||
: JsonToken(token)
|
||||
{
|
||||
}
|
||||
|
||||
// Move to the next JsonPair
|
||||
void operator++()
|
||||
{
|
||||
*this = JsonObjectIterator(nextSibling().nextSibling());
|
||||
}
|
||||
|
||||
// Get the JsonPair pointed by the iterator
|
||||
JsonPair operator*() const
|
||||
{
|
||||
return JsonPair(*this);
|
||||
}
|
||||
|
||||
// Test iterator equality
|
||||
bool operator!= (const JsonObjectIterator& other) const
|
||||
{
|
||||
return JsonToken::operator!=(other);
|
||||
}
|
||||
|
||||
// Get the key of the JsonPair pointed by the iterator
|
||||
const char* key() const
|
||||
{
|
||||
return operator*().key();
|
||||
}
|
||||
|
||||
// Get the key of the JsonPair pointed by the iterator
|
||||
JsonValue value() const
|
||||
{
|
||||
return operator*().value();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonValue.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// A JSON key-value pair, as a part of a JSON object
|
||||
class JsonPair : JsonToken
|
||||
{
|
||||
public:
|
||||
// Convert a JsonToken to a JsonPair
|
||||
JsonPair(JsonToken token)
|
||||
: JsonToken(token)
|
||||
{
|
||||
}
|
||||
|
||||
// Get the key
|
||||
const char* key()
|
||||
{
|
||||
return getText();
|
||||
}
|
||||
|
||||
// Get the value
|
||||
JsonValue value()
|
||||
{
|
||||
return nextSibling();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonParserBase.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// The JSON parser.
|
||||
//
|
||||
// You need to specifiy the number of token to be allocated for that parser.
|
||||
//
|
||||
// CAUTION: JsonArray, JsonObject and JsonValue contain pointers to tokens of the
|
||||
// JsonParser, so they need the JsonParser to be in memory to work.
|
||||
// As a result, you must not create JsonArray, JsonObject or JsonValue that have a
|
||||
// longer life that the JsonParser.
|
||||
template <int MAX_TOKENS>
|
||||
class JsonParser : public JsonParserBase
|
||||
{
|
||||
public:
|
||||
JsonParser()
|
||||
: JsonParserBase(tokens, MAX_TOKENS)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
jsmntok_t tokens[MAX_TOKENS];
|
||||
};
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{C15274DE-2695-4DFE-8520-4424223FE6DA}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>JsonParser</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="jsmn.h" />
|
||||
<ClInclude Include="JsonArray.h" />
|
||||
<ClInclude Include="JsonArrayIterator.h" />
|
||||
<ClInclude Include="JsonObject.h" />
|
||||
<ClInclude Include="JsonObjectIterator.h" />
|
||||
<ClInclude Include="JsonPair.h" />
|
||||
<ClInclude Include="JsonParser.h" />
|
||||
<ClInclude Include="JsonParserBase.h" />
|
||||
<ClInclude Include="JsonToken.h" />
|
||||
<ClInclude Include="JsonValue.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jsmn.cpp" />
|
||||
<ClCompile Include="JsonArray.cpp" />
|
||||
<ClCompile Include="JsonObject.cpp" />
|
||||
<ClCompile Include="JsonParserBase.cpp" />
|
||||
<ClCompile Include="JsonToken.cpp" />
|
||||
<ClCompile Include="JsonValue.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,69 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="JsonParserBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonToken.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonValue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonParser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="jsmn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonArrayIterator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonObject.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonObjectIterator.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="JsonPair.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="jsmn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonArray.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonObject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonParserBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonToken.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonValue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonParserBase.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
JsonValue JsonParserBase::parse(char* json)
|
||||
{
|
||||
jsmn_parser parser;
|
||||
jsmn_init(&parser);
|
||||
|
||||
if (JSMN_SUCCESS != jsmn_parse(&parser, json, tokens, maxTokens))
|
||||
return JsonToken::null();
|
||||
|
||||
return JsonToken(json, tokens);
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// Base class for the JSON parser, in case you want to provide your own buffer
|
||||
class JsonParserBase
|
||||
{
|
||||
public:
|
||||
|
||||
// Create a JSON parser using the provided buffer
|
||||
JsonParserBase(jsmntok_t* tokens, int maxTokens)
|
||||
: tokens(tokens), maxTokens(maxTokens)
|
||||
{
|
||||
}
|
||||
|
||||
// Parse the JSON string and return a array
|
||||
//
|
||||
// The content of the string may be altered to add '\0' at the
|
||||
// end of string tokens
|
||||
JsonValue parse(char* json);
|
||||
|
||||
// Obsolete: use parse() instead
|
||||
DEPRECATED JsonArray parseArray(char* json)
|
||||
{
|
||||
return parse(json);
|
||||
}
|
||||
|
||||
// Obsolete: use parse() instead
|
||||
DEPRECATED JsonObject parseHashTable(char* json)
|
||||
{
|
||||
return parse(json);
|
||||
}
|
||||
|
||||
private:
|
||||
jsmntok_t* tokens;
|
||||
int maxTokens;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonToken.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
JsonToken JsonToken::nextSibling() const
|
||||
{
|
||||
// start with current token
|
||||
jsmntok_t* t = token;
|
||||
|
||||
// count the number of token to skip
|
||||
int yetToVisit = 1;
|
||||
|
||||
// skip all nested tokens
|
||||
while (yetToVisit)
|
||||
{
|
||||
yetToVisit += t->size - 1;
|
||||
t++;
|
||||
}
|
||||
|
||||
// build a JsonToken at the new location
|
||||
return JsonToken(json, t);
|
||||
}
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsmn.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// A pointer to a JSON token
|
||||
class JsonToken
|
||||
{
|
||||
public:
|
||||
|
||||
// Create a "null" pointer
|
||||
JsonToken()
|
||||
: token(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Create a pointer to the specified JSON token
|
||||
JsonToken(char* json, jsmntok_t* token)
|
||||
: json(json), token(token)
|
||||
{
|
||||
}
|
||||
|
||||
// Get content of the JSON token
|
||||
char* getText()
|
||||
{
|
||||
json[token->end] = 0;
|
||||
return json + token->start;
|
||||
}
|
||||
|
||||
// Get the number of children tokens
|
||||
int childrenCount()
|
||||
{
|
||||
return token->size;
|
||||
}
|
||||
|
||||
// Get a pointer to the first child of the current token
|
||||
JsonToken firstChild() const
|
||||
{
|
||||
return JsonToken(json, token + 1);
|
||||
}
|
||||
|
||||
// Get a pointer to the next sibling token (ie skiping the children tokens)
|
||||
JsonToken nextSibling() const;
|
||||
|
||||
// Test equality
|
||||
bool operator!=(const JsonToken& other) const
|
||||
{
|
||||
return token != other.token;
|
||||
}
|
||||
|
||||
// Tell if the pointer is "null"
|
||||
bool isValid()
|
||||
{
|
||||
return token != 0;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a JSON object
|
||||
bool isObject()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_OBJECT;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a JSON array
|
||||
bool isArray()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_ARRAY;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a primitive
|
||||
bool isPrimitive()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_PRIMITIVE;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a string
|
||||
bool isString()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_STRING;
|
||||
}
|
||||
|
||||
// Explicit wait to create a "null" JsonToken
|
||||
static JsonToken null()
|
||||
{
|
||||
return JsonToken();
|
||||
}
|
||||
|
||||
private:
|
||||
char* json;
|
||||
jsmntok_t* token;
|
||||
};
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include <stdlib.h> // for strtol, strtod
|
||||
#include <string.h> // for strcmp()
|
||||
#include "JsonArray.h"
|
||||
#include "JsonObject.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
// Convert the JsonValue to a bool.
|
||||
// Returns false if the JsonValue is not a primitve.
|
||||
JsonValue::operator bool()
|
||||
{
|
||||
if (!isPrimitive()) return 0;
|
||||
|
||||
char *text = getText();
|
||||
|
||||
// "true"
|
||||
if (text[0] == 't') return true;
|
||||
|
||||
// "false"
|
||||
if (text[0] == 'f') return false;
|
||||
|
||||
// "null"
|
||||
if (text[0] == 'n') return false;
|
||||
|
||||
// number
|
||||
return strtol(text, 0, 0) != 0;
|
||||
}
|
||||
|
||||
// Convert the JsonValue to a floating point value.
|
||||
// Returns false if the JsonValue is not a number.
|
||||
JsonValue::operator double()
|
||||
{
|
||||
return isPrimitive() ? strtod(getText(), 0) : 0;
|
||||
}
|
||||
|
||||
// Convert the JsonValue to a floating point value.
|
||||
// Returns false if the JsonValue is not a number.
|
||||
JsonValue::operator long()
|
||||
{
|
||||
return isPrimitive() ? strtol(getText(), 0, 0) : 0;
|
||||
}
|
||||
|
||||
// Convert the JsonValue to a string.
|
||||
// Returns 0 if the JsonValue is not a string.
|
||||
JsonValue::operator char*()
|
||||
{
|
||||
return isString() || isPrimitive() ? getText() : 0;
|
||||
}
|
||||
|
||||
// Get the nested value at the specified index.
|
||||
// Returns an invalid JsonValue if the current value is not an array.
|
||||
JsonValue JsonValue::operator[](int index)
|
||||
{
|
||||
// sanity check
|
||||
if (index < 0 || !isArray() || index >= childrenCount())
|
||||
return null();
|
||||
|
||||
// skip first token, it's the whole object
|
||||
JsonToken runningToken = firstChild();
|
||||
|
||||
// skip all tokens before the specified index
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
// move forward: current + nested tokens
|
||||
runningToken = runningToken.nextSibling();
|
||||
}
|
||||
|
||||
return runningToken;
|
||||
}
|
||||
|
||||
// Get the nested value matching the specified index.
|
||||
// Returns an invalid JsonValue if the current value is not an object.
|
||||
JsonValue JsonValue::operator[](const char* desiredKey)
|
||||
{
|
||||
// sanity check
|
||||
if (desiredKey == 0 || !isObject())
|
||||
return null();
|
||||
|
||||
// skip first token, it's the whole object
|
||||
JsonToken runningToken = firstChild();
|
||||
|
||||
// scan each keys
|
||||
for (int i = 0; i < childrenCount() / 2; i++)
|
||||
{
|
||||
// get 'key' token string
|
||||
char* key = runningToken.getText();
|
||||
|
||||
// move to the 'value' token
|
||||
runningToken = runningToken.nextSibling();
|
||||
|
||||
// compare with desired name
|
||||
if (strcmp(desiredKey, key) == 0)
|
||||
{
|
||||
// return the value token that follows the key token
|
||||
return runningToken;
|
||||
}
|
||||
|
||||
// skip nested tokens
|
||||
runningToken = runningToken.nextSibling();
|
||||
}
|
||||
|
||||
// nothing found, return NULL
|
||||
return null();
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonToken.h"
|
||||
|
||||
#ifndef ARDUINO_JSON_NO_DEPRECATION_WARNING
|
||||
#ifdef __GNUC__
|
||||
#define DEPRECATED __attribute__((deprecated))
|
||||
#elif defined(_MSC_VER)
|
||||
#define DEPRECATED __declspec(deprecated)
|
||||
#endif
|
||||
#else
|
||||
#define DEPRECATED
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// A JSON value
|
||||
// Can be converted to string, double, bool, array or object.
|
||||
class JsonValue : protected JsonToken
|
||||
{
|
||||
public:
|
||||
|
||||
// Create a invalid value
|
||||
JsonValue()
|
||||
{
|
||||
}
|
||||
|
||||
// Convert a JsonToken to a JsonValue
|
||||
JsonValue(JsonToken token)
|
||||
: JsonToken(token)
|
||||
{
|
||||
}
|
||||
|
||||
// Tell is the JsonValue is valid
|
||||
bool success()
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
// Convert the JsonValue to a bool.
|
||||
// Returns false if the JsonValue is not a primitve.
|
||||
operator bool();
|
||||
|
||||
// Convert the JsonValue to a floating point value.
|
||||
// Returns false if the JsonValue is not a number.
|
||||
operator double();
|
||||
|
||||
// Convert the JsonValue to a long integer.
|
||||
// Returns 0 if the JsonValue is not a number.
|
||||
operator long();
|
||||
|
||||
// Convert the JsonValue to a string.
|
||||
// Returns 0 if the JsonValue is not a string.
|
||||
operator char*();
|
||||
|
||||
// Get the nested value at the specified index.
|
||||
// Returns an invalid JsonValue if the current value is not an array.
|
||||
JsonValue operator[](int index);
|
||||
|
||||
// Get the nested value matching the specified index.
|
||||
// Returns an invalid JsonValue if the current value is not an object.
|
||||
JsonValue operator[](const char* key);
|
||||
};
|
||||
}
|
||||
}
|
@ -1,250 +0,0 @@
|
||||
Arduino JSON library - Parser
|
||||
=============================
|
||||
|
||||
This library is an thin C++ wrapper around the *jsmn* tokenizer: http://zserge.com/jsmn.html
|
||||
|
||||
It's design to be very lightweight, works without any allocation on the heap (no malloc) and supports nested objects.
|
||||
|
||||
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
|
||||
--------
|
||||
|
||||
* Based on the well-proven [jsmn](http://zserge.com/jsmn.html) tokenizer
|
||||
* Supports nested objects
|
||||
* Elegant API, very easy to use
|
||||
* Fixed memory allocation (no malloc)
|
||||
* Small footprint
|
||||
* MIT License
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
JsonParser<32> parser;
|
||||
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
|
||||
JsonObject root = parser.parse(json);
|
||||
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
|
||||
How to use ?
|
||||
-------------
|
||||
|
||||
### 1. Install the library
|
||||
|
||||
Download the library and extract it to:
|
||||
|
||||
<your Arduino Sketch folder>/libraries/ArduinoJson
|
||||
|
||||
### 2. Import in your sketch
|
||||
|
||||
Just add the following lines at the top of your `.ino` file:
|
||||
|
||||
#include <JsonParser.h>
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
> ##### Having a namespace conflict?
|
||||
> To be able to use both `ArduinoJson::Generator` and `ArduinoJson::Parser` in the same file, you need to do one of the followings:
|
||||
>
|
||||
> * Put the `using` statements into different functions
|
||||
> * `using namespace ArduinoJson`, then prefix the type names by `Generator::` or `Parser::`
|
||||
> * Create aliases for the namespaces or the types (C++11 only)
|
||||
|
||||
### 3. Create a parser
|
||||
|
||||
To extract data from the JSON string, you need to create a `JsonParser`, and specify the number of token you allocate for the parser itself:
|
||||
|
||||
JsonParser<32> parser;
|
||||
|
||||
> #### How to choose the number of tokens ?
|
||||
|
||||
> A token is an element of the JSON object: either a key, a value, an object or an array.
|
||||
> As an example the `char json[]` on the top of this page contains 12 tokens (don't forget to count 1 for the whole object and 1 more for the array itself).
|
||||
|
||||
> The more tokens you allocate, the more complex the JSON can be, but also the more memory is occupied.
|
||||
> Each token takes 8 bytes, so `sizeof(JsonParser<32>)` is 256 bytes which is quite big in an Arduino with only 2KB of RAM.
|
||||
> Don't forget that you also have to store the JSON string in RAM and it's probably big.
|
||||
|
||||
> 32 tokens may seem small, but it's very decent for an 8-bit processor, you wouldn't get better results with other JSON libraries.
|
||||
|
||||
### 4. Extract data
|
||||
|
||||
To use this library, you need to know beforehand what is the type of data contained in the JSON string, which is very likely.
|
||||
|
||||
The root object has to be either an object (like `{"key":"value"}`) or an array (like `[1,2]`).
|
||||
|
||||
The nested objects can be either arrays, booleans, objects, numbers or strings.
|
||||
If you need other type, you can get the string value and parse it yourself.
|
||||
|
||||
#### Object
|
||||
|
||||
Consider we have a `char json[]` containing to the following JSON string:
|
||||
|
||||
{
|
||||
"sensor":"gps",
|
||||
"time":1351824120,
|
||||
"data":[48.756080,2.302038]
|
||||
}
|
||||
|
||||
In this case the string contains a JSON object, so you need to extract a `JsonObject`:
|
||||
|
||||
JsonObject root = parser.parse(json);
|
||||
|
||||
To check if the parsing was successful, you must check:
|
||||
|
||||
if (!root.success())
|
||||
{
|
||||
// Parsing fail: could be an invalid JSON, or too many tokens
|
||||
}
|
||||
|
||||
And then extract the member you need:
|
||||
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
You can also iterate through the key-value pairs of the object:
|
||||
|
||||
for (JsonObjectIterator i=root.begin(); i!=root.end(); ++i)
|
||||
{
|
||||
Serial.println(i.key());
|
||||
Serial.println((char*)i.value());
|
||||
}
|
||||
|
||||
#### Array
|
||||
|
||||
Consider we have a `char json[]` containing to the following JSON string:
|
||||
|
||||
[
|
||||
[ 1.2, 3.4 ],
|
||||
[ 5.6, 7.8 ]
|
||||
]
|
||||
|
||||
In this case the root object of the JSON string is an array, so you need to extract a `JsonArray`:
|
||||
|
||||
JsonArray root = parser.parse(json);
|
||||
|
||||
To check if the parsing was successful, you must check:
|
||||
|
||||
if (!root.success())
|
||||
{
|
||||
// Parsing fail: could be an invalid JSON, or too many tokens
|
||||
}
|
||||
|
||||
And then extract the content by its index in the array:
|
||||
|
||||
double a = root[0][0];
|
||||
double b = root[0][1];
|
||||
double c = root[1][0];
|
||||
double d = root[1][1];
|
||||
|
||||
You can also iterate through the key-value pairs of the object:
|
||||
|
||||
for (JsonArrayIterator i=array.begin(); i!=array.end(); ++i)
|
||||
{
|
||||
Serial.println((char*)*i);
|
||||
}
|
||||
|
||||
Common pitfalls
|
||||
---------------
|
||||
|
||||
### 1. Not enough tokens
|
||||
|
||||
By design, the library has no way to tell you why `JsonParser::parse()` failed.
|
||||
|
||||
There are basically two reasons why they may fail:
|
||||
|
||||
1. the JSON string is invalid
|
||||
2. the JSON string contains more tokens that the parser can store
|
||||
|
||||
So, if you are sure the JSON string is correct and you still can't parse it, you should slightly increase the number of token of the parser.
|
||||
|
||||
### 2. Not enough memory
|
||||
|
||||
You may go into unpredictable trouble if you allocate more memory than your processor really has.
|
||||
It's a very common issue in embedded development.
|
||||
|
||||
To diagnose this, look at every big objects in you code and sum their size to check that they fit in RAM.
|
||||
|
||||
For example, don't do this:
|
||||
|
||||
char json[1024]; // 1 KB
|
||||
JsonParser<64> parser; // 512 B
|
||||
|
||||
because it may be too big for a processor with only 2 KB: you need free memory to store other variables and the call stack.
|
||||
|
||||
That is why an 8-bit processor is not able to parse long and complex JSON strings.
|
||||
|
||||
### 3. JsonParser not in memory
|
||||
|
||||
To reduce the memory consumption, `JsonValue`, `JsonArray` and `JsonObject` contains pointer to the token that are inside the `JsonParser`. This can only work if the `JsonParser` is still in memory.
|
||||
|
||||
For example, don't do this:
|
||||
|
||||
JsonArray getArray(char* json)
|
||||
{
|
||||
JsonParser<16> parser;
|
||||
return parser.parseArray(parser);
|
||||
}
|
||||
|
||||
because the local variable `parser` will be *removed* from memory when the function `getArray()` returns, and the pointer inside `JsonArray` will point to an invalid location.
|
||||
|
||||
### 4. JSON string is altered
|
||||
|
||||
This will probably never be an issue, but you need to be aware of this feature.
|
||||
|
||||
When you pass a `char[]` to `JsonParser::parse()`, the content of the string will be altered to add `\0` at the end of the tokens.
|
||||
|
||||
This is because we want functions like `JsonArray::getString()` to return a null-terminating string without any memory allocation.
|
||||
|
||||
|
||||
Memory usage
|
||||
------------
|
||||
|
||||
Here are the size of the main classes of the library.
|
||||
|
||||
This table is for an 8-bit Arduino, types would be bigger on a 32-bit processor.
|
||||
|
||||
| Type | Size in bytes |
|
||||
| ------------ | ------------- |
|
||||
| `Parser<N>` | 4 + 8 x N |
|
||||
| `JsonArray` | 4 |
|
||||
| `JsonObject` | 4 |
|
||||
| `JsonValue` | 4 |
|
||||
|
||||
Code size
|
||||
---------
|
||||
|
||||
The sizes have been obtained with Arduino IDE 1.0.5 for a Duemilanove.
|
||||
|
||||
### Minimum setup
|
||||
|
||||
| Function | Size |
|
||||
| ------------------------------------ | ---- |
|
||||
| `jsmn_parse()` | 962 |
|
||||
| `JsonValue::operator[](char const*)` | 218 |
|
||||
| `JsonParserBase::parse()` | 116 |
|
||||
| `JsonValue::operator[](int)` | 108 |
|
||||
| `strcmp()` | 18 |
|
||||
|
||||
### Additional space for integers
|
||||
|
||||
| Function | Size |
|
||||
| ---------------------------- | ---- |
|
||||
| `strtol()` | 606 |
|
||||
| `JsonValue::operator long()` | 94 |
|
||||
|
||||
### Additional space for floating points
|
||||
|
||||
| Function | Size |
|
||||
| -------------------------------- | ----- |
|
||||
| `strtod()` | 1369 |
|
||||
| `JsonValue::operator double()` | 82 |
|
@ -1,255 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jsmn.h"
|
||||
|
||||
/**
|
||||
* Allocates a fresh unused token from the token pull.
|
||||
*/
|
||||
static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,
|
||||
jsmntok_t *tokens, size_t num_tokens) {
|
||||
jsmntok_t *tok;
|
||||
if (parser->toknext >= num_tokens) {
|
||||
return NULL;
|
||||
}
|
||||
tok = &tokens[parser->toknext++];
|
||||
tok->start = tok->end = -1;
|
||||
tok->size = 0;
|
||||
#ifdef JSMN_PARENT_LINKS
|
||||
tok->parent = -1;
|
||||
#endif
|
||||
return tok;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills token type and boundaries.
|
||||
*/
|
||||
static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,
|
||||
int start, int end) {
|
||||
token->type = type;
|
||||
token->start = start;
|
||||
token->end = end;
|
||||
token->size = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills next available token with JSON primitive.
|
||||
*/
|
||||
static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js,
|
||||
jsmntok_t *tokens, size_t num_tokens) {
|
||||
jsmntok_t *token;
|
||||
int start;
|
||||
|
||||
start = parser->pos;
|
||||
|
||||
for (; js[parser->pos] != '\0'; parser->pos++) {
|
||||
switch (js[parser->pos]) {
|
||||
#ifndef JSMN_STRICT
|
||||
/* In strict mode primitive must be followed by "," or "}" or "]" */
|
||||
case ':':
|
||||
#endif
|
||||
case '\t' : case '\r' : case '\n' : case ' ' :
|
||||
case ',' : case ']' : case '}' :
|
||||
goto found;
|
||||
}
|
||||
if (js[parser->pos] < 32 || js[parser->pos] >= 127) {
|
||||
parser->pos = start;
|
||||
return JSMN_ERROR_INVAL;
|
||||
}
|
||||
}
|
||||
#ifdef JSMN_STRICT
|
||||
/* In strict mode primitive must be followed by a comma/object/array */
|
||||
parser->pos = start;
|
||||
return JSMN_ERROR_PART;
|
||||
#endif
|
||||
|
||||
found:
|
||||
token = jsmn_alloc_token(parser, tokens, num_tokens);
|
||||
if (token == NULL) {
|
||||
parser->pos = start;
|
||||
return JSMN_ERROR_NOMEM;
|
||||
}
|
||||
jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos);
|
||||
#ifdef JSMN_PARENT_LINKS
|
||||
token->parent = parser->toksuper;
|
||||
#endif
|
||||
parser->pos--;
|
||||
return JSMN_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filsl next token with JSON string.
|
||||
*/
|
||||
static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js,
|
||||
jsmntok_t *tokens, size_t num_tokens) {
|
||||
jsmntok_t *token;
|
||||
|
||||
int start = parser->pos;
|
||||
|
||||
parser->pos++;
|
||||
|
||||
/* Skip starting quote */
|
||||
for (; js[parser->pos] != '\0'; parser->pos++) {
|
||||
char c = js[parser->pos];
|
||||
|
||||
/* Quote: end of string */
|
||||
if (c == '\"') {
|
||||
token = jsmn_alloc_token(parser, tokens, num_tokens);
|
||||
if (token == NULL) {
|
||||
parser->pos = start;
|
||||
return JSMN_ERROR_NOMEM;
|
||||
}
|
||||
jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos);
|
||||
#ifdef JSMN_PARENT_LINKS
|
||||
token->parent = parser->toksuper;
|
||||
#endif
|
||||
return JSMN_SUCCESS;
|
||||
}
|
||||
|
||||
/* Backslash: Quoted symbol expected */
|
||||
if (c == '\\') {
|
||||
parser->pos++;
|
||||
switch (js[parser->pos]) {
|
||||
/* Allowed escaped symbols */
|
||||
case '\"': case '/' : case '\\' : case 'b' :
|
||||
case 'f' : case 'r' : case 'n' : case 't' :
|
||||
break;
|
||||
/* Allows escaped symbol \uXXXX */
|
||||
case 'u':
|
||||
/* TODO */
|
||||
break;
|
||||
/* Unexpected symbol */
|
||||
default:
|
||||
parser->pos = start;
|
||||
return JSMN_ERROR_INVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
parser->pos = start;
|
||||
return JSMN_ERROR_PART;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON string and fill tokens.
|
||||
*/
|
||||
jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,
|
||||
unsigned int num_tokens) {
|
||||
jsmnerr_t r;
|
||||
int i;
|
||||
jsmntok_t *token;
|
||||
|
||||
for (; js[parser->pos] != '\0'; parser->pos++) {
|
||||
char c;
|
||||
jsmntype_t type;
|
||||
|
||||
c = js[parser->pos];
|
||||
switch (c) {
|
||||
case '{': case '[':
|
||||
token = jsmn_alloc_token(parser, tokens, num_tokens);
|
||||
if (token == NULL)
|
||||
return JSMN_ERROR_NOMEM;
|
||||
if (parser->toksuper != -1) {
|
||||
tokens[parser->toksuper].size++;
|
||||
#ifdef JSMN_PARENT_LINKS
|
||||
token->parent = parser->toksuper;
|
||||
#endif
|
||||
}
|
||||
token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY);
|
||||
token->start = parser->pos;
|
||||
parser->toksuper = parser->toknext - 1;
|
||||
break;
|
||||
case '}': case ']':
|
||||
type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY);
|
||||
#ifdef JSMN_PARENT_LINKS
|
||||
if (parser->toknext < 1) {
|
||||
return JSMN_ERROR_INVAL;
|
||||
}
|
||||
token = &tokens[parser->toknext - 1];
|
||||
for (;;) {
|
||||
if (token->start != -1 && token->end == -1) {
|
||||
if (token->type != type) {
|
||||
return JSMN_ERROR_INVAL;
|
||||
}
|
||||
token->end = parser->pos + 1;
|
||||
parser->toksuper = token->parent;
|
||||
break;
|
||||
}
|
||||
if (token->parent == -1) {
|
||||
break;
|
||||
}
|
||||
token = &tokens[token->parent];
|
||||
}
|
||||
#else
|
||||
for (i = parser->toknext - 1; i >= 0; i--) {
|
||||
token = &tokens[i];
|
||||
if (token->start != -1 && token->end == -1) {
|
||||
if (token->type != type) {
|
||||
return JSMN_ERROR_INVAL;
|
||||
}
|
||||
parser->toksuper = -1;
|
||||
token->end = parser->pos + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Error if unmatched closing bracket */
|
||||
if (i == -1) return JSMN_ERROR_INVAL;
|
||||
for (; i >= 0; i--) {
|
||||
token = &tokens[i];
|
||||
if (token->start != -1 && token->end == -1) {
|
||||
parser->toksuper = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case '\"':
|
||||
r = jsmn_parse_string(parser, js, tokens, num_tokens);
|
||||
if (r < 0) return r;
|
||||
if (parser->toksuper != -1)
|
||||
tokens[parser->toksuper].size++;
|
||||
break;
|
||||
case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':
|
||||
break;
|
||||
#ifdef JSMN_STRICT
|
||||
/* In strict mode primitives are: numbers and booleans */
|
||||
case '-': case '0': case '1' : case '2': case '3' : case '4':
|
||||
case '5': case '6': case '7' : case '8': case '9':
|
||||
case 't': case 'f': case 'n' :
|
||||
#else
|
||||
/* In non-strict mode every unquoted value is a primitive */
|
||||
default:
|
||||
#endif
|
||||
r = jsmn_parse_primitive(parser, js, tokens, num_tokens);
|
||||
if (r < 0) return r;
|
||||
if (parser->toksuper != -1)
|
||||
tokens[parser->toksuper].size++;
|
||||
break;
|
||||
|
||||
#ifdef JSMN_STRICT
|
||||
/* Unexpected char in strict mode */
|
||||
default:
|
||||
return JSMN_ERROR_INVAL;
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (i = parser->toknext - 1; i >= 0; i--) {
|
||||
/* Unmatched opened object or array */
|
||||
if (tokens[i].start != -1 && tokens[i].end == -1) {
|
||||
return JSMN_ERROR_PART;
|
||||
}
|
||||
}
|
||||
|
||||
return JSMN_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new parser based over a given buffer with an array of tokens
|
||||
* available.
|
||||
*/
|
||||
void jsmn_init(jsmn_parser *parser) {
|
||||
parser->pos = 0;
|
||||
parser->toknext = 0;
|
||||
parser->toksuper = -1;
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
#ifndef __JSMN_H_
|
||||
#define __JSMN_H_
|
||||
|
||||
/**
|
||||
* JSON type identifier. Basic types are:
|
||||
* o Object
|
||||
* o Array
|
||||
* o String
|
||||
* o Other primitive: number, boolean (true/false) or null
|
||||
*/
|
||||
typedef enum {
|
||||
JSMN_PRIMITIVE = 0,
|
||||
JSMN_OBJECT = 1,
|
||||
JSMN_ARRAY = 2,
|
||||
JSMN_STRING = 3
|
||||
} jsmntype_t;
|
||||
|
||||
typedef enum {
|
||||
/* Not enough tokens were provided */
|
||||
JSMN_ERROR_NOMEM = -1,
|
||||
/* Invalid character inside JSON string */
|
||||
JSMN_ERROR_INVAL = -2,
|
||||
/* The string is not a full JSON packet, more bytes expected */
|
||||
JSMN_ERROR_PART = -3,
|
||||
/* Everything was fine */
|
||||
JSMN_SUCCESS = 0
|
||||
} jsmnerr_t;
|
||||
|
||||
/**
|
||||
* JSON token description.
|
||||
* @param type type (object, array, string etc.)
|
||||
* @param start start position in JSON data string
|
||||
* @param end end position in JSON data string
|
||||
*/
|
||||
typedef struct {
|
||||
jsmntype_t type;
|
||||
int start;
|
||||
int end;
|
||||
int size;
|
||||
#ifdef JSMN_PARENT_LINKS
|
||||
int parent;
|
||||
#endif
|
||||
} jsmntok_t;
|
||||
|
||||
/**
|
||||
* JSON parser. Contains an array of token blocks available. Also stores
|
||||
* the string being parsed now and current position in that string
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int pos; /* offset in the JSON string */
|
||||
int toknext; /* next token to allocate */
|
||||
int toksuper; /* superior token node, e.g parent object or array */
|
||||
} jsmn_parser;
|
||||
|
||||
/**
|
||||
* Create JSON parser over an array of tokens
|
||||
*/
|
||||
void jsmn_init(jsmn_parser *parser);
|
||||
|
||||
/**
|
||||
* Run JSON parser. It parses a JSON data string into and array of tokens, each describing
|
||||
* a single JSON object.
|
||||
*/
|
||||
jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js,
|
||||
jsmntok_t *tokens, unsigned int num_tokens);
|
||||
|
||||
#endif /* __JSMN_H_ */
|
@ -1,244 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonParser.h"
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
namespace ArduinoJsonParserTests
|
||||
{
|
||||
TEST_CLASS(GbathreeBug)
|
||||
{
|
||||
char json[1024];
|
||||
JsonParser<200> parser;
|
||||
JsonHashTable root;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD_INITIALIZE(Initialize)
|
||||
{
|
||||
// BUG described here:
|
||||
// http://forum.arduino.cc/index.php?topic=172578.msg1608219#msg1608219
|
||||
strcpy(json, "{ \"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":10000,\"actintensity1\":50,\"actintensity2\":255,\"measintensity\":255,\"calintensity\":255,\"pulses\":[50,50,50],\"act\":[2,1,2,2],\"red\":[2,2,2,2],\"detectors\":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]],\"alta\":[2,2,2,2],\"altb\":[2,2,2,2],\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}");
|
||||
root = parser.parseHashTable(json);
|
||||
}
|
||||
|
||||
TEST_METHOD(Root)
|
||||
{
|
||||
Assert::IsTrue(root.success());
|
||||
}
|
||||
|
||||
TEST_METHOD(ProtocolName)
|
||||
{
|
||||
string protocol_name = root.getString("protocol_name");
|
||||
Assert::AreEqual(string("fluorescence"), protocol_name);
|
||||
}
|
||||
|
||||
TEST_METHOD(Repeats)
|
||||
{
|
||||
Assert::AreEqual(1L, root.getLong("repeats"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Wait)
|
||||
{
|
||||
Assert::AreEqual(0L, root.getLong("wait"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Measurements)
|
||||
{
|
||||
Assert::AreEqual(3L, root.getLong("measurements"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Meas2_Light)
|
||||
{
|
||||
Assert::AreEqual(15L, root.getLong("meas2_light"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Meas1_Baseline)
|
||||
{
|
||||
Assert::AreEqual(0L, root.getLong("meas1_baseline"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Act_Light)
|
||||
{
|
||||
Assert::AreEqual(20L, root.getLong("act_light"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Pulsesize)
|
||||
{
|
||||
Assert::AreEqual(25L, root.getLong("pulsesize"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Pulsedistance)
|
||||
{
|
||||
Assert::AreEqual(10000L, root.getLong("pulsedistance"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Actintensity1)
|
||||
{
|
||||
Assert::AreEqual(50L, root.getLong("actintensity1"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Actintensity2)
|
||||
{
|
||||
Assert::AreEqual(255L, root.getLong("actintensity2"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Measintensity)
|
||||
{
|
||||
Assert::AreEqual(255L, root.getLong("measintensity"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Calintensity)
|
||||
{
|
||||
Assert::AreEqual(255L, root.getLong("calintensity"));
|
||||
}
|
||||
|
||||
TEST_METHOD(Pulses)
|
||||
{
|
||||
// "pulses":[50,50,50]
|
||||
|
||||
JsonArray array = root.getArray("pulses");
|
||||
Assert::IsTrue(array.success());
|
||||
|
||||
Assert::AreEqual(3, array.getLength());
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
Assert::AreEqual(50L, array.getLong(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Act)
|
||||
{
|
||||
// "act":[2,1,2,2]
|
||||
|
||||
JsonArray array = root.getArray("act");
|
||||
Assert::IsTrue(array.success());
|
||||
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
Assert::AreEqual(2L, array.getLong(0));
|
||||
Assert::AreEqual(1L, array.getLong(1));
|
||||
Assert::AreEqual(2L, array.getLong(2));
|
||||
Assert::AreEqual(2L, array.getLong(3));
|
||||
}
|
||||
|
||||
TEST_METHOD(Detectors)
|
||||
{
|
||||
// "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]]
|
||||
|
||||
JsonArray array = root.getArray("detectors");
|
||||
Assert::IsTrue(array.success());
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert::AreEqual(4, array.getArray(i).getLength());
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
Assert::AreEqual(34L, array.getArray(i).getLong(j));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Alta)
|
||||
{
|
||||
// alta:[2,2,2,2]
|
||||
|
||||
JsonArray array = root.getArray("alta");
|
||||
Assert::IsTrue(array.success());
|
||||
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert::AreEqual(2L, array.getLong(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Altb)
|
||||
{
|
||||
// altb:[2,2,2,2]
|
||||
|
||||
JsonArray array = root.getArray("altb");
|
||||
Assert::IsTrue(array.success());
|
||||
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert::AreEqual(2L, array.getLong(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Measlights)
|
||||
{
|
||||
// "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
|
||||
|
||||
JsonArray array = root.getArray("measlights");
|
||||
Assert::IsTrue(array.success());
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert::AreEqual(4, array.getArray(i).getLength());
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
Assert::AreEqual(15L, array.getArray(i).getLong(j));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Measlights2)
|
||||
{
|
||||
// "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]]
|
||||
|
||||
JsonArray array = root.getArray("measlights2");
|
||||
Assert::IsTrue(array.success());
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert::AreEqual(4, array.getArray(i).getLength());
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
Assert::AreEqual(15L, array.getArray(i).getLong(j));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Altc)
|
||||
{
|
||||
// altc:[2,2,2,2]
|
||||
|
||||
JsonArray array = root.getArray("altc");
|
||||
Assert::IsTrue(array.success());
|
||||
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert::AreEqual(2L, array.getLong(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(Altd)
|
||||
{
|
||||
// altd:[2,2,2,2]
|
||||
|
||||
JsonArray array = root.getArray("altd");
|
||||
Assert::IsTrue(array.success());
|
||||
|
||||
Assert::AreEqual(4, array.getLength());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Assert::AreEqual(2L, array.getLong(i));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonParser.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
namespace JsonParserTests
|
||||
{
|
||||
TEST_CLASS(JsonArrayIteratorTests)
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(EmptyJson)
|
||||
{
|
||||
char json[] = "";
|
||||
JsonParser<1> parser;
|
||||
|
||||
JsonArray a = parser.parse(json);
|
||||
|
||||
int loopCount = 0;
|
||||
|
||||
for (long i : a)
|
||||
{
|
||||
loopCount++;
|
||||
}
|
||||
|
||||
Assert::AreEqual(0, loopCount);
|
||||
}
|
||||
|
||||
TEST_METHOD(ThreeIntegers)
|
||||
{
|
||||
char json [] = "[1,2,3]";
|
||||
long expected [] = {1, 2, 3};
|
||||
JsonParser<4> parser;
|
||||
|
||||
JsonArray a = parser.parse(json);
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (long i : a)
|
||||
{
|
||||
Assert::AreEqual(expected[index++], i);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(ThreeStrings)
|
||||
{
|
||||
char json[] = "[\"1\",\"2\",\"3\"]";
|
||||
char* expected[] = {"1", "2", "3"};
|
||||
JsonParser<4> parser;
|
||||
|
||||
JsonArray a = parser.parse(json);
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (const char* i : a)
|
||||
{
|
||||
Assert::AreEqual(expected[index++], i);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonParser.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
namespace ArduinoJsonParserTests
|
||||
{
|
||||
TEST_CLASS(JsonArrayTests)
|
||||
{
|
||||
JsonArray array;
|
||||
char json[256];
|
||||
jsmntok_t tokens[32];
|
||||
JsonParserBase parser = JsonParserBase(tokens, 32);
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(EmptyString)
|
||||
{
|
||||
whenInputIs("");
|
||||
parseMustFail();
|
||||
}
|
||||
|
||||
TEST_METHOD(TooFewClosingBrackets)
|
||||
{
|
||||
whenInputIs("[[]");
|
||||
parseMustFail();
|
||||
}
|
||||
|
||||
TEST_METHOD(TooManyClosingBrackets)
|
||||
{
|
||||
whenInputIs("[]]");
|
||||
parseMustFail();
|
||||
}
|
||||
|
||||
TEST_METHOD(EmptyArray)
|
||||
{
|
||||
whenInputIs("[]");
|
||||
parseMustSucceed();
|
||||
lengthMustBe(0);
|
||||
}
|
||||
|
||||
TEST_METHOD(NotEnoughTokens)
|
||||
{
|
||||
setTokenCountTo(2);
|
||||
|
||||
whenInputIs("[1,2]");
|
||||
|
||||
parseMustFail();
|
||||
itemMustNotExist(0);
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoIntegers)
|
||||
{
|
||||
setTokenCountTo(3);
|
||||
|
||||
whenInputIs("[1,2]");
|
||||
|
||||
parseMustSucceed();
|
||||
lengthMustBe(2);
|
||||
itemMustBe(0, 1L);
|
||||
itemMustBe(1, 2L);
|
||||
itemMustNotExist(2);
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoBooleans)
|
||||
{
|
||||
setTokenCountTo(3);
|
||||
|
||||
whenInputIs("[true,false]");
|
||||
|
||||
parseMustSucceed();
|
||||
lengthMustBe(2);
|
||||
itemMustBe(0, true);
|
||||
itemMustBe(1, false);
|
||||
itemMustNotExist(2);
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
setTokenCountTo(3);
|
||||
|
||||
whenInputIs("[\"hello\",\"world\"]");
|
||||
|
||||
parseMustSucceed();
|
||||
lengthMustBe(2);
|
||||
itemMustBe(0, "hello");
|
||||
itemMustBe(1, "world");
|
||||
itemMustNotExist(2);
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoDimensionsArray)
|
||||
{
|
||||
setTokenCountTo(7);
|
||||
|
||||
whenInputIs("[[1,2],[3,4]]");
|
||||
|
||||
parseMustSucceed();
|
||||
lengthMustBe(2);
|
||||
itemMustBe(0, 0, 1L);
|
||||
itemMustBe(0, 1, 2L);
|
||||
itemMustBe(1, 0, 3L);
|
||||
itemMustBe(1, 1, 4L);
|
||||
itemMustNotExist(2);
|
||||
}
|
||||
|
||||
TEST_METHOD(ThreeDimensionsArray)
|
||||
{
|
||||
setTokenCountTo(15);
|
||||
|
||||
whenInputIs("[[[1,2],[3,4]],[[5,6],[7,8]]]");
|
||||
|
||||
parseMustSucceed();
|
||||
lengthMustBe(2);
|
||||
itemMustBe(0, 0, 0, 1L);
|
||||
itemMustBe(0, 0, 1, 2L);
|
||||
itemMustBe(0, 1, 0, 3L);
|
||||
itemMustBe(0, 1, 1, 4L);
|
||||
itemMustBe(1, 0, 0, 5L);
|
||||
itemMustBe(1, 0, 1, 6L);
|
||||
itemMustBe(1, 1, 0, 7L);
|
||||
itemMustBe(1, 1, 1, 8L);
|
||||
itemMustNotExist(2);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void setTokenCountTo(int n)
|
||||
{
|
||||
parser = JsonParserBase(tokens, n);
|
||||
}
|
||||
|
||||
void whenInputIs(const char* input)
|
||||
{
|
||||
strcpy(json, input);
|
||||
array = parser.parseArray(json);
|
||||
}
|
||||
|
||||
void parseMustFail()
|
||||
{
|
||||
Assert::IsFalse(array.success());
|
||||
lengthMustBe(0);
|
||||
}
|
||||
|
||||
void parseMustSucceed()
|
||||
{
|
||||
Assert::IsTrue(array.success());
|
||||
}
|
||||
|
||||
void lengthMustBe(int expected)
|
||||
{
|
||||
Assert::AreEqual(expected, array.getLength());
|
||||
}
|
||||
|
||||
void itemMustBe(int index, long expected)
|
||||
{
|
||||
Assert::AreEqual(expected, array.getLong(index));
|
||||
}
|
||||
|
||||
void itemMustBe(int index, bool expected)
|
||||
{
|
||||
Assert::AreEqual(expected, array.getBool(index));
|
||||
}
|
||||
|
||||
void itemMustBe(int index, const char* expected)
|
||||
{
|
||||
Assert::AreEqual(expected, array.getString(index));
|
||||
}
|
||||
|
||||
void itemMustBe(int index0, int index1, long expected)
|
||||
{
|
||||
Assert::AreEqual(expected, array.getArray(index0).getLong(index1));
|
||||
}
|
||||
|
||||
void itemMustBe(int index0, int index1, int index2, long expected)
|
||||
{
|
||||
Assert::AreEqual(expected, array.getArray(index0).getArray(index1).getLong(index2));
|
||||
}
|
||||
|
||||
void itemMustNotExist(int index)
|
||||
{
|
||||
Assert::IsFalse(array.getHashTable(index).success());
|
||||
Assert::IsFalse(array.getArray(index).success());
|
||||
Assert::IsFalse(array.getBool(index));
|
||||
Assert::AreEqual(0.0, array.getDouble(index));
|
||||
Assert::AreEqual(0L, array.getLong(index));
|
||||
Assert::IsNull(array.getString(index));
|
||||
}
|
||||
};
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonParser.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
namespace JsonParserTests
|
||||
{
|
||||
TEST_CLASS(JsonObjectIteratorTests)
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(EmptyObject)
|
||||
{
|
||||
char json [] = "{}";
|
||||
JsonParser<1> parser;
|
||||
|
||||
JsonHashTable a = parser.parse(json);
|
||||
|
||||
int loopCount = 0;
|
||||
|
||||
for (auto i : a)
|
||||
{
|
||||
loopCount++;
|
||||
}
|
||||
|
||||
Assert::AreEqual(0, loopCount);
|
||||
}
|
||||
|
||||
TEST_METHOD(EmptyJson)
|
||||
{
|
||||
char json[] = "";
|
||||
JsonParser<1> parser;
|
||||
|
||||
JsonHashTable a = parser.parse(json);
|
||||
|
||||
int loopCount = 0;
|
||||
|
||||
for (auto i : a)
|
||||
{
|
||||
loopCount++;
|
||||
}
|
||||
|
||||
Assert::AreEqual(0, loopCount);
|
||||
}
|
||||
|
||||
TEST_METHOD(ThreeStrings)
|
||||
{
|
||||
char json[] = "{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}";
|
||||
char* expectedKeys[] = {"key1", "key2", "key3"};
|
||||
char* expectedValues[] = {"value1", "value2", "value3"};
|
||||
JsonParser<7> parser;
|
||||
|
||||
JsonHashTable a = parser.parse(json);
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (auto i : a)
|
||||
{
|
||||
Assert::AreEqual(expectedKeys[index], i.key());
|
||||
Assert::AreEqual(expectedValues[index], (const char*) i.value());
|
||||
index++;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -1,171 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonParser.h"
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
namespace ArduinoJsonParserTests
|
||||
{
|
||||
TEST_CLASS(JsonHashTableTests)
|
||||
{
|
||||
JsonHashTable hashTable;
|
||||
JsonArray nestedArray;
|
||||
char json[256];
|
||||
jsmntok_t tokens[32];
|
||||
JsonParserBase parser = JsonParserBase(tokens, 32);
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(EmptyString)
|
||||
{
|
||||
whenInputIs("");
|
||||
parseMustFail();
|
||||
}
|
||||
|
||||
TEST_METHOD(EmptyHashTable)
|
||||
{
|
||||
whenInputIs("{}");
|
||||
parseMustSucceed();
|
||||
}
|
||||
|
||||
TEST_METHOD(NotEnoughTokens)
|
||||
{
|
||||
setTokenCountTo(2);
|
||||
|
||||
whenInputIs("{\"key\":0}");
|
||||
|
||||
parseMustFail();
|
||||
itemMustNotExist("key");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoIntegers)
|
||||
{
|
||||
setTokenCountTo(5);
|
||||
|
||||
whenInputIs("{\"key1\":1,\"key2\":2}");
|
||||
|
||||
parseMustSucceed();
|
||||
itemMustBe("key1", 1L);
|
||||
itemMustBe("key2", 2L);
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoBooleans)
|
||||
{
|
||||
setTokenCountTo(5);
|
||||
|
||||
whenInputIs("{\"key1\":true,\"key2\":false}");
|
||||
|
||||
parseMustSucceed();
|
||||
itemMustBe("key1", true);
|
||||
itemMustBe("key2", false);
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
setTokenCountTo(5);
|
||||
|
||||
whenInputIs("{\"key1\":\"hello\",\"key2\":\"world\"}");
|
||||
|
||||
parseMustSucceed();
|
||||
itemMustBe("key1", "hello");
|
||||
itemMustBe("key2", "world");
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoNestedArrays)
|
||||
{
|
||||
setTokenCountTo(9);
|
||||
|
||||
whenInputIs("{\"key1\":[1,2],\"key2\":[3,4]}");
|
||||
parseMustSucceed();
|
||||
|
||||
itemMustBeAnArray("key1");
|
||||
arrayLengthMustBe(2);
|
||||
arrayItemMustBe(0, 1L);
|
||||
arrayItemMustBe(1, 2L);
|
||||
arrayItemMustBe(2, 0L);
|
||||
|
||||
itemMustBeAnArray("key2");
|
||||
arrayLengthMustBe(2);
|
||||
arrayItemMustBe(0, 3L);
|
||||
arrayItemMustBe(1, 4L);
|
||||
arrayItemMustBe(2, 0L);
|
||||
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void setTokenCountTo(int n)
|
||||
{
|
||||
parser = JsonParserBase(tokens, n);
|
||||
}
|
||||
|
||||
void whenInputIs(const char* input)
|
||||
{
|
||||
strcpy(json, input);
|
||||
hashTable = parser.parseHashTable(json);
|
||||
}
|
||||
|
||||
void parseMustFail()
|
||||
{
|
||||
Assert::IsFalse(hashTable.success());
|
||||
}
|
||||
|
||||
void parseMustSucceed()
|
||||
{
|
||||
Assert::IsTrue(hashTable.success());
|
||||
}
|
||||
|
||||
void itemMustBe(const char* key, long expected)
|
||||
{
|
||||
Assert::AreEqual(expected, hashTable.getLong(key));
|
||||
}
|
||||
|
||||
void itemMustBe(const char* key, bool expected)
|
||||
{
|
||||
Assert::AreEqual(expected, hashTable.getBool(key));
|
||||
}
|
||||
|
||||
void itemMustBe(const char* key, const char* expected)
|
||||
{
|
||||
Assert::AreEqual(expected, hashTable.getString(key));
|
||||
}
|
||||
|
||||
void itemMustNotExist(const char* key)
|
||||
{
|
||||
Assert::IsFalse(hashTable.containsKey(key));
|
||||
Assert::IsFalse(hashTable.getHashTable(key).success());
|
||||
Assert::IsFalse(hashTable.getArray(key).success());
|
||||
Assert::IsFalse(hashTable.getBool(key));
|
||||
Assert::AreEqual(0.0, hashTable.getDouble(key));
|
||||
Assert::AreEqual(0L, hashTable.getLong(key));
|
||||
Assert::IsNull(hashTable.getString(key));
|
||||
}
|
||||
|
||||
void itemMustBeAnArray(const char* key)
|
||||
{
|
||||
nestedArray = hashTable.getArray(key);
|
||||
Assert::IsTrue(nestedArray.success());
|
||||
}
|
||||
|
||||
void arrayLengthMustBe(int expected)
|
||||
{
|
||||
Assert::AreEqual(expected, nestedArray.getLength());
|
||||
}
|
||||
|
||||
void arrayItemMustBe(int index, long expected)
|
||||
{
|
||||
Assert::AreEqual(expected, nestedArray.getLong(index));
|
||||
}
|
||||
};
|
||||
}
|
@ -1,102 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4DD596EF-0185-4AB4-A3C2-F20C496F7806}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>ArduinoJsonParserTests</RootNamespace>
|
||||
<ProjectName>JsonParserTests</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v120</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>$(VC_IncludePath);..</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ARDUINO_JSON_NO_DEPRECATION_WARNING;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="JsonObjectIteratorTests.cpp" />
|
||||
<ClCompile Include="JsonArrayTests.cpp" />
|
||||
<ClCompile Include="JsonArrayIteratorTests.cpp" />
|
||||
<ClCompile Include="JsonObjectTests.cpp" />
|
||||
<ClCompile Include="GbathreeBug.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\JsonParser\JsonParser.vcxproj">
|
||||
<Project>{c15274de-2695-4dfe-8520-4424223fe6da}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,34 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="JsonArrayTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GbathreeBug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonObjectTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonArrayIteratorTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonObjectIteratorTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,25 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "CppUnitTest.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
|
||||
namespace ArduinoJsonParserTests
|
||||
{
|
||||
TEST_CLASS(TestHashGenerator)
|
||||
{
|
||||
public:
|
||||
|
||||
TEST_METHOD(TestMethod1)
|
||||
{
|
||||
JsonArray<5> arr;
|
||||
arr.Add(1);
|
||||
arr.Add("Hi!");
|
||||
|
||||
JsonHashTable<4> hash;
|
||||
hash.Add("key1", 1);
|
||||
hash.Add("key2", "Hello!");
|
||||
hash.Add("key3", arr);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
10
LICENSE.md
Normal file
10
LICENSE.md
Normal file
@ -0,0 +1,10 @@
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright © 2014 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.
|
67
README.md
67
README.md
@ -1,6 +1,8 @@
|
||||
Arduino JSON library
|
||||
====================
|
||||
|
||||
[](https://travis-ci.org/bblanchon/ArduinoJson) [](https://coveralls.io/r/bblanchon/ArduinoJson?branch=master)
|
||||
|
||||
*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).
|
||||
@ -10,37 +12,56 @@ It has been written with Arduino in mind, but it isn't linked to Arduino librari
|
||||
Features
|
||||
--------
|
||||
|
||||
* JSON decoding: [more details here](/JsonParser/)
|
||||
* JSON encoding: [more details here](/JsonGenerator/)
|
||||
* JSON decoding
|
||||
* JSON encoding (with optional indentation)
|
||||
* Elegant API, very easy to use
|
||||
* Fixed memory allocation (no malloc)
|
||||
* Small footprint
|
||||
* MIT License
|
||||
|
||||
Feature comparison
|
||||
------------------
|
||||
Quick start
|
||||
-----------
|
||||
|
||||
| Library | Memory allocation | Nested objects | Parser size | Encoder size |
|
||||
| ------------ | ----------------- | -------------- | ----------- | ------------- |
|
||||
| Arduino JSON | static | yes | 2642 Bytes | 862 bytes |
|
||||
| json-arduino | dynamic | no | 3348 (+27%) | not supported |
|
||||
| aJson | dynamic | yes | 5088 (+93%) | 4678 (+540%) |
|
||||
#### Decoding / Parsing
|
||||
|
||||
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
|
||||
"Parser size" was measured with a program parsing `{"sensor":"outdoor","value":25.6}`.
|
||||
For each library, I wrote a program that extracts a string and a float. I subtracted the size of a program doing the same without any JSON parsing involved. [Source files are here](https://gist.github.com/bblanchon/e8ba914a7109f3642c0f).
|
||||
StaticJsonBuffer<200> jsonBuffer;
|
||||
|
||||
"Encoder size" was measured with a program generating `{"sensor":"outdoor","value":25.6}`.
|
||||
[Source files are here](https://gist.github.com/bblanchon/60224e9dcfeab4ddc7e9).
|
||||
JsonObject& root = jsonBuffer.parseObject(json);
|
||||
|
||||
In each case the target platform was an Arduino Duemilanove and Arduino IDE 1.0.5 was used.
|
||||
const char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
Links: [json-arduino](https://github.com/not404/json-arduino), [aJson](https://github.com/interactive-matter/aJson)
|
||||
#### Encoding / Generating
|
||||
|
||||
StaticJsonBuffer<200> jsonBuffer;
|
||||
|
||||
JsonObject& root = jsonBuffer.createObject();
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
|
||||
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)
|
||||
|
||||
Testimonials
|
||||
------------
|
||||
|
||||
From Arduino's Forum user `jflaplante`:
|
||||
> I tried the [aJson and 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`:
|
||||
@ -49,10 +70,12 @@ From Arduino's Forum user `gbathree`:
|
||||
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.
|
||||
|
||||
Related blog posts
|
||||
-----
|
||||
From GitHub user `zacsketches`:
|
||||
|
||||
* [The project I originally wrote this library for](http://blog.benoitblanchon.fr/rfid-payment-terminal/)
|
||||
* [Motivation for this library](http://blog.benoitblanchon.fr/arduino-json-parser/)
|
||||
* [Release of version 2](http://blog.benoitblanchon.fr/arduino-json-v2-0/)
|
||||
* [Release of version 3](http://blog.benoitblanchon.fr/arduino-json-v3-0/)
|
||||
> 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!!
|
||||
|
||||
---
|
||||
|
||||
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¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :smile:
|
30
examples/IndentedPrintExample/IndentedPrintExample.ino
Normal file
30
examples/IndentedPrintExample/IndentedPrintExample.ino
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Arduino JSON library - IndentedPrint example
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
IndentedPrint serial(Serial);
|
||||
serial.setTabSize(4);
|
||||
|
||||
serial.println("This is at indentation 0");
|
||||
serial.indent();
|
||||
serial.println("This is at indentation 1");
|
||||
serial.println("This is also at indentation 1");
|
||||
serial.indent();
|
||||
serial.println("This is at indentation 2");
|
||||
|
||||
serial.unindent();
|
||||
serial.unindent();
|
||||
serial.println("This is back at indentation 0");
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
@ -1,29 +1,42 @@
|
||||
/*
|
||||
* Arduino JSON library - Generator example
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
// Copyright Benoit Blanchon 2014
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#include <JsonGenerator.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
StaticJsonBuffer<200> jsonBuffer;
|
||||
|
||||
JsonArray<2> array;
|
||||
array.add<6>(48.756080); // 6 is the number of decimals to print
|
||||
array.add<6>(2.302038); // if not specified, 2 digits are printed
|
||||
JsonObject& root = jsonBuffer.createObject();
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
|
||||
JsonObject<3> root;
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
root["data"] = array;
|
||||
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
|
||||
|
||||
Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
root.printTo(Serial);
|
||||
// This prints:
|
||||
// {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
|
||||
Serial.println();
|
||||
|
||||
root.prettyPrintTo(Serial);
|
||||
// This prints:
|
||||
// {
|
||||
// "sensor": "gps",
|
||||
// "time": 1351824120,
|
||||
// "data": [
|
||||
// 48.756080,
|
||||
// 2.302038
|
||||
// ]
|
||||
// }
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
@ -1,40 +1,37 @@
|
||||
/*
|
||||
* Arduino JSON library - Parser Example
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
// Copyright Benoit Blanchon 2014
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#include <JsonParser.h>
|
||||
#include <ArduinoJson.h>
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
void setup() {
|
||||
Serial.begin(9600);
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
StaticJsonBuffer<200> jsonBuffer;
|
||||
|
||||
char json [] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
char json[] =
|
||||
"{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
|
||||
JsonParser<16> parser;
|
||||
JsonObject& root = jsonBuffer.parseObject(json);
|
||||
|
||||
JsonObject root = parser.parse(json);
|
||||
if (!root.success()) {
|
||||
Serial.println("parseObject() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!root.success())
|
||||
{
|
||||
Serial.println("JsonParser.parse() failed");
|
||||
return;
|
||||
}
|
||||
const char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
Serial.println(sensor);
|
||||
Serial.println(time);
|
||||
Serial.println(latitude, 6);
|
||||
Serial.println(longitude, 6);
|
||||
Serial.println(sensor);
|
||||
Serial.println(time);
|
||||
Serial.println(latitude, 6);
|
||||
Serial.println(longitude, 6);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
|
||||
void loop() {
|
||||
// not used in this example
|
||||
}
|
74
examples/JsonServer/JsonServer.ino
Normal file
74
examples/JsonServer/JsonServer.ino
Normal 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();
|
||||
}
|
||||
}
|
12
include/ArduinoJson.h
Normal file
12
include/ArduinoJson.h
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright Benoit Blanchon 2014
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#include "../include/ArduinoJson/DynamicJsonBuffer.hpp"
|
||||
#include "../include/ArduinoJson/JsonArray.hpp"
|
||||
#include "../include/ArduinoJson/JsonObject.hpp"
|
||||
#include "../include/ArduinoJson/StaticJsonBuffer.hpp"
|
||||
|
||||
using namespace ArduinoJson;
|
31
include/ArduinoJson/Arduino/Print.hpp
Normal file
31
include/ArduinoJson/Arduino/Print.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// 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
|
67
include/ArduinoJson/DynamicJsonBuffer.hpp
Normal file
67
include/ArduinoJson/DynamicJsonBuffer.hpp
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonBuffer.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];
|
||||
};
|
||||
}
|
54
include/ArduinoJson/Internals/IndentedPrint.hpp
Normal file
54
include/ArduinoJson/Internals/IndentedPrint.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Decorator on top of Print to allow indented output.
|
||||
// This class is used by JsonPrintable::prettyPrintTo() but can also be used
|
||||
// for your own purpose, like logging.
|
||||
class IndentedPrint : public Print {
|
||||
public:
|
||||
explicit IndentedPrint(Print &p) : sink(&p) {
|
||||
level = 0;
|
||||
tabSize = 2;
|
||||
isNewLine = true;
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t);
|
||||
|
||||
// Adds one level of indentation
|
||||
void indent() {
|
||||
if (level < MAX_LEVEL) level++;
|
||||
}
|
||||
|
||||
// Removes one level of indentation
|
||||
void unindent() {
|
||||
if (level > 0) level--;
|
||||
}
|
||||
|
||||
// Set the number of space printed for each level of indentation
|
||||
void setTabSize(uint8_t n) {
|
||||
if (n < MAX_TAB_SIZE) tabSize = n & MAX_TAB_SIZE;
|
||||
}
|
||||
|
||||
private:
|
||||
Print *sink;
|
||||
uint8_t level : 4;
|
||||
uint8_t tabSize : 3;
|
||||
bool isNewLine : 1;
|
||||
|
||||
size_t writeTabs();
|
||||
|
||||
static const int MAX_LEVEL = 15; // because it's only 4 bits
|
||||
static const int MAX_TAB_SIZE = 7; // because it's only 3 bits
|
||||
};
|
||||
}
|
||||
}
|
23
include/ArduinoJson/Internals/JsonBufferAllocated.hpp
Normal file
23
include/ArduinoJson/Internals/JsonBufferAllocated.hpp
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
class JsonBufferAllocated {
|
||||
public:
|
||||
void *operator new(size_t n, JsonBuffer *jsonBuffer) throw() {
|
||||
return jsonBuffer->alloc(n);
|
||||
}
|
||||
|
||||
void operator delete(void *, JsonBuffer *) throw() {}
|
||||
};
|
||||
}
|
||||
}
|
42
include/ArduinoJson/Internals/JsonParser.hpp
Normal file
42
include/ArduinoJson/Internals/JsonParser.hpp
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "../JsonVariant.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Parse JSON string to create JsonArrays and JsonObjects
|
||||
// This internal class is not indended to be used directly.
|
||||
// Instead, use JsonBuffer.parseArray() or .parseObject()
|
||||
class JsonParser {
|
||||
public:
|
||||
JsonParser(JsonBuffer *buffer, char *json, uint8_t nestingLimit)
|
||||
: _buffer(buffer), _ptr(json), _nestingLimit(nestingLimit) {}
|
||||
|
||||
JsonArray &parseArray();
|
||||
JsonObject &parseObject();
|
||||
|
||||
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();
|
||||
|
||||
JsonBuffer *_buffer;
|
||||
char *_ptr;
|
||||
uint8_t _nestingLimit;
|
||||
};
|
||||
}
|
||||
}
|
54
include/ArduinoJson/Internals/JsonPrintable.hpp
Normal file
54
include/ArduinoJson/Internals/JsonPrintable.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IndentedPrint.hpp"
|
||||
#include "JsonWriter.hpp"
|
||||
#include "Prettyfier.hpp"
|
||||
#include "StringBuilder.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Implements all the overloads of printTo() and prettyPrintTo()
|
||||
// Caution: this class use a template parameter to avoid virtual methods.
|
||||
// This is a bit curious but allows to reduce the size of JsonVariant, JsonArray
|
||||
// and JsonObject.
|
||||
template <typename T>
|
||||
class JsonPrintable {
|
||||
public:
|
||||
size_t printTo(Print &print) const {
|
||||
JsonWriter writer(print);
|
||||
downcast().writeTo(writer);
|
||||
return writer.bytesWritten();
|
||||
}
|
||||
|
||||
size_t printTo(char *buffer, size_t bufferSize) const {
|
||||
StringBuilder sb(buffer, bufferSize);
|
||||
return printTo(sb);
|
||||
}
|
||||
|
||||
size_t prettyPrintTo(IndentedPrint &print) const {
|
||||
Prettyfier p(print);
|
||||
return printTo(p);
|
||||
}
|
||||
|
||||
size_t prettyPrintTo(char *buffer, size_t bufferSize) const {
|
||||
StringBuilder sb(buffer, bufferSize);
|
||||
return prettyPrintTo(sb);
|
||||
}
|
||||
|
||||
size_t prettyPrintTo(Print &print) const {
|
||||
IndentedPrint indentedPrint = IndentedPrint(print);
|
||||
return prettyPrintTo(indentedPrint);
|
||||
}
|
||||
|
||||
private:
|
||||
const T &downcast() const { return *static_cast<const T *>(this); }
|
||||
};
|
||||
}
|
||||
}
|
28
include/ArduinoJson/Internals/JsonVariantContent.hpp
Normal file
28
include/ArduinoJson/Internals/JsonVariantContent.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// Forward declarations
|
||||
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
|
||||
const char* asString; // asString can be null
|
||||
JsonArray* asArray; // asArray cannot be null
|
||||
JsonObject* asObject; // asObject cannot be null
|
||||
};
|
||||
}
|
||||
}
|
33
include/ArduinoJson/Internals/JsonVariantType.hpp
Normal file
33
include/ArduinoJson/Internals/JsonVariantType.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
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
|
||||
|
||||
// The following values are reserved for double 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
|
||||
// ...
|
||||
};
|
||||
}
|
||||
}
|
64
include/ArduinoJson/Internals/JsonWriter.hpp
Normal file
64
include/ArduinoJson/Internals/JsonWriter.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../Arduino/Print.hpp"
|
||||
#include "QuotedString.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Writes the JSON tokens to a Print implementation
|
||||
// This class is used by:
|
||||
// - JsonArray::writeTo()
|
||||
// - JsonObject::writeTo()
|
||||
// - JsonVariant::writeTo()
|
||||
// Its derived by PrettyJsonWriter that overrides some members to add
|
||||
// indentation.
|
||||
class JsonWriter {
|
||||
public:
|
||||
explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
|
||||
|
||||
// Returns the number of bytes sent to the Print implementation.
|
||||
// This is very handy for implementations of printTo() that must return the
|
||||
// number of bytes written.
|
||||
size_t bytesWritten() { 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);
|
||||
}
|
||||
|
||||
void writeLong(long value) { _length += _sink.print(value); }
|
||||
|
||||
void writeBoolean(bool value) {
|
||||
_length += _sink.print(value ? "true" : "false");
|
||||
}
|
||||
void writeDouble(double value, uint8_t decimals) {
|
||||
_length += _sink.print(value, decimals);
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
72
include/ArduinoJson/Internals/List.hpp
Normal file
72
include/ArduinoJson/Internals/List.hpp
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../JsonBuffer.hpp"
|
||||
#include "ListConstIterator.hpp"
|
||||
#include "ListIterator.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A singly linked list of T.
|
||||
// The linked list is composed of ListNode<T>.
|
||||
// It is derived by JsonArray and JsonObject
|
||||
template <typename T>
|
||||
class List {
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef ListNode<T> node_type;
|
||||
typedef ListIterator<T> iterator;
|
||||
typedef ListConstIterator<T> const_iterator;
|
||||
|
||||
// Creates an empty List<T> attached to a JsonBuffer.
|
||||
// The JsonBuffer allows to allocate new nodes.
|
||||
// When buffer is NULL, the List is not able to grow and success() returns
|
||||
// false. This is used to identify bad memory allocations and parsing
|
||||
// failures.
|
||||
explicit List(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {}
|
||||
|
||||
// Returns true if the object is valid
|
||||
// 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; }
|
||||
|
||||
// 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;
|
||||
return new (_buffer) node_type();
|
||||
}
|
||||
|
||||
void addNode(node_type *nodeToAdd) {
|
||||
if (_firstNode) {
|
||||
node_type *lastNode = _firstNode;
|
||||
while (lastNode->next) lastNode = lastNode->next;
|
||||
lastNode->next = nodeToAdd;
|
||||
} else {
|
||||
_firstNode = nodeToAdd;
|
||||
}
|
||||
}
|
||||
|
||||
void removeNode(node_type *nodeToRemove);
|
||||
|
||||
JsonBuffer *_buffer;
|
||||
node_type *_firstNode;
|
||||
};
|
||||
}
|
||||
}
|
40
include/ArduinoJson/Internals/ListConstIterator.hpp
Normal file
40
include/ArduinoJson/Internals/ListConstIterator.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ListNode.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A read-only forward itertor for List<T>
|
||||
template <typename T>
|
||||
class ListConstIterator {
|
||||
public:
|
||||
explicit ListConstIterator(const ListNode<T> *node = NULL) : _node(node) {}
|
||||
|
||||
const T &operator*() const { return _node->content; }
|
||||
const T *operator->() { return &_node->content; }
|
||||
|
||||
bool operator==(const ListConstIterator<T> &other) const {
|
||||
return _node == other._node;
|
||||
}
|
||||
|
||||
bool operator!=(const ListConstIterator<T> &other) const {
|
||||
return _node != other._node;
|
||||
}
|
||||
|
||||
ListConstIterator<T> &operator++() {
|
||||
if (_node) _node = _node->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
const ListNode<T> *_node;
|
||||
};
|
||||
}
|
||||
}
|
43
include/ArduinoJson/Internals/ListIterator.hpp
Normal file
43
include/ArduinoJson/Internals/ListIterator.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ListNode.hpp"
|
||||
#include "ListConstIterator.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A read-write forward iterator for List<T>
|
||||
template <typename T>
|
||||
class ListIterator {
|
||||
public:
|
||||
explicit ListIterator(ListNode<T> *node = NULL) : _node(node) {}
|
||||
|
||||
T &operator*() const { return _node->content; }
|
||||
T *operator->() { return &_node->content; }
|
||||
|
||||
bool operator==(const ListIterator<T> &other) const {
|
||||
return _node == other._node;
|
||||
}
|
||||
|
||||
bool operator!=(const ListIterator<T> &other) const {
|
||||
return _node != other._node;
|
||||
}
|
||||
|
||||
ListIterator<T> &operator++() {
|
||||
if (_node) _node = _node->next;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator ListConstIterator<T>() const { return ListConstIterator<T>(_node); }
|
||||
|
||||
private:
|
||||
ListNode<T> *_node;
|
||||
};
|
||||
}
|
||||
}
|
26
include/ArduinoJson/Internals/ListNode.hpp
Normal file
26
include/ArduinoJson/Internals/ListNode.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#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 : public Internals::JsonBufferAllocated {
|
||||
ListNode() : next(NULL) {}
|
||||
|
||||
ListNode<T> *next;
|
||||
T content;
|
||||
};
|
||||
}
|
||||
}
|
46
include/ArduinoJson/Internals/Prettyfier.hpp
Normal file
46
include/ArduinoJson/Internals/Prettyfier.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IndentedPrint.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// Converts a compact JSON string into an indented one.
|
||||
class Prettyfier : public Print {
|
||||
public:
|
||||
explicit Prettyfier(IndentedPrint& p) : _sink(p) {
|
||||
_previousChar = 0;
|
||||
_inString = false;
|
||||
}
|
||||
|
||||
virtual size_t write(uint8_t);
|
||||
|
||||
private:
|
||||
Prettyfier& operator=(const Prettyfier&); // cannot be assigned
|
||||
|
||||
bool inEmptyBlock() { return _previousChar == '{' || _previousChar == '['; }
|
||||
|
||||
size_t handleStringChar(uint8_t);
|
||||
size_t handleMarkupChar(uint8_t);
|
||||
|
||||
size_t handleBlockClose(uint8_t);
|
||||
size_t handleBlockOpen(uint8_t);
|
||||
size_t handleColumn();
|
||||
size_t handleComma();
|
||||
size_t handleQuoteOpen();
|
||||
size_t handleNormalChar(uint8_t);
|
||||
size_t indentIfNeeded();
|
||||
size_t unindentIfNeeded();
|
||||
|
||||
uint8_t _previousChar;
|
||||
IndentedPrint& _sink;
|
||||
bool _inString;
|
||||
};
|
||||
}
|
||||
}
|
29
include/ArduinoJson/Internals/QuotedString.hpp
Normal file
29
include/ArduinoJson/Internals/QuotedString.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// 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);
|
||||
};
|
||||
}
|
||||
}
|
34
include/ArduinoJson/Internals/ReferenceType.hpp
Normal file
34
include/ArduinoJson/Internals/ReferenceType.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
// A type that is meant to be used by reference only (JsonArray and JsonObject)
|
||||
class ReferenceType {
|
||||
public:
|
||||
bool operator==(const ReferenceType& other) const {
|
||||
// two JsonArray are equal if they are the same instance
|
||||
// (we don't compare the content)
|
||||
return this == &other;
|
||||
}
|
||||
|
||||
bool operator!=(const ReferenceType& other) const { return this != &other; }
|
||||
|
||||
protected:
|
||||
ReferenceType() {}
|
||||
|
||||
private:
|
||||
// copy constructor is private
|
||||
ReferenceType(const ReferenceType&);
|
||||
|
||||
// copy operator is private
|
||||
ReferenceType& operator=(const ReferenceType&);
|
||||
};
|
||||
}
|
||||
}
|
30
include/ArduinoJson/Internals/StringBuilder.hpp
Normal file
30
include/ArduinoJson/Internals/StringBuilder.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// 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;
|
||||
};
|
||||
}
|
||||
}
|
90
include/ArduinoJson/JsonArray.hpp
Normal file
90
include/ArduinoJson/JsonArray.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Internals/JsonBufferAllocated.hpp"
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/List.hpp"
|
||||
#include "Internals/ReferenceType.hpp"
|
||||
#include "JsonVariant.hpp"
|
||||
|
||||
// Returns the size (in bytes) of an array with n elements.
|
||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||
#define JSON_ARRAY_SIZE(NUMBER_OF_ELEMENTS) \
|
||||
(sizeof(JsonArray) + (NUMBER_OF_ELEMENTS) * sizeof(JsonArray::node_type))
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// Forward declarations
|
||||
class JsonObject;
|
||||
class JsonBuffer;
|
||||
|
||||
// An array of JsonVariant.
|
||||
//
|
||||
// The constructor is private, instances must be created via
|
||||
// JsonBuffer::createArray() or JsonBuffer::parseArray().
|
||||
// A JsonArray can be serialized to a JSON string via JsonArray::printTo().
|
||||
// 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>,
|
||||
public Internals::JsonBufferAllocated {
|
||||
// JsonBuffer is a friend because it needs to call the private constructor.
|
||||
friend class JsonBuffer;
|
||||
|
||||
public:
|
||||
// Returns the JsonVariant at the specified index (synonym for operator[])
|
||||
JsonVariant &at(int index) const;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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); }
|
||||
|
||||
// Adds a reference to the specified JsonArray at the end of the array.
|
||||
void add(JsonArray &array) { add().set(array); }
|
||||
|
||||
// Adds a reference to the specified JsonObject at the end of the array.
|
||||
void add(JsonObject &obejct) { add().set(obejct); }
|
||||
|
||||
// Creates a JsonArray and adds a reference at the end of the array.
|
||||
// It's a shortcut for JsonBuffer::createArray() and JsonArray::add()
|
||||
JsonArray &createNestedArray();
|
||||
|
||||
// Creates a JsonObject and adds a reference at the end of the array.
|
||||
// It's a shortcut for JsonBuffer::createObject() and JsonArray::add()
|
||||
JsonObject &createNestedObject();
|
||||
|
||||
// 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; }
|
||||
|
||||
// Serialize the array to the specified JsonWriter.
|
||||
void writeTo(Internals::JsonWriter &writer) const;
|
||||
|
||||
private:
|
||||
// Create an empty JsonArray attached to the specified JsonBuffer.
|
||||
explicit JsonArray(JsonBuffer *buffer)
|
||||
: Internals::List<JsonVariant>(buffer) {}
|
||||
|
||||
// The instance returned by JsonArray::invalid()
|
||||
static JsonArray _invalid;
|
||||
};
|
||||
}
|
87
include/ArduinoJson/JsonBuffer.hpp
Normal file
87
include/ArduinoJson/JsonBuffer.hpp
Normal file
@ -0,0 +1,87 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint8_t
|
||||
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#elif defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
class JsonArray;
|
||||
class JsonObject;
|
||||
|
||||
// Entry point for using the library.
|
||||
//
|
||||
// Handle the memory management (done in derived classes) and calls the parser.
|
||||
// This abstract class is implemented by StaticJsonBuffer which implements a
|
||||
// fixed memory allocation.
|
||||
class JsonBuffer {
|
||||
public:
|
||||
// CAUTION: NO VIRTUAL DESTRUCTOR!
|
||||
// If we add a virtual constructor the Arduino compiler will add malloc() and
|
||||
// free() to the binary, adding 706 useless bytes.
|
||||
// virtual ~JsonBuffer() {}
|
||||
|
||||
// Allocates an empty JsonArray.
|
||||
//
|
||||
// Returns a reference to the new JsonArray or JsonArray::invalid() if the
|
||||
// allocation fails.
|
||||
JsonArray &createArray();
|
||||
|
||||
// Allocates an empty JsonObject.
|
||||
//
|
||||
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
|
||||
// allocation fails.
|
||||
JsonObject &createObject();
|
||||
|
||||
// Allocates and populate a JsonArray from a JSON string.
|
||||
//
|
||||
// The First argument is a pointer to the JSON string, the memory must be
|
||||
// writable
|
||||
// because the parser will insert null-terminators and replace escaped chars.
|
||||
//
|
||||
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
|
||||
//
|
||||
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
|
||||
// allocation fails.
|
||||
JsonArray &parseArray(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
|
||||
|
||||
// Allocates and populate a JsonObject from a JSON string.
|
||||
//
|
||||
// The First argument is a pointer to the JSON string, the memory must be
|
||||
// writable
|
||||
// because the parser will insert null-terminators and replace escaped chars.
|
||||
//
|
||||
// The second argument set the nesting limit (see comment on DEFAULT_LIMIT)
|
||||
//
|
||||
// Returns a reference to the new JsonObject or JsonObject::invalid() if the
|
||||
// allocation fails.
|
||||
JsonObject &parseObject(char *json, uint8_t nestingLimit = DEFAULT_LIMIT);
|
||||
|
||||
// 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;
|
||||
};
|
||||
}
|
107
include/ArduinoJson/JsonObject.hpp
Normal file
107
include/ArduinoJson/JsonObject.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Internals/JsonBufferAllocated.hpp"
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/List.hpp"
|
||||
#include "Internals/ReferenceType.hpp"
|
||||
#include "JsonPair.hpp"
|
||||
|
||||
// Returns the size (in bytes) of an object with n elements.
|
||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||
#define JSON_OBJECT_SIZE(NUMBER_OF_ELEMENTS) \
|
||||
(sizeof(JsonObject) + (NUMBER_OF_ELEMENTS) * sizeof(JsonObject::node_type))
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// Forward declarations
|
||||
class JsonArray;
|
||||
class JsonBuffer;
|
||||
|
||||
// A dictionary of JsonVariant indexed by string (char*)
|
||||
//
|
||||
// The constructor is private, instances must be created via
|
||||
// JsonBuffer::createObject() or JsonBuffer::parseObject().
|
||||
// A JsonObject can be serialized to a JSON string via JsonObject::printTo().
|
||||
// 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>,
|
||||
public Internals::JsonBufferAllocated {
|
||||
// JsonBuffer is a friend because it needs to call the private constructor.
|
||||
friend class JsonBuffer;
|
||||
|
||||
public:
|
||||
typedef const char *key_type;
|
||||
typedef JsonPair value_type;
|
||||
|
||||
// Gets the JsonVariant associated with the specified key.
|
||||
// Returns a reference or JsonVariant::invalid() if not found.
|
||||
JsonVariant &at(key_type 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);
|
||||
}
|
||||
|
||||
// Adds the specified key with a reference to the specified JsonArray.
|
||||
void add(key_type key, JsonArray &array) { add(key).set(array); }
|
||||
|
||||
// Adds the specified key with a reference to the specified JsonObject.
|
||||
void add(key_type key, JsonObject &object) { add(key).set(object); }
|
||||
|
||||
// Creates and adds a JsonArray.
|
||||
// This is a shortcut for JsonBuffer::createArray() and JsonObject::add().
|
||||
JsonArray &createNestedArray(key_type key);
|
||||
|
||||
// Creates and adds a JsonObject.
|
||||
// This is a shortcut for JsonBuffer::createObject() and JsonObject::add().
|
||||
JsonObject &createNestedObject(key_type key);
|
||||
|
||||
// Tells weither the specified key is present and associated with a value.
|
||||
bool containsKey(key_type key) const { return at(key).success(); }
|
||||
|
||||
// Removes the specified key and the associated value.
|
||||
void remove(key_type 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;
|
||||
|
||||
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;
|
||||
|
||||
// The instance returned by JsonObject::invalid()
|
||||
static JsonObject _invalid;
|
||||
};
|
||||
}
|
18
include/ArduinoJson/JsonPair.hpp
Normal file
18
include/ArduinoJson/JsonPair.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonVariant.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// A key value pair for JsonObject.
|
||||
struct JsonPair {
|
||||
const char* key;
|
||||
JsonVariant value;
|
||||
};
|
||||
}
|
286
include/ArduinoJson/JsonVariant.hpp
Normal file
286
include/ArduinoJson/JsonVariant.hpp
Normal file
@ -0,0 +1,286 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h> // for uint8_t
|
||||
|
||||
#include "Internals/JsonPrintable.hpp"
|
||||
#include "Internals/JsonVariantContent.hpp"
|
||||
#include "Internals/JsonVariantType.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// Forward declarations.
|
||||
class JsonArray;
|
||||
class JsonObject;
|
||||
|
||||
// A variant that can be a any value serializable to a JSON value.
|
||||
//
|
||||
// It can be set to:
|
||||
// - a boolean
|
||||
// - 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> {
|
||||
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.
|
||||
// It will be serialized as "true" or "false" in JSON.
|
||||
void set(bool value);
|
||||
|
||||
// Sets the variant to 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.
|
||||
template <typename T>
|
||||
JsonVariant &operator=(T value) {
|
||||
set(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Sets the variant to be a reference to an array.
|
||||
JsonVariant &operator=(JsonArray &array) {
|
||||
set(array);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Sets the variant to be a reference to an object.
|
||||
JsonVariant &operator=(JsonObject &object) {
|
||||
set(object);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Gets the variant as a boolean value.
|
||||
// Returns false if the variant is not a boolean value.
|
||||
operator bool() const;
|
||||
|
||||
// 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>()); }
|
||||
|
||||
// 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 &>(); }
|
||||
|
||||
// Get the variant as the specified type.
|
||||
// See cast operators for details.
|
||||
template <typename T>
|
||||
T as() const {
|
||||
return static_cast<T>(*this);
|
||||
}
|
||||
|
||||
// Tells weither the variant has the specified type.
|
||||
// Returns true if the variant has type type T, false otherwise.
|
||||
template <typename T>
|
||||
bool is() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns an invalid variant.
|
||||
// This is meant to replace a NULL pointer.
|
||||
static JsonVariant &invalid() { return _invalid; }
|
||||
|
||||
// Serialize the variant to a JsonWriter
|
||||
void writeTo(Internals::JsonWriter &writer) 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;
|
||||
|
||||
// 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);
|
||||
|
||||
private:
|
||||
// Special constructor used only to create _invalid.
|
||||
explicit JsonVariant(Internals::JsonVariantType type) : _type(type) {}
|
||||
|
||||
// Helper for interger cast operators
|
||||
template <typename T>
|
||||
T cast_long_to() const {
|
||||
return static_cast<T>(as<long>());
|
||||
}
|
||||
|
||||
// The current type of the variant
|
||||
Internals::JsonVariantType _type;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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>();
|
||||
}
|
||||
}
|
36
include/ArduinoJson/StaticJsonBuffer.hpp
Normal file
36
include/ArduinoJson/StaticJsonBuffer.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright Benoit Blanchon 2014-2015
|
||||
// MIT License
|
||||
//
|
||||
// Arduino JSON library
|
||||
// https://github.com/bblanchon/ArduinoJson
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonBuffer.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
// Implements a JsonBuffer with fixed memory allocation.
|
||||
// The template paramenter CAPACITY specifies the capacity of the buffer in
|
||||
// bytes.
|
||||
template <size_t CAPACITY>
|
||||
class StaticJsonBuffer : public JsonBuffer {
|
||||
public:
|
||||
explicit StaticJsonBuffer() : _size(0) {}
|
||||
|
||||
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;
|
||||
return p;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t _buffer[CAPACITY];
|
||||
size_t _size;
|
||||
};
|
||||
}
|
12
keywords.txt
12
keywords.txt
@ -1,6 +1,14 @@
|
||||
JsonParser KEYWORD1
|
||||
JsonArray KEYWORD1
|
||||
JsonObject KEYWORD1
|
||||
JsonVariant KEYWORD1
|
||||
StaticJsonBuffer KEYWORD1
|
||||
add KEYWORD2
|
||||
parse KEYWORD2
|
||||
createArray KEYWORD2
|
||||
createNestedArray KEYWORD2
|
||||
createNestedObject KEYWORD2
|
||||
createObject KEYWORD2
|
||||
parseArray KEYWORD2
|
||||
parseObject KEYWORD2
|
||||
prettyPrintTo KEYWORD2
|
||||
printTo KEYWORD2
|
||||
success KEYWORD2
|
||||
|
17
library.json
Normal file
17
library.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "Json",
|
||||
"keywords": "json, rest, http, web",
|
||||
"description": "An elegant and efficient JSON library for embedded systems",
|
||||
"repository":
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/bblanchon/ArduinoJson.git"
|
||||
},
|
||||
"authors":
|
||||
{
|
||||
"name": "Benoit Blanchon",
|
||||
"url": "http://blog.benoitblanchon.fr"
|
||||
},
|
||||
"frameworks": "arduino",
|
||||
"platforms": "atmelavr"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user