forked from bblanchon/ArduinoJson
Compare commits
311 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 |
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,6 +1,5 @@
|
|||||||
*.sdf
|
.DS_Store
|
||||||
*.user
|
/.idea
|
||||||
*.suo
|
/build
|
||||||
Debug
|
/bin
|
||||||
ipch
|
/lib
|
||||||
*.opensdf
|
|
||||||
|
6
.travis.yml
Normal file
6
.travis.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
language: c++
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
- clang
|
||||||
|
before_script: cmake .
|
||||||
|
script: make && make test
|
@ -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
|
|
@ -1,6 +1,15 @@
|
|||||||
Arduino JSON: change log
|
Arduino JSON: change log
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
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 `doc/Migrating to the new API.md`.
|
||||||
|
|
||||||
|
|
||||||
v3.4
|
v3.4
|
||||||
----
|
----
|
||||||
|
|
||||||
|
15
CMakeLists.txt
Normal file
15
CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
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()
|
||||||
|
|
||||||
|
add_subdirectory(src)
|
||||||
|
add_subdirectory(test)
|
@ -1,15 +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/IndentedPrint.cpp"
|
|
||||||
#include "JsonGenerator/JsonArrayBase.cpp"
|
|
||||||
#include "JsonGenerator/JsonObjectBase.cpp"
|
|
||||||
#include "JsonGenerator/JsonValue.cpp"
|
|
||||||
#include "JsonGenerator/JsonPrettyPrint.cpp"
|
|
||||||
#include "JsonGenerator/JsonPrintable.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,45 +0,0 @@
|
|||||||
#include "IndentedPrint.h"
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Generator;
|
|
||||||
|
|
||||||
void IndentedPrint::indent()
|
|
||||||
{
|
|
||||||
if (level < MAX_LEVEL)
|
|
||||||
level++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndentedPrint::unindent()
|
|
||||||
{
|
|
||||||
if (level > 0)
|
|
||||||
level--;
|
|
||||||
}
|
|
||||||
|
|
||||||
void IndentedPrint::setTabSize(uint8_t n)
|
|
||||||
{
|
|
||||||
if (n < MAX_TAB_SIZE)
|
|
||||||
tabSize = n;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t IndentedPrint::write(uint8_t c)
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
|
|
||||||
if (isNewLine)
|
|
||||||
n += writeTabs();
|
|
||||||
|
|
||||||
n += sink.write(c);
|
|
||||||
|
|
||||||
isNewLine = c == '\n';
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t IndentedPrint::writeTabs()
|
|
||||||
{
|
|
||||||
size_t n = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < level*tabSize; i++)
|
|
||||||
n += sink.write(' ');
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Print.h"
|
|
||||||
|
|
||||||
namespace ArduinoJson
|
|
||||||
{
|
|
||||||
namespace Generator
|
|
||||||
{
|
|
||||||
// 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:
|
|
||||||
|
|
||||||
IndentedPrint(Print& p)
|
|
||||||
: sink(p)
|
|
||||||
{
|
|
||||||
level = 0;
|
|
||||||
tabSize = 2;
|
|
||||||
isNewLine = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual size_t write(uint8_t);
|
|
||||||
|
|
||||||
// Adds one level of indentation
|
|
||||||
void indent();
|
|
||||||
|
|
||||||
// Removes one level of indentation
|
|
||||||
void unindent();
|
|
||||||
|
|
||||||
// Set the number of space printed for each level of indentation
|
|
||||||
void setTabSize(uint8_t n);
|
|
||||||
|
|
||||||
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
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "JsonPrintable.h"
|
|
||||||
#include "JsonValue.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,101 +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="IndentedPrint.h" />
|
|
||||||
<ClInclude Include="JsonPrettyPrint.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="IndentedPrint.cpp" />
|
|
||||||
<ClCompile Include="JsonPrettyPrint.cpp" />
|
|
||||||
<ClCompile Include="JsonArrayBase.cpp" />
|
|
||||||
<ClCompile Include="JsonObjectBase.cpp" />
|
|
||||||
<ClCompile Include="JsonPrintable.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,84 +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>
|
|
||||||
<ClInclude Include="IndentedPrint.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="JsonPrettyPrint.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>
|
|
||||||
<ClCompile Include="IndentedPrint.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="JsonPrettyPrint.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="JsonPrintable.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,62 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "JsonPrintable.h"
|
|
||||||
#include "JsonValue.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,97 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "JsonPrettyPrint.h"
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Generator;
|
|
||||||
|
|
||||||
size_t JsonPrettyPrint::write(uint8_t c)
|
|
||||||
{
|
|
||||||
size_t n = inString ? handleStringChar(c) : handleMarkupChar(c);
|
|
||||||
previousChar = c;
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleStringChar(uint8_t c)
|
|
||||||
{
|
|
||||||
bool isQuote = c == '"' && previousChar != '\\';
|
|
||||||
|
|
||||||
if (isQuote) inString = false;
|
|
||||||
|
|
||||||
return sink.write(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleMarkupChar(uint8_t c)
|
|
||||||
{
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '{':
|
|
||||||
case '[':
|
|
||||||
return handleBlockOpen(c);
|
|
||||||
|
|
||||||
case '}':
|
|
||||||
case ']':
|
|
||||||
return handleBlockClose(c);
|
|
||||||
|
|
||||||
case ':':
|
|
||||||
return handleColumn();
|
|
||||||
|
|
||||||
case ',':
|
|
||||||
return handleComma();
|
|
||||||
|
|
||||||
case '"':
|
|
||||||
return handleQuoteOpen();
|
|
||||||
|
|
||||||
default:
|
|
||||||
return handleNormalChar(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleBlockOpen(uint8_t c)
|
|
||||||
{
|
|
||||||
return indentIfNeeded() + sink.write(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleBlockClose(uint8_t c)
|
|
||||||
{
|
|
||||||
return unindentIfNeeded() + sink.write(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleColumn()
|
|
||||||
{
|
|
||||||
return sink.write(':') + sink.write(' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleComma()
|
|
||||||
{
|
|
||||||
return sink.write(',') + sink.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleQuoteOpen()
|
|
||||||
{
|
|
||||||
inString = true;
|
|
||||||
return indentIfNeeded() + sink.write('"');
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t JsonPrettyPrint::handleNormalChar(uint8_t c)
|
|
||||||
{
|
|
||||||
return indentIfNeeded() + sink.write(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t JsonPrettyPrint::indentIfNeeded()
|
|
||||||
{
|
|
||||||
if (!inEmptyBlock()) return 0;
|
|
||||||
|
|
||||||
sink.indent();
|
|
||||||
return sink.println();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t JsonPrettyPrint::unindentIfNeeded()
|
|
||||||
{
|
|
||||||
if (inEmptyBlock()) return 0;
|
|
||||||
|
|
||||||
sink.unindent();
|
|
||||||
return sink.println();
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Print.h"
|
|
||||||
#include "IndentedPrint.h"
|
|
||||||
|
|
||||||
namespace ArduinoJson
|
|
||||||
{
|
|
||||||
namespace Generator
|
|
||||||
{
|
|
||||||
// Converts a compact JSON string into an indented one.
|
|
||||||
class JsonPrettyPrint : public Print
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
JsonPrettyPrint(IndentedPrint& p)
|
|
||||||
: sink(p)
|
|
||||||
{
|
|
||||||
previousChar = 0;
|
|
||||||
inString = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual size_t write(uint8_t);
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint8_t previousChar;
|
|
||||||
IndentedPrint& sink;
|
|
||||||
bool inString;
|
|
||||||
|
|
||||||
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();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "JsonPrintable.h"
|
|
||||||
#include "JsonPrettyPrint.h"
|
|
||||||
#include "StringBuilder.h"
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Generator;
|
|
||||||
using namespace ArduinoJson::Internals;
|
|
||||||
|
|
||||||
size_t JsonPrintable::printTo(char* buffer, size_t bufferSize) const
|
|
||||||
{
|
|
||||||
StringBuilder sb(buffer, bufferSize);
|
|
||||||
return printTo(sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t JsonPrintable::prettyPrintTo(char* buffer, size_t bufferSize) const
|
|
||||||
{
|
|
||||||
StringBuilder sb(buffer, bufferSize);
|
|
||||||
return prettyPrintTo(sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t JsonPrintable::prettyPrintTo(IndentedPrint& p) const
|
|
||||||
{
|
|
||||||
JsonPrettyPrint prettyPrint(p);
|
|
||||||
return printTo(prettyPrint);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t JsonPrintable::prettyPrintTo(Print& p) const
|
|
||||||
{
|
|
||||||
IndentedPrint indentedPrint(p);
|
|
||||||
return prettyPrintTo(indentedPrint);
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Print.h"
|
|
||||||
#include "Printable.h"
|
|
||||||
#include "IndentedPrint.h"
|
|
||||||
|
|
||||||
namespace ArduinoJson
|
|
||||||
{
|
|
||||||
namespace Generator
|
|
||||||
{
|
|
||||||
// Contains methods to generate a JSON string.
|
|
||||||
// Implemented by both JsonObject and JsonArray
|
|
||||||
class JsonPrintable : public Printable
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
// Generates the compact JSON string and sends it to a Print stream
|
|
||||||
virtual size_t printTo(Print& p) const = 0;
|
|
||||||
|
|
||||||
// Generates the compact JSON string and writes it in a buffer
|
|
||||||
size_t printTo(char* buffer, size_t bufferSize) const;
|
|
||||||
|
|
||||||
// Generates the indented JSON string and sends it to a Print stream
|
|
||||||
size_t prettyPrintTo(Print& p) const;
|
|
||||||
|
|
||||||
// Generates the indented JSON string and sends it to a IndentedPrint stream
|
|
||||||
// This overload allows a finer control of the output because you can customize
|
|
||||||
// the IndentedPrint.
|
|
||||||
size_t prettyPrintTo(IndentedPrint& p) const;
|
|
||||||
|
|
||||||
// Generates the indented JSON string and writes it in a buffer
|
|
||||||
size_t prettyPrintTo(char* buffer, size_t bufferSize) const;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -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,40 +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);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Print::println()
|
|
||||||
{
|
|
||||||
return write('\r') + write('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,29 +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);
|
|
||||||
size_t println();
|
|
||||||
};
|
|
||||||
|
|
||||||
#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,247 +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
|
|
||||||
* Supports indented output
|
|
||||||
* 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));
|
|
||||||
|
|
||||||
> ##### Want an indented output?
|
|
||||||
> By default the generated JSON is as small as possible. It contains no extra space, nor line break.
|
|
||||||
> But if you want an indented, more readable output, you can.
|
|
||||||
> Simply call `prettyPrintTo` instead of `printTo()`:
|
|
||||||
>
|
|
||||||
> array.prettyPrintTo(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`, `Wire`...
|
|
||||||
|
|
||||||
|
|
||||||
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,107 +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="PrettyPrint_Array_Tests.cpp" />
|
|
||||||
<ClCompile Include="PrettyPrint_Object_Tests.cpp" />
|
|
||||||
<ClCompile Include="PrettyPrint_String_Tests.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,52 +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>
|
|
||||||
<ClCompile Include="PrettyPrint_Array_Tests.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="PrettyPrint_Object_Tests.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="PrettyPrint_String_Tests.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,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "CppUnitTest.h"
|
|
||||||
#include "JsonPrettyPrint.h"
|
|
||||||
#include "StringBuilder.h"
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
|
||||||
using namespace ArduinoJson::Generator;
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
|
||||||
|
|
||||||
namespace JsonGeneratorTests
|
|
||||||
{
|
|
||||||
TEST_CLASS(PrettyPrint_Array_Tests)
|
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
size_t returnValue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
TEST_METHOD(EmptyArray)
|
|
||||||
{
|
|
||||||
whenInputIs("[]");
|
|
||||||
outputMustBe("[]");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(OneElement)
|
|
||||||
{
|
|
||||||
whenInputIs("[1]");
|
|
||||||
outputMustBe(
|
|
||||||
"[\r\n"
|
|
||||||
" 1\r\n"
|
|
||||||
"]");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(TwoElements)
|
|
||||||
{
|
|
||||||
whenInputIs("[1,2]");
|
|
||||||
outputMustBe(
|
|
||||||
"[\r\n"
|
|
||||||
" 1,\r\n"
|
|
||||||
" 2\r\n"
|
|
||||||
"]");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EmptyNestedArrays)
|
|
||||||
{
|
|
||||||
whenInputIs("[[],[]]");
|
|
||||||
outputMustBe(
|
|
||||||
"[\r\n"
|
|
||||||
" [],\r\n"
|
|
||||||
" []\r\n"
|
|
||||||
"]");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(NestedArrays)
|
|
||||||
{
|
|
||||||
whenInputIs("[[1,2],[3,4]]");
|
|
||||||
outputMustBe(
|
|
||||||
"[\r\n"
|
|
||||||
" [\r\n"
|
|
||||||
" 1,\r\n"
|
|
||||||
" 2\r\n"
|
|
||||||
" ],\r\n"
|
|
||||||
" [\r\n"
|
|
||||||
" 3,\r\n"
|
|
||||||
" 4\r\n"
|
|
||||||
" ]\r\n"
|
|
||||||
"]");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void whenInputIs(const char input[])
|
|
||||||
{
|
|
||||||
StringBuilder sb(buffer, sizeof(buffer));
|
|
||||||
IndentedPrint indentedPrint(sb);
|
|
||||||
JsonPrettyPrint decorator(indentedPrint);
|
|
||||||
|
|
||||||
returnValue = decorator.print(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void outputMustBe(const char* expected)
|
|
||||||
{
|
|
||||||
Assert::AreEqual(expected, buffer);
|
|
||||||
Assert::AreEqual(strlen(expected), returnValue);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "CppUnitTest.h"
|
|
||||||
#include "JsonPrettyPrint.h"
|
|
||||||
#include "StringBuilder.h"
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
|
||||||
using namespace ArduinoJson::Generator;
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
|
||||||
|
|
||||||
namespace JsonGeneratorTests
|
|
||||||
{
|
|
||||||
TEST_CLASS(PrettyPrint_Object_Tests)
|
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
size_t returnValue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
TEST_METHOD(EmptyObject)
|
|
||||||
{
|
|
||||||
whenInputIs("{}");
|
|
||||||
outputMustBe("{}");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(OneMember)
|
|
||||||
{
|
|
||||||
whenInputIs("{\"key\":\"value\"}");
|
|
||||||
outputMustBe(
|
|
||||||
"{\r\n"
|
|
||||||
" \"key\": \"value\"\r\n"
|
|
||||||
"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(TwoMembers)
|
|
||||||
{
|
|
||||||
whenInputIs("{\"key1\":\"value1\",\"key2\":\"value2\"}");
|
|
||||||
outputMustBe(
|
|
||||||
"{\r\n"
|
|
||||||
" \"key1\": \"value1\",\r\n"
|
|
||||||
" \"key2\": \"value2\"\r\n"
|
|
||||||
"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EmptyNestedObjects)
|
|
||||||
{
|
|
||||||
whenInputIs("{\"key1\":{},\"key2\":{}}");
|
|
||||||
outputMustBe(
|
|
||||||
"{\r\n"
|
|
||||||
" \"key1\": {},\r\n"
|
|
||||||
" \"key2\": {}\r\n"
|
|
||||||
"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(NestedObjects)
|
|
||||||
{
|
|
||||||
whenInputIs("{\"key1\":{\"a\":1},\"key2\":{\"b\":2}}");
|
|
||||||
outputMustBe(
|
|
||||||
"{\r\n"
|
|
||||||
" \"key1\": {\r\n"
|
|
||||||
" \"a\": 1\r\n"
|
|
||||||
" },\r\n"
|
|
||||||
" \"key2\": {\r\n"
|
|
||||||
" \"b\": 2\r\n"
|
|
||||||
" }\r\n"
|
|
||||||
"}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void whenInputIs(const char input[])
|
|
||||||
{
|
|
||||||
StringBuilder sb(buffer, sizeof(buffer));
|
|
||||||
IndentedPrint indentedPrint(sb);
|
|
||||||
JsonPrettyPrint decorator(indentedPrint);
|
|
||||||
|
|
||||||
returnValue = decorator.print(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
void outputMustBe(const char* expected)
|
|
||||||
{
|
|
||||||
Assert::AreEqual(expected, buffer);
|
|
||||||
Assert::AreEqual(strlen(expected), returnValue);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "CppUnitTest.h"
|
|
||||||
#include "JsonPrettyPrint.h"
|
|
||||||
#include "StringBuilder.h"
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
|
||||||
using namespace ArduinoJson::Generator;
|
|
||||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
|
||||||
|
|
||||||
namespace JsonGeneratorTests
|
|
||||||
{
|
|
||||||
TEST_CLASS(PrettyPrint_String_Tests)
|
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
size_t returnValue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
TEST_METHOD(EmptyString)
|
|
||||||
{
|
|
||||||
whenInputIs("");
|
|
||||||
outputMustBe("");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(TrickyCharacters)
|
|
||||||
{
|
|
||||||
whenInputIs ("\":\\\"',\"");
|
|
||||||
outputMustBe("\":\\\"',\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(OpeningCurlyBrace)
|
|
||||||
{
|
|
||||||
whenInputIs ("\"{\"");
|
|
||||||
outputMustBe("\"{\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(OpeningSquareBrace)
|
|
||||||
{
|
|
||||||
whenInputIs("\"[\"");
|
|
||||||
outputMustBe("\"[\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(ClosingCurlyBrace)
|
|
||||||
{
|
|
||||||
whenInputIs("\"}\"");
|
|
||||||
outputMustBe("\"}\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(ClosingSquareBrace)
|
|
||||||
{
|
|
||||||
whenInputIs("\"]\"");
|
|
||||||
outputMustBe("\"]\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void whenInputIs(const char input[])
|
|
||||||
{
|
|
||||||
StringBuilder sb(buffer, sizeof(buffer));
|
|
||||||
IndentedPrint indentedPrint(sb);
|
|
||||||
JsonPrettyPrint decorator(indentedPrint);
|
|
||||||
|
|
||||||
returnValue = decorator.print(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
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,71 +0,0 @@
|
|||||||
/*
|
|
||||||
* Arduino JSON library
|
|
||||||
* Benoit Blanchon 2014 - MIT License
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "JsonToken.h"
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Parser;
|
|
||||||
|
|
||||||
char* JsonToken::getText()
|
|
||||||
{
|
|
||||||
char* s = json + token->start;
|
|
||||||
json[token->end] = 0;
|
|
||||||
|
|
||||||
unescapeString(s);
|
|
||||||
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void JsonToken::unescapeString(char* s)
|
|
||||||
{
|
|
||||||
char* readPtr = s;
|
|
||||||
char* writePtr = s;
|
|
||||||
char c;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
c = *readPtr++;
|
|
||||||
|
|
||||||
if (c == '\\')
|
|
||||||
{
|
|
||||||
c = unescapeChar(*readPtr++);
|
|
||||||
}
|
|
||||||
|
|
||||||
*writePtr++ = c;
|
|
||||||
|
|
||||||
} while (c != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char JsonToken::unescapeChar(char c)
|
|
||||||
{
|
|
||||||
// Optimized for code size on a 8-bit AVR
|
|
||||||
|
|
||||||
const char* p = "b\bf\fn\nr\rt\t";
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (p[0] == 0) return c;
|
|
||||||
if (p[0] == c) return p[1];
|
|
||||||
p += 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,99 +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();
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
static char unescapeChar(char c);
|
|
||||||
static void unescapeString(char* s);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -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,189 +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(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,165 +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(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,103 +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" />
|
|
||||||
<ClCompile Include="JsonStringTests.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,37 +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="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>
|
|
||||||
<ClCompile Include="JsonArrayTests.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="JsonStringTests.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,107 +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(JsonStringTests)
|
|
||||||
{
|
|
||||||
const char* actual;
|
|
||||||
char json[256];
|
|
||||||
JsonParser<32> parser;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
TEST_METHOD(EmptyString)
|
|
||||||
{
|
|
||||||
whenInputIs("");
|
|
||||||
outputMustBe(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(JustOneQuote)
|
|
||||||
{
|
|
||||||
whenInputIs("\"");
|
|
||||||
outputMustBe(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(SimpleString)
|
|
||||||
{
|
|
||||||
whenInputIs("\"Hi!\"");
|
|
||||||
outputMustBe("Hi!");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedQuote)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\\"34\""); // ie 12\"34
|
|
||||||
outputMustBe("12\"34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedReverseSolidus)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\\\34\""); // ie 12\\34
|
|
||||||
outputMustBe("12\\34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedSolidus)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\/34\"");
|
|
||||||
outputMustBe("12/34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedBackspace)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\b34\"");
|
|
||||||
outputMustBe("12\b34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedFormfeed)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\f34\"");
|
|
||||||
outputMustBe("12\f34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedNewline)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\n34\"");
|
|
||||||
outputMustBe("12\n34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedCarriageReturn)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\r34\"");
|
|
||||||
outputMustBe("12\r34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(EscapedTab)
|
|
||||||
{
|
|
||||||
whenInputIs("\"12\\t34\"");
|
|
||||||
outputMustBe("12\t34");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_METHOD(AllEscapedCharsTogether)
|
|
||||||
{
|
|
||||||
whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\"");
|
|
||||||
outputMustBe("1\"2\\3/4\b5\f6\n7\r8\t9");
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
void whenInputIs(const char* input)
|
|
||||||
{
|
|
||||||
strcpy(json, input);
|
|
||||||
actual = parser.parse(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
void outputMustBe(const char* expected)
|
|
||||||
{
|
|
||||||
Assert::AreEqual(expected, actual);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
65
README.md
65
README.md
@ -1,6 +1,8 @@
|
|||||||
Arduino JSON library
|
Arduino JSON library
|
||||||
====================
|
====================
|
||||||
|
|
||||||
|
[](https://travis-ci.org/bblanchon/ArduinoJson)
|
||||||
|
|
||||||
*An elegant and efficient JSON library for embedded systems.*
|
*An elegant and efficient JSON library for embedded systems.*
|
||||||
|
|
||||||
It's design to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc).
|
It's design to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc).
|
||||||
@ -10,37 +12,54 @@ It has been written with Arduino in mind, but it isn't linked to Arduino librari
|
|||||||
Features
|
Features
|
||||||
--------
|
--------
|
||||||
|
|
||||||
* JSON decoding: [see documentation here](/JsonParser/)
|
* JSON decoding
|
||||||
* JSON encoding: [see documentation here](/JsonGenerator/)
|
* JSON encoding (with optional indentation)
|
||||||
* Elegant API, very easy to use
|
* Elegant API, very easy to use
|
||||||
* Fixed memory allocation (no malloc)
|
* Fixed memory allocation (no malloc)
|
||||||
* Small footprint
|
* Small footprint
|
||||||
* MIT License
|
* MIT License
|
||||||
|
|
||||||
Feature comparison
|
Quick start
|
||||||
------------------
|
-----------
|
||||||
|
|
||||||
| Library | Memory allocation | Nested objects | Parser size | Encoder size |
|
#### Decoding / Parsing
|
||||||
| ------------ | ----------------- | -------------- | ----------- | ------------- |
|
|
||||||
| Arduino JSON | static | yes | 2760 Bytes | 862 bytes |
|
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||||
| json-arduino | dynamic | no | 3348 (+21%) | not supported |
|
|
||||||
| aJson | dynamic | yes | 5088 (+84%) | 4678 (+540%) |
|
|
||||||
|
|
||||||
"Parser size" was measured with a program parsing `{"sensor":"outdoor","value":25.6}`.
|
StaticJsonBuffer<200> jsonBuffer;
|
||||||
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).
|
|
||||||
|
|
||||||
"Encoder size" was measured with a program generating `{"sensor":"outdoor","value":25.6}`.
|
JsonObject& root = jsonBuffer.parseObject(json);
|
||||||
[Source files are here](https://gist.github.com/bblanchon/60224e9dcfeab4ddc7e9).
|
|
||||||
|
|
||||||
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)
|
[See complete guide](/doc/Decoding JSON.md)
|
||||||
|
|
||||||
|
#### 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]}
|
||||||
|
|
||||||
|
[See complete guide](/doc/Encoding JSON.md)
|
||||||
|
|
||||||
Testimonials
|
Testimonials
|
||||||
------------
|
------------
|
||||||
|
|
||||||
From Arduino's Forum user `jflaplante`:
|
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.
|
> I have no such problem so far with your library. It is working perfectly with my web services.
|
||||||
|
|
||||||
From Arduino's Forum user `gbathree`:
|
From Arduino's Forum user `gbathree`:
|
||||||
@ -49,10 +68,12 @@ From Arduino's Forum user `gbathree`:
|
|||||||
From StackOverflow user `thegreendroid`:
|
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.
|
> 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/)
|
> Thanks for a great library!!!
|
||||||
* [Motivation for this library](http://blog.benoitblanchon.fr/arduino-json-parser/)
|
> 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.
|
||||||
* [Release of version 2](http://blog.benoitblanchon.fr/arduino-json-v2-0/)
|
> ArduinoJson saved me a week's worth of time!!
|
||||||
* [Release of version 3](http://blog.benoitblanchon.fr/arduino-json-v3-0/)
|
|
||||||
|
---
|
||||||
|
|
||||||
|
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:
|
102
doc/Avoiding pitfalls.md
Normal file
102
doc/Avoiding pitfalls.md
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
Avoiding common pitfalls in Arduino JSON
|
||||||
|
========================================
|
||||||
|
|
||||||
|
As `StaticJsonBuffer` is the corner stone of this library, you'll see that every pitfall listed here are related to a wrong understanding of the memory model.
|
||||||
|
|
||||||
|
Make sure you read [Arduino JSON memory model](Memory model.md) before going further.
|
||||||
|
|
||||||
|
## 1. Make `StaticJsonBuffer` big enough
|
||||||
|
|
||||||
|
By design, the library has no way to tell you why `parseArray()` or `parseObject()` failed.
|
||||||
|
|
||||||
|
There are basically two reasons why they may fail:
|
||||||
|
|
||||||
|
1. the JSON string is invalid,
|
||||||
|
2. the JSON string contains more values that the buffer can store.
|
||||||
|
|
||||||
|
So, if you are sure the JSON string is correct and you still can't parse it, you should try to increase the size of the `StaticJsonBuffer`.
|
||||||
|
|
||||||
|
## 2. Make sure everything fits in 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
|
||||||
|
StaticJsonBuffer<512> buffer; // 514 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. Keep the `StaticJsonBuffer` in memory long enough
|
||||||
|
|
||||||
|
Remember that `StaticJsonBuffer`'s function return references.
|
||||||
|
References don't contain data, they are just pointer to the actual.
|
||||||
|
So they can only work if the actual data is in memory.
|
||||||
|
|
||||||
|
For example, don't do this:
|
||||||
|
|
||||||
|
JsonArray& getArray(char* json)
|
||||||
|
{
|
||||||
|
StaticJsonBuffer<200> buffer;
|
||||||
|
return buffer.parseArray(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
because the local variable `buffer` will be *removed* from memory when the function `parseArray()` returns, and the `JsonArray&` will point to an invalid location.
|
||||||
|
|
||||||
|
## 4. Don't reuse the same `StaticJsonBuffer`
|
||||||
|
|
||||||
|
During is lifetime a `StaticJsonBuffer` growth until it's discarded. If you try to reuse the same instance several time, it will rapidly get full.
|
||||||
|
|
||||||
|
For this reason, you should not use a global variable for your `StaticJsonBuffer`. I don't think there is any scenario in which a global `StaticJsonBuffer` would be a valid option.
|
||||||
|
|
||||||
|
The best practice is to declare it in a local scope, so that it's discarded as soon as possible. My advice it to declare it in a function which unique role is to handle the JSON serialization.
|
||||||
|
|
||||||
|
## 5. Keep the JSON string in memory long enough
|
||||||
|
|
||||||
|
The library never make memory duplication.
|
||||||
|
This has an important implication on string values, it means that the library will return pointer to chunks of the string.
|
||||||
|
|
||||||
|
For instance, let's imagine that you parse `["hello","world"]`, like this:
|
||||||
|
|
||||||
|
char[] json = "[\"hello\",\"world\"]";
|
||||||
|
StaticJsonBuffer<32> buffer;
|
||||||
|
JsonArray& array = buffer.parseArray(json);
|
||||||
|
|
||||||
|
const char* first = array[0];
|
||||||
|
const char* second = array[1];
|
||||||
|
|
||||||
|
In that case, both `first` and `second` are pointers to the content of the original string `json`.
|
||||||
|
So this will only work if `json` is still in memory.
|
||||||
|
|
||||||
|
## 6. JSON string is altered
|
||||||
|
|
||||||
|
If you read carefully the previous section, you may have come to the conclusion that the JSON parser modifies the JSON string.
|
||||||
|
|
||||||
|
Indeed, the parser modifies the string for two reasons:
|
||||||
|
|
||||||
|
1. it inserts `\0` to terminate substrings,
|
||||||
|
2. it translate escaped characters like `\n` or `\t`.
|
||||||
|
|
||||||
|
Most of the time this wont be an issue, but there are some corner cases that can be problematic.
|
||||||
|
|
||||||
|
Let take the example bellow:
|
||||||
|
|
||||||
|
char[] json = "[\"hello\",\"world\"]";
|
||||||
|
StaticJsonBuffer<32> buffer;
|
||||||
|
JsonArray& array = buffer.parseArray(json);
|
||||||
|
|
||||||
|
If you replace it by:
|
||||||
|
|
||||||
|
char* json = "[\"hello\",\"world\"]";
|
||||||
|
StaticJsonBuffer<32> buffer;
|
||||||
|
JsonArray& array = buffer.parseArray(json);
|
||||||
|
|
||||||
|
Depending on your platform, you may have an exception because the parser tries to write at a location that is read-only.
|
||||||
|
In the first case `char json[]` declares an array of `char` initialized to the specified string.
|
||||||
|
In the second case `char* json` declares a pointer to a read-only string, in fact it should be a `const char*` instead of a `char*`.
|
||||||
|
|
15
doc/Contributing.md
Normal file
15
doc/Contributing.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
Contributing to Arduino JSON
|
||||||
|
============================
|
||||||
|
|
||||||
|
If you want to contribute to the project, please:
|
||||||
|
|
||||||
|
1. Use GitHub pull request feature
|
||||||
|
2. Follow the coding conventions
|
||||||
|
3. Write tests
|
||||||
|
|
||||||
|
About the coding conventions: I try to follow the [Google C++ Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html) with few variations to match the Arduino conventions.
|
||||||
|
|
||||||
|
I use [ClangFormat](http://clang.llvm.org/docs/ClangFormat.html) to format the code for me.
|
||||||
|
I use [CppLint](http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py) to detect non-compliant stuff.
|
||||||
|
|
||||||
|
You should have a look at the `scripts/` folder as it contains a few helpers scripts.
|
148
doc/Decoding JSON.md
Normal file
148
doc/Decoding JSON.md
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
Decoding JSON with Arduino JSON
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Before writing any code, don't forget to include the header:
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md).
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Here an example that parse the string `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`:
|
||||||
|
|
||||||
|
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 1: Reserve memory space
|
||||||
|
//
|
||||||
|
StaticJsonBuffer<200> jsonBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 2: Deserialize the JSON string
|
||||||
|
//
|
||||||
|
JsonObject& root = jsonBuffer.parseObject(json);
|
||||||
|
|
||||||
|
if (!root.success())
|
||||||
|
{
|
||||||
|
Serial.println("parseObject() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 3: Retrieve the values
|
||||||
|
//
|
||||||
|
const char* sensor = root["sensor"];
|
||||||
|
long time = root["time"];
|
||||||
|
double latitude = root["data"][0];
|
||||||
|
double longitude = root["data"][1];
|
||||||
|
|
||||||
|
## Step 1: Reserve memory space
|
||||||
|
|
||||||
|
Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`.
|
||||||
|
|
||||||
|
Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`.
|
||||||
|
|
||||||
|
## Step 2: Parse the JSON string
|
||||||
|
|
||||||
|
You invoke the JSON parser through the instance of `StaticJsonBuffer`.
|
||||||
|
It exposes two functions for parsing JSON:
|
||||||
|
|
||||||
|
1. `parseArray()` that returns a reference to a `JsonArray`
|
||||||
|
2. `parseObject()` that returns a reference to a `JsonObject`
|
||||||
|
|
||||||
|
Let's see an example.
|
||||||
|
Say we want to parse `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`, it's an object so we call `parseObject()` as follows:
|
||||||
|
|
||||||
|
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||||
|
|
||||||
|
JsonObject& root = jsonBuffer.parseObject(json);
|
||||||
|
|
||||||
|
As you can see `parseObject()` takes a `char*` as a parameter.
|
||||||
|
Be careful, it's not a `const char*`, the memory must be writable.
|
||||||
|
Indeed, the parser will modify the string in two cases:
|
||||||
|
|
||||||
|
1. to insert string endings (character `\0`),
|
||||||
|
2. to translate escaped characters (like `\n` or `\t`).
|
||||||
|
|
||||||
|
Another thing that you must keep in mind is that the string (`char json[]` in the example above) must stay in memory during the whole parsing process.
|
||||||
|
That is because the in memory object tree will store pointer to chunks of the string, so as to avoid any memory duplication.
|
||||||
|
|
||||||
|
Now, to check if the parsing was successful, you can call `JsonObject::success()`:
|
||||||
|
|
||||||
|
if (!root.success())
|
||||||
|
{
|
||||||
|
// Parsing fail
|
||||||
|
}
|
||||||
|
|
||||||
|
The result can be `false` for tree reasons:
|
||||||
|
|
||||||
|
1. the JSON string is invalid,
|
||||||
|
2. the JSON string doesn't represent an object,
|
||||||
|
3. the `StaticJsonBuffer` is too small.
|
||||||
|
|
||||||
|
We just saw how to parse an object, there is nothing more to say for arrays, the procedure is exactly the same.
|
||||||
|
|
||||||
|
## Step 3: Retrieve the values
|
||||||
|
|
||||||
|
Now that the object or array is in memory, you can extract the data very easily.
|
||||||
|
|
||||||
|
In this section, we'll see how to do it with a `JsonObject`.
|
||||||
|
Once again, there is nothing more to say about arrays, `JsonArray` works exactly the same as `JsonObject`.
|
||||||
|
|
||||||
|
#### Subscript operator
|
||||||
|
|
||||||
|
The simplest way is to use the subscript operator of `JsonObject`:
|
||||||
|
|
||||||
|
const char* sensor = root["sensor"];
|
||||||
|
long time = root["time"];
|
||||||
|
|
||||||
|
You can chain the subscript operator if you have nested arrays or objects:
|
||||||
|
|
||||||
|
double latitude = root["data"][0];
|
||||||
|
double longitude = root["data"][1];
|
||||||
|
|
||||||
|
But alternatively, you can get a reference to the nested array:
|
||||||
|
|
||||||
|
JsonArray& nestedArray = root["data"];
|
||||||
|
|
||||||
|
#### Casting values
|
||||||
|
|
||||||
|
In the previous examples, the values were implicitly casted to the target type.
|
||||||
|
You can also do this explicitly
|
||||||
|
|
||||||
|
const char* sensor = root["sensor"].asString();
|
||||||
|
long time = root["time"].as<long>();
|
||||||
|
JsonArray& nestedArray = root["data"].asArray();
|
||||||
|
|
||||||
|
If the actual value doesn't match the target type, a default value will be return:
|
||||||
|
|
||||||
|
1. `false` for boolean values
|
||||||
|
2. `0` for integer values
|
||||||
|
3. `NULL` for string values
|
||||||
|
4. `JsonArray::invalid()` for nested arrays
|
||||||
|
5. `JsonObject::invalid()` for nested object
|
||||||
|
|
||||||
|
#### Check values
|
||||||
|
|
||||||
|
If you want to know if some value is present, call `containsKey()`:
|
||||||
|
|
||||||
|
if (root.contains("extra"))
|
||||||
|
{
|
||||||
|
// root["extra"] is valid
|
||||||
|
}
|
||||||
|
|
||||||
|
If you want to check the type value has a certain type, call `is<T>()`:
|
||||||
|
|
||||||
|
if (root["extra"].is<JsonArray&>())
|
||||||
|
{
|
||||||
|
// root["extra"] is an array
|
||||||
|
}
|
||||||
|
|
||||||
|
You can also iterate through the key-value pairs of the object:
|
||||||
|
|
||||||
|
for (JsonObject::itertor it=root.begin(); it!=root.end(); ++it)
|
||||||
|
{
|
||||||
|
Serial.println(it->key);
|
||||||
|
Serial.println(i->value.asString());
|
||||||
|
}
|
140
doc/Encoding JSON.md
Normal file
140
doc/Encoding JSON.md
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
Encoding JSON with Arduino JSON
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Before writing any code, don't forget to include the header:
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md).
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
Here is an example to generate `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 1: Reserve memory space
|
||||||
|
//
|
||||||
|
StaticJsonBuffer<200> jsonBuffer;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 2: Build object tree in memory
|
||||||
|
//
|
||||||
|
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
|
||||||
|
|
||||||
|
//
|
||||||
|
// Step 3: Generate the JSON string
|
||||||
|
//
|
||||||
|
root.printTo(Serial);
|
||||||
|
|
||||||
|
## Step 1: Reserve memory space
|
||||||
|
|
||||||
|
Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`.
|
||||||
|
|
||||||
|
Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`.
|
||||||
|
|
||||||
|
## Step 2: Build object tree in memory
|
||||||
|
|
||||||
|
Now that you have enough memory hold by the `StaticJsonBuffer`, you can use it to build your in-memory representation of the JSON string.
|
||||||
|
|
||||||
|
#### Arrays
|
||||||
|
|
||||||
|
You create an array like this:
|
||||||
|
|
||||||
|
JsonArray& array = jsonBuffer.createArray();
|
||||||
|
|
||||||
|
Don't forget the `&` after `JsonArray`, it needs to be a reference to 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(3.1415, 4); // 4 digits: "3.1415"
|
||||||
|
array.add(3.1415); // 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 2.
|
||||||
|
> 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 this behavior.
|
||||||
|
|
||||||
|
You can add a nested array or object if you have a reference to it.
|
||||||
|
Or simpler, you can create nested array or nested objects from the array:
|
||||||
|
|
||||||
|
JsonArray& nestedArray = array.createNestedArray();
|
||||||
|
JsonObject& nestedObject = array.createNestedObject();
|
||||||
|
|
||||||
|
#### Objects
|
||||||
|
|
||||||
|
You create an object like this:
|
||||||
|
|
||||||
|
JsonObject& object = jsonBuffer.createObject();
|
||||||
|
|
||||||
|
Again, don't forget the `&` after `JsonObject`, it needs to be a reference to 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(3.1415, 4); // 4 digits "3.1415"
|
||||||
|
object["key5"] = 3.1415; // default: 2 digits "3.14"
|
||||||
|
|
||||||
|
You can add a nested array or object if you have a reference to it.
|
||||||
|
Or simpler, you can create nested array or nested objects from the object:
|
||||||
|
|
||||||
|
JsonArray& nestedArray = object.createNestedArray("key6");
|
||||||
|
JsonObject& nestedObject = object.createNestedObject("key7");
|
||||||
|
|
||||||
|
> ##### 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`
|
||||||
|
|
||||||
|
## Step 3: Generate 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 `Print` implementation 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));
|
||||||
|
|
||||||
|
> ##### Want an indented output?
|
||||||
|
> By default the generated JSON is as small as possible. It contains no extra space, nor line break.
|
||||||
|
> But if you want an indented, more readable output, you can.
|
||||||
|
> Simply call `prettyPrintTo` instead of `printTo()`:
|
||||||
|
>
|
||||||
|
> array.prettyPrintTo(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
#### Send to a `Print` implementation
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
array.printTo(Serial);
|
||||||
|
|
||||||
|
And, of course if you need an indented JSON string:
|
||||||
|
|
||||||
|
array.prettyPrintTo(Serial);
|
||||||
|
|
||||||
|
> ##### About the Print interface
|
||||||
|
> The library is designed to send the JSON string to an implementation of the `Print` interface that is part of Arduino.
|
||||||
|
> In the example above we used `Serial`, but they are many other implementations that would work as well, including: `HardwareSerial`, `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`...
|
||||||
|
> When you use this library out of the Arduino environment, it will use it's own implementation of `Print` and everything will be the same.
|
58
doc/Memory model.md
Normal file
58
doc/Memory model.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
Arduino JSON memory model
|
||||||
|
=========================
|
||||||
|
|
||||||
|
## Fixed memory allocation
|
||||||
|
|
||||||
|
### Introducing `StaticJsonBuffer`
|
||||||
|
|
||||||
|
Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer` class.
|
||||||
|
|
||||||
|
Before using any function of the library you need to create a `StaticJsonBuffer`. Then you can use this instance to create arrays and objects, or parse a JSON string.
|
||||||
|
|
||||||
|
`StaticJsonBuffer` has a template parameter that determines its capacity. For example, the following line create a `StaticJsonBuffer` with a capacity of 200 bytes:
|
||||||
|
|
||||||
|
StaticJsonBuffer<200> jsonBuffer;
|
||||||
|
|
||||||
|
The bigger the buffer is, the more complex the object tree can be, but also the more memory you need.
|
||||||
|
|
||||||
|
### How to determine the buffer size?
|
||||||
|
|
||||||
|
So the big question you should have in mind right now is *How can I determine the size?*.
|
||||||
|
|
||||||
|
There are basically two approaches here:
|
||||||
|
|
||||||
|
1. either you can predict the content of the object tree,
|
||||||
|
2. or, you know how much memory is available.
|
||||||
|
|
||||||
|
In the first case, you know some constraints on the object tree. For instance, let's say that your know in advance (and by that I mean "at compilation time") that you want to generate an object with 3 values, one of them being an array with 2 values, like the following:
|
||||||
|
|
||||||
|
{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||||
|
|
||||||
|
To determine the memory usage of this object tree, you use the two macros `JSON_ARRAY_SIZE(n)` and `JSON_OBJECT_SIZE(n)`, both take the number of elements as an argument.
|
||||||
|
For the example above, it would be:
|
||||||
|
|
||||||
|
const int BUFFER_SIZE = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2);
|
||||||
|
StaticJsonBuffer<BUFFER_SIZE> jsonBuffer;
|
||||||
|
|
||||||
|
In the second case, let's say you dynamically generate a JSON object tree of a random complexity so you can't put a limit based on that. But on the other hand, you don't want your program to crash because the object tree doesn't fit in memory.
|
||||||
|
The solution here is to determine how much memory is available, or in other words how much memory you can afford for the JSON object tree.
|
||||||
|
|
||||||
|
### Why choosing fixed allocation?
|
||||||
|
|
||||||
|
This fixed allocation approach may seem a bit strange, especially if your a desktop application developer used to dynamic allocation, but it make a lot of sense in an embedded context:
|
||||||
|
|
||||||
|
1. the code is smaller
|
||||||
|
2. it uses less memory
|
||||||
|
3. it doesn't create memory fragmentation
|
||||||
|
4. it predictable
|
||||||
|
|
||||||
|
Don't forget that the memory is "freed" as soon as the `StaticJsonBuffer` is out of scope, like any other variable. It only hold the memory for a short amount of time.
|
||||||
|
|
||||||
|
## Memory usage
|
||||||
|
|
||||||
|
#### Object size for 8-bit AVR
|
||||||
|
|
||||||
|
| Type | Size |
|
||||||
|
|-------------------------|------------|
|
||||||
|
| JsonArray of N element | 4 + 8 * N |
|
||||||
|
| JsonObject of N element | 4 + 10 * N |
|
80
doc/Migrating code to new API.md
Normal file
80
doc/Migrating code to new API.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
Migrating code written for Arduino JSON v3 to v4
|
||||||
|
================================================
|
||||||
|
|
||||||
|
Arduino JSON v4 was a major rewrite of the library, and the API changed significantly.
|
||||||
|
|
||||||
|
## Includes
|
||||||
|
|
||||||
|
Arduino JSON v3 had two include files:
|
||||||
|
|
||||||
|
#include <JsonParser.h>
|
||||||
|
#include <JsonGenerator.h>
|
||||||
|
|
||||||
|
Arduino JSON v4 only has one:
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
## Namespaces
|
||||||
|
|
||||||
|
Arduino JSON v3 had two namespaces:
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Parser;
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
|
||||||
|
Arduino JSON v4 doesn't require the `using namespace` statement.
|
||||||
|
It has a namespace but the `using namespace` is done in the header file.
|
||||||
|
|
||||||
|
## StaticJsonBuffer
|
||||||
|
|
||||||
|
Arduino JSON v3 had different memory allocation models for the parser:
|
||||||
|
|
||||||
|
JsonParser<16> parser; // 16 being the capacity in "tokens"
|
||||||
|
|
||||||
|
and for the generator:
|
||||||
|
|
||||||
|
JsonArray<4> array; // 4 being the number of element
|
||||||
|
JsonObject<4> object;
|
||||||
|
|
||||||
|
Arduino JSON v4 only has one memory allocation model:
|
||||||
|
|
||||||
|
StaticJsonBuffer<128> buffer; // 128 being the capacity in bytes
|
||||||
|
|
||||||
|
## Return values for the parser
|
||||||
|
|
||||||
|
Arduino JSON v3 returned value types:
|
||||||
|
|
||||||
|
JsonArray array = parser.parseArray(json);
|
||||||
|
JsonObject object = parser.parseObject(json);
|
||||||
|
|
||||||
|
Arduino JSON v4 returns references types:
|
||||||
|
|
||||||
|
JsonArray& array = buffer.parseArray(json);
|
||||||
|
JsonObject& object = buffer.parseObject(json);
|
||||||
|
|
||||||
|
Everything else is compatible
|
||||||
|
|
||||||
|
## Creating arrays and objects
|
||||||
|
|
||||||
|
Arduino JSON v3 allowed to create `JsonArray` and `JsonObject` directly:
|
||||||
|
|
||||||
|
JsonArray<4> array;
|
||||||
|
JsonObject<4> object;
|
||||||
|
|
||||||
|
Arduino JSON v4 requires that you use a `StaticJsonBuffer` for that:
|
||||||
|
|
||||||
|
JsonArray& array = buffer.createArray();
|
||||||
|
JsonObject& object = buffer.createObject();
|
||||||
|
|
||||||
|
Note: you don't have to specify the capacity anymore.
|
||||||
|
|
||||||
|
## Printable interface
|
||||||
|
|
||||||
|
Arduino JSON v3 used to implement the Printable interface, which allowed statements like:
|
||||||
|
|
||||||
|
Serial.print(array);
|
||||||
|
|
||||||
|
But Arduino JSON v4 doesn't, instead you need to write this:
|
||||||
|
|
||||||
|
array.printTo(Serial);
|
||||||
|
|
||||||
|
Note: there was a good reason for removing that feature, and it's reducing the size of `JsonArray` and `JsonObject`.
|
30
doc/Using the library with Arduino.md
Normal file
30
doc/Using the library with Arduino.md
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
Using the library with Arduino
|
||||||
|
==============================
|
||||||
|
|
||||||
|
This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment.
|
||||||
|
If you don't use the Arduino IDE, please read [Using the library without Arduino](Using the library without Arduino.md).
|
||||||
|
|
||||||
|
## Install the library
|
||||||
|
|
||||||
|
[Download the zip package](https://github.com/bblanchon/ArduinoJson/releases) and extract it to:
|
||||||
|
|
||||||
|
<your Arduino Sketch folder>/libraries/ArduinoJson
|
||||||
|
|
||||||
|
Then restart the Arduino IDE.
|
||||||
|
|
||||||
|
## Run the examples sketches
|
||||||
|
|
||||||
|
Click `File` / `Example` / `ArduinoJson`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Use the library in your sketches
|
||||||
|
|
||||||
|
Just add the following line at the top of your program:
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
|
Then follow the instructions:
|
||||||
|
|
||||||
|
1. [Parsing JSON](Parsin JSON.md)
|
||||||
|
2. [Generating JSON](Generating JSON.md)
|
37
doc/Using the library without Arduino.md
Normal file
37
doc/Using the library without Arduino.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
Using the library without Arduino
|
||||||
|
=================================
|
||||||
|
|
||||||
|
This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment.
|
||||||
|
If you use the Arduino IDE, please read [Using the library with Arduino](Using the library with Arduino.md).
|
||||||
|
|
||||||
|
However, it can be used without Arduino IDE with very little effort.
|
||||||
|
|
||||||
|
## Compiling the library
|
||||||
|
|
||||||
|
Step 1: Download source code:
|
||||||
|
|
||||||
|
git clone https://github.com/bblanchon/ArduinoJson.git
|
||||||
|
|
||||||
|
Step 2: Generate the `Makefile` for your environment
|
||||||
|
|
||||||
|
cd ArduinoJson
|
||||||
|
cmake .
|
||||||
|
|
||||||
|
Step 3: Build
|
||||||
|
|
||||||
|
make
|
||||||
|
|
||||||
|
## File paths
|
||||||
|
|
||||||
|
Assuming you installed the library into `<arduino-json>`, you need to add:
|
||||||
|
|
||||||
|
1. `<arduino-json>/include` to your include path
|
||||||
|
2. `<arduino-json>/lib` to your library path
|
||||||
|
|
||||||
|
|
||||||
|
----------
|
||||||
|
|
||||||
|
You are now ready to follow the instructions:
|
||||||
|
|
||||||
|
1. [Parsing JSON](Parsin JSON.md)
|
||||||
|
2. [Generating JSON](Generating JSON.md)
|
@ -3,41 +3,28 @@
|
|||||||
* Benoit Blanchon 2014 - MIT License
|
* Benoit Blanchon 2014 - MIT License
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <JsonGenerator.h>
|
#include <ArduinoJson.h>
|
||||||
|
|
||||||
using namespace ArduinoJson::Generator;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
void setup()
|
void setup() {
|
||||||
{
|
Serial.begin(9600);
|
||||||
Serial.begin(9600);
|
|
||||||
|
IndentedPrint serial(Serial);
|
||||||
JsonObject<1> json;
|
serial.setTabSize(4);
|
||||||
json["key"] = "value";
|
|
||||||
|
serial.println("This is at indentation 0");
|
||||||
IndentedPrint serial(Serial);
|
serial.indent();
|
||||||
serial.setTabSize(4);
|
serial.println("This is at indentation 1");
|
||||||
|
serial.println("This is also at indentation 1");
|
||||||
serial.println("This is at indentation 0");
|
serial.indent();
|
||||||
serial.indent();
|
serial.println("This is at indentation 2");
|
||||||
serial.println("This is at indentation 1");
|
|
||||||
serial.println("This is also at indentation 1");
|
serial.unindent();
|
||||||
serial.indent();
|
serial.unindent();
|
||||||
serial.println("This is at indentation 2");
|
serial.println("This is back at indentation 0");
|
||||||
|
|
||||||
serial.println("You can print JSON here, as usual:");
|
|
||||||
serial.println(json);
|
|
||||||
serial.println();
|
|
||||||
|
|
||||||
serial.println("But you can also prettyPrint JSON here:");
|
|
||||||
json.prettyPrintTo(serial);
|
|
||||||
serial.println();
|
|
||||||
|
|
||||||
serial.unindent();
|
|
||||||
serial.unindent();
|
|
||||||
serial.println("This is back at indentation 0");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop() {
|
||||||
{
|
// not used in this example
|
||||||
|
|
||||||
}
|
}
|
@ -1,32 +1,42 @@
|
|||||||
/*
|
// Copyright Benoit Blanchon 2014
|
||||||
* Arduino JSON library - Generator example
|
// MIT License
|
||||||
* 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()
|
StaticJsonBuffer<200> jsonBuffer;
|
||||||
{
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
JsonArray<2> array;
|
JsonObject& root = jsonBuffer.createObject();
|
||||||
array.add<6>(48.756080); // 6 is the number of decimals to print
|
root["sensor"] = "gps";
|
||||||
array.add<6>(2.302038); // if not specified, 2 digits are printed
|
root["time"] = 1351824120;
|
||||||
|
|
||||||
JsonObject<3> root;
|
JsonArray& data = root.createNestedArray("data");
|
||||||
root["sensor"] = "gps";
|
data.add(48.756080, 6); // 6 is the number of decimals to print
|
||||||
root["time"] = 1351824120;
|
data.add(2.302038, 6); // if not specified, 2 digits are printed
|
||||||
root["data"] = array;
|
|
||||||
|
|
||||||
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();
|
Serial.println();
|
||||||
root.prettyPrintTo(Serial); // same string indented
|
|
||||||
|
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 @@
|
|||||||
/*
|
// Copyright Benoit Blanchon 2014
|
||||||
* Arduino JSON library - Parser Example
|
// MIT License
|
||||||
* 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()
|
StaticJsonBuffer<200> jsonBuffer;
|
||||||
{
|
|
||||||
Serial.begin(9600);
|
|
||||||
|
|
||||||
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())
|
const char* sensor = root["sensor"];
|
||||||
{
|
long time = root["time"];
|
||||||
Serial.println("JsonParser.parse() failed");
|
double latitude = root["data"][0];
|
||||||
return;
|
double longitude = root["data"][1];
|
||||||
}
|
|
||||||
|
|
||||||
char* sensor = root["sensor"];
|
Serial.println(sensor);
|
||||||
long time = root["time"];
|
Serial.println(time);
|
||||||
double latitude = root["data"][0];
|
Serial.println(latitude, 6);
|
||||||
double longitude = root["data"][1];
|
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
|
||||||
|
|
||||||
}
|
}
|
11
include/ArduinoJson.h
Normal file
11
include/ArduinoJson.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#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
|
||||||
|
// 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
|
54
include/ArduinoJson/Internals/IndentedPrint.hpp
Normal file
54
include/ArduinoJson/Internals/IndentedPrint.hpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014
|
||||||
|
// 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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
42
include/ArduinoJson/Internals/JsonParser.hpp
Normal file
42
include/ArduinoJson/Internals/JsonParser.hpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
// 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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
74
include/ArduinoJson/Internals/List.hpp
Normal file
74
include/ArduinoJson/Internals/List.hpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../JsonBuffer.hpp"
|
||||||
|
#include "ListConstIterator.hpp"
|
||||||
|
#include "ListIterator.hpp"
|
||||||
|
#include "PlacementNew.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;
|
||||||
|
void *ptr = _buffer->alloc(sizeof(node_type));
|
||||||
|
return ptr ? new (ptr) node_type() : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
// 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;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
40
include/ArduinoJson/Internals/ListIterator.hpp
Normal file
40
include/ArduinoJson/Internals/ListIterator.hpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ListNode.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ListNode<T> *_node;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
24
include/ArduinoJson/Internals/ListNode.hpp
Normal file
24
include/ArduinoJson/Internals/ListNode.hpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h> // for NULL
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
// A node for a singly-linked list.
|
||||||
|
// Used by List<T> and its iterators.
|
||||||
|
template <typename T>
|
||||||
|
struct ListNode {
|
||||||
|
ListNode() : next(NULL) {}
|
||||||
|
|
||||||
|
ListNode<T>* next;
|
||||||
|
T content;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
19
include/ArduinoJson/Internals/PlacementNew.hpp
Normal file
19
include/ArduinoJson/Internals/PlacementNew.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
// Copyright Benoit Blanchon 2014
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Arduino JSON library
|
||||||
|
// https://github.com/bblanchon/ArduinoJson
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef ARDUINO
|
||||||
|
|
||||||
|
// Declares the placement new as in <new>.
|
||||||
|
// This is required for Arduino IDE because it doesn't include the <new> header.
|
||||||
|
inline void *operator new(size_t, void *p) throw() { return p; }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
|
#endif
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user