forked from bblanchon/ArduinoJson
Compare commits
161 Commits
Author | SHA1 | Date | |
---|---|---|---|
a1b6c2df75 | |||
feb6060887 | |||
49d2b4b2a2 | |||
286a514fbe | |||
9d3b522e7b | |||
c32642e130 | |||
7a3fa35bd8 | |||
0154fc15cb | |||
24d173c3b9 | |||
d4c1b6f2c2 | |||
58c051f564 | |||
763aa7fe37 | |||
cd88fb0882 | |||
ec843659d8 | |||
2997a405a0 | |||
57f28c2017 | |||
b3b70b78cf | |||
48018bd6e6 | |||
61952a9bcd | |||
602cc104f9 | |||
d71a39211d | |||
f77a8b02e3 | |||
aa2cd0db00 | |||
f127ef6019 | |||
3ae7327687 | |||
23e61cc0f7 | |||
b5002265cf | |||
e48ea94789 | |||
6539c6982c | |||
d877d77b63 | |||
1df6cde026 | |||
fafae8181b | |||
151fc52c1c | |||
ea79340dc7 | |||
9e88514700 | |||
752378a8cb | |||
8465cc0c83 | |||
2ddf8f1619 | |||
f7aa0f89e3 | |||
3d322fdb28 | |||
981adf1989 | |||
dbc3bee3a0 | |||
3f2b7b706a | |||
c243417585 | |||
514a6c0879 | |||
76f9ecce75 | |||
410ca55e88 | |||
66c05041e8 | |||
aafabd8e8d | |||
eb1a774778 | |||
75c89e7b35 | |||
e31a2136fc | |||
380722402f | |||
030c8542e7 | |||
1f25d4434e | |||
f29904e217 | |||
7246db7691 | |||
4bdbc6c1fc | |||
8e6fdb20eb | |||
016d0d699e | |||
6771603a05 | |||
d067cf0e84 | |||
13593d73a3 | |||
bc86ae800a | |||
df52dceaa1 | |||
d460b59b50 | |||
8e5ea91f8d | |||
4a8b7d0cb4 | |||
96c9b5deee | |||
8e81b9bb26 | |||
817cc09975 | |||
1bc45f1fd7 | |||
d2fe9ddf49 | |||
5cc06180e6 | |||
65e8b6d405 | |||
09294cb5e6 | |||
158f4600fb | |||
0d28612507 | |||
7c99d4d63d | |||
1a01800782 | |||
6384bc414a | |||
c10bcee324 | |||
028ff6676e | |||
23b5237f74 | |||
88510705be | |||
15d3068d78 | |||
ae6beb9340 | |||
c1f4128ccd | |||
5fb6edfc91 | |||
2771b830b7 | |||
84aa627038 | |||
4528b8fc95 | |||
60c6f2db47 | |||
13c386c7a3 | |||
7877ee1b4c | |||
2c29327ebd | |||
85ffb83aa6 | |||
1ce6661fa6 | |||
68a2ca905e | |||
7e4ab9f31c | |||
44e5549456 | |||
3e36831cdc | |||
5129f3400c | |||
0449ee4fd3 | |||
6e4eb45210 | |||
abef85218e | |||
649f292ea7 | |||
805c0741e6 | |||
0fc54ba54c | |||
df72419f09 | |||
d3d0da2d7f | |||
407d536e06 | |||
c22473cf37 | |||
3e8861b1a0 | |||
f565a9b1b7 | |||
06026cc7d4 | |||
04f52733c2 | |||
c06f42659a | |||
e619b8f5bd | |||
1e28217393 | |||
a1e8c8800a | |||
00ad540f4e | |||
cd7a7b1533 | |||
0fe77176e1 | |||
e94575b4b8 | |||
b278d7711b | |||
851d21e08c | |||
b75d32e980 | |||
daa62b3737 | |||
ed497df9d6 | |||
79953730fc | |||
5d2ffc49fd | |||
714a37bd59 | |||
4a1d8483cc | |||
0d4d77a7cd | |||
c329572d24 | |||
ca01ecfb49 | |||
78249a0ada | |||
45c9ba1191 | |||
5e1697f47b | |||
f2579397d6 | |||
b6e3a37ad9 | |||
73eda08dd4 | |||
6164328892 | |||
7487b8cbb7 | |||
6a868e46bd | |||
d189bd7140 | |||
9f07cdcabf | |||
41b5bba939 | |||
7ac4a91591 | |||
5534635feb | |||
2e5b959e8b | |||
9ee3dc638d | |||
ccb97fc6e0 | |||
39c185ae67 | |||
cf1324c09b | |||
0b087b7bdb | |||
dde5a2510b | |||
a42b03ec26 | |||
2f98e59fc6 | |||
f58a8b0ca5 |
@ -7,6 +7,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonGeneratorTests", "JsonG
|
||||
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
|
||||
@ -21,6 +25,14 @@ Global
|
||||
{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
|
||||
|
13
BuildArduinoPackage.sh
Normal file
13
BuildArduinoPackage.sh
Normal file
@ -0,0 +1,13 @@
|
||||
#!/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
|
83
CHANGELOG.md
83
CHANGELOG.md
@ -1,10 +1,85 @@
|
||||
Arduino JSON library: change log
|
||||
================================
|
||||
Arduino JSON: change log
|
||||
========================
|
||||
|
||||
v3.4
|
||||
----
|
||||
|
||||
* Fixed escaped char parsing (issue #16)
|
||||
|
||||
|
||||
v3.3
|
||||
----
|
||||
|
||||
* Added indented output for the JSON generator (issue #11), see example bellow.
|
||||
* Added `IndentedPrint`, a decorator for `Print` to allow indented output
|
||||
|
||||
Example:
|
||||
|
||||
JsonOject<2> json;
|
||||
json["key"] = "value";
|
||||
json.prettyPrintTo(Serial);
|
||||
|
||||
v3.2
|
||||
----
|
||||
|
||||
* Fixed a bug when adding nested object in `JsonArray` (bug introduced in v3.1).
|
||||
|
||||
v3.1
|
||||
----
|
||||
|
||||
* Calling `Generator::JsonObject::add()` twice with the same `key` now replaces the `value`
|
||||
* Added `Generator::JsonObject::operator[]`, see bellow the new API
|
||||
* Added `Generator::JsonObject::remove()` (issue #9)
|
||||
|
||||
Old generator API:
|
||||
|
||||
JsonObject<3> root;
|
||||
root.add("sensor", "gps");
|
||||
root.add("time", 1351824120);
|
||||
root.add("data", array);
|
||||
|
||||
New generator API:
|
||||
|
||||
JsonObject<3> root;
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
root["data"] = array;
|
||||
|
||||
v3.0
|
||||
----
|
||||
|
||||
* New parser API, see bellow
|
||||
* Renamed `JsonHashTable` into `JsonObject`
|
||||
* Added iterators for `JsonArray` and `JsonObject` (issue #4)
|
||||
|
||||
Old parser API:
|
||||
|
||||
JsonHashTable root = parser.parseHashTable(json);
|
||||
|
||||
char* sensor = root.getString("sensor");
|
||||
long time = root.getLong("time");
|
||||
double latitude = root.getArray("data").getDouble(0);
|
||||
double longitude = root.getArray("data").getDouble(1);
|
||||
|
||||
New parser API:
|
||||
|
||||
JsonObject root = parser.parse(json);
|
||||
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
v2.1
|
||||
----
|
||||
|
||||
* Fixed case `#include "jsmn.cpp"` which caused an error in Linux (issue #6)
|
||||
* Fixed a buffer overrun in JSON Parser (issue #5)
|
||||
|
||||
v2.0
|
||||
----
|
||||
|
||||
* Added JSON encoding.
|
||||
* Added JSON encoding (issue #2)
|
||||
* Renamed the library `ArduinoJsonParser` becomes `ArduinoJson`
|
||||
|
||||
**Breaking change**: you need to add the following line at the top of your program.
|
||||
@ -14,7 +89,7 @@ v2.0
|
||||
v1.2
|
||||
----
|
||||
|
||||
* Example: changed `char[] json` into `char json[]`. Damn it C# !
|
||||
* Fixed error in JSON parser example (issue #1)
|
||||
|
||||
v1.1
|
||||
----
|
||||
|
@ -6,7 +6,10 @@
|
||||
// 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/JsonHashTableBase.cpp"
|
||||
#include "JsonGenerator/JsonPrettyPrint.cpp"
|
||||
#include "JsonGenerator/JsonPrintable.cpp"
|
||||
#include "JsonGenerator/StringBuilder.cpp"
|
@ -4,4 +4,4 @@
|
||||
*/
|
||||
|
||||
#include "JsonGenerator/JsonArray.h"
|
||||
#include "JsonGenerator/JsonHashTable.h"
|
||||
#include "JsonGenerator/JsonObject.h"
|
@ -30,10 +30,8 @@ static inline size_t printCharTo(char c, Print& p)
|
||||
: p.write(c);
|
||||
}
|
||||
|
||||
size_t EscapedString::printTo(Print& p) const
|
||||
size_t EscapedString::printTo(const char* s, Print& p)
|
||||
{
|
||||
const char* s = rawString;
|
||||
|
||||
if (!s) return p.print("null");
|
||||
|
||||
size_t n = p.write('\"');
|
||||
|
@ -14,16 +14,7 @@ namespace ArduinoJson
|
||||
class EscapedString
|
||||
{
|
||||
public:
|
||||
|
||||
void set(const char* s)
|
||||
{
|
||||
rawString = s;
|
||||
}
|
||||
|
||||
size_t printTo(Print&) const;
|
||||
|
||||
private:
|
||||
const char* rawString;
|
||||
static size_t printTo(const char*, Print&);
|
||||
};
|
||||
}
|
||||
}
|
45
JsonGenerator/IndentedPrint.cpp
Normal file
45
JsonGenerator/IndentedPrint.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#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;
|
||||
}
|
53
JsonGenerator/IndentedPrint.h
Normal file
53
JsonGenerator/IndentedPrint.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ namespace ArduinoJson
|
||||
}
|
||||
|
||||
private:
|
||||
Internals::JsonValue items[N];
|
||||
JsonValue items[N];
|
||||
};
|
||||
}
|
||||
}
|
@ -5,27 +5,50 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonObjectBase.h"
|
||||
#include "JsonPrintable.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
class JsonArrayBase : public JsonObjectBase
|
||||
class JsonArrayBase : public JsonPrintable
|
||||
{
|
||||
public:
|
||||
JsonArrayBase(Internals::JsonValue* items, int capacity)
|
||||
JsonArrayBase(JsonValue* items, int capacity)
|
||||
: items(items), capacity(capacity), count(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void add(T value)
|
||||
void add(const Printable& value)
|
||||
{
|
||||
if (count >= capacity) return;
|
||||
addIfPossible<const Printable&>(value);
|
||||
}
|
||||
|
||||
items[count++].set(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>
|
||||
@ -33,17 +56,24 @@ namespace ArduinoJson
|
||||
{
|
||||
if (count >= capacity) return;
|
||||
|
||||
Internals::JsonValue& v = items[count++];
|
||||
JsonValue& v = items[count++];
|
||||
v.set<DIGITS>(value);
|
||||
}
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
|
||||
using JsonObjectBase::printTo;
|
||||
using JsonPrintable::printTo;
|
||||
|
||||
private:
|
||||
Internals::JsonValue* items;
|
||||
int count, capacity;
|
||||
JsonValue* items;
|
||||
int capacity, count;
|
||||
|
||||
template<typename T>
|
||||
void addIfPossible(T value)
|
||||
{
|
||||
if (count < capacity)
|
||||
items[count++] = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
101
JsonGenerator/JsonGenerator.vcxproj
Normal file
101
JsonGenerator/JsonGenerator.vcxproj
Normal file
@ -0,0 +1,101 @@
|
||||
<?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>
|
84
JsonGenerator/JsonGenerator.vcxproj.filters
Normal file
84
JsonGenerator/JsonGenerator.vcxproj.filters
Normal file
@ -0,0 +1,84 @@
|
||||
<?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,27 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonHashTableBase.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
template<int N>
|
||||
class JsonHashTable : public JsonHashTableBase
|
||||
{
|
||||
public:
|
||||
JsonHashTable()
|
||||
: JsonHashTableBase(items, N)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
KeyValuePair items[N];
|
||||
};
|
||||
}
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonHashTable.h"
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
|
||||
size_t JsonHashTableBase::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 += current->key.printTo(p);
|
||||
n += p.write(':');
|
||||
n += current->value.printTo(p);
|
||||
|
||||
current++;
|
||||
|
||||
if (i > 1)
|
||||
{
|
||||
n += p.write(',');
|
||||
}
|
||||
}
|
||||
|
||||
n += p.write('}');
|
||||
|
||||
return n;
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonObjectBase.h"
|
||||
#include "EscapedString.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
class JsonHashTableBase : public JsonObjectBase
|
||||
{
|
||||
public:
|
||||
|
||||
template<typename T>
|
||||
void add(const char* key, T value)
|
||||
{
|
||||
if (count >= capacity) return;
|
||||
|
||||
items[count].key.set(key);
|
||||
items[count].value.set(value);
|
||||
count++;
|
||||
}
|
||||
|
||||
template<int DIGITS>
|
||||
void add(const char* key, double value)
|
||||
{
|
||||
if (count >= capacity) return;
|
||||
|
||||
items[count].key.set(key);
|
||||
items[count].value.set<DIGITS>(value);
|
||||
count++;
|
||||
}
|
||||
|
||||
using JsonObjectBase::printTo;
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
|
||||
protected:
|
||||
|
||||
struct KeyValuePair
|
||||
{
|
||||
Internals::EscapedString key;
|
||||
Internals::JsonValue value;
|
||||
};
|
||||
|
||||
JsonHashTableBase(KeyValuePair* items, int capacity)
|
||||
: items(items), capacity(capacity), count(0)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
KeyValuePair* items;
|
||||
int count;
|
||||
int capacity;
|
||||
};
|
||||
}
|
||||
}
|
44
JsonGenerator/JsonObject.h
Normal file
44
JsonGenerator/JsonObject.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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>
|
||||
{
|
||||
};
|
||||
}
|
||||
}
|
92
JsonGenerator/JsonObjectBase.cpp
Normal file
92
JsonGenerator/JsonObjectBase.cpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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,31 +1,62 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonPrintable.h"
|
||||
#include "JsonValue.h"
|
||||
#include "Print.h"
|
||||
#include "Printable.h"
|
||||
#include "EscapedString.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Generator
|
||||
{
|
||||
class JsonObjectBase : public Printable
|
||||
typedef const char* JsonKey;
|
||||
|
||||
class JsonObjectBase : public JsonPrintable
|
||||
{
|
||||
public:
|
||||
JsonValue& operator[](JsonKey);
|
||||
bool containsKey(JsonKey) const;
|
||||
void remove(JsonKey key);
|
||||
|
||||
size_t printTo(char* buffer, size_t bufferSize)
|
||||
template<typename T>
|
||||
void add(JsonKey key, T value)
|
||||
{
|
||||
using namespace Internals;
|
||||
|
||||
StringBuilder sb(buffer, bufferSize);
|
||||
return printTo(sb);
|
||||
operator[](key) = value;
|
||||
}
|
||||
|
||||
virtual size_t printTo(Print& p) const = 0;
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
97
JsonGenerator/JsonPrettyPrint.cpp
Normal file
97
JsonGenerator/JsonPrettyPrint.cpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
52
JsonGenerator/JsonPrettyPrint.h
Normal file
52
JsonGenerator/JsonPrettyPrint.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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();
|
||||
};
|
||||
}
|
||||
}
|
35
JsonGenerator/JsonPrintable.cpp
Normal file
35
JsonGenerator/JsonPrintable.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
40
JsonGenerator/JsonPrintable.h
Normal file
40
JsonGenerator/JsonPrintable.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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;
|
||||
};
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
#include "EscapedString.h"
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
size_t JsonValue::printBoolTo(const Content& c, Print& p)
|
||||
@ -28,5 +29,5 @@ size_t JsonValue::printPrintableTo(const Content& c, Print& p)
|
||||
|
||||
size_t JsonValue::printStringTo(const Content& c, Print& p)
|
||||
{
|
||||
return c.asString.printTo(p);
|
||||
return EscapedString::printTo(c.asString, p);
|
||||
}
|
@ -11,68 +11,109 @@
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Internals
|
||||
namespace Generator
|
||||
{
|
||||
class JsonValue
|
||||
{
|
||||
public:
|
||||
|
||||
void set(bool value)
|
||||
|
||||
void operator=(bool value)
|
||||
{
|
||||
printToImpl = &printBoolTo;
|
||||
content.asBool = value;
|
||||
}
|
||||
|
||||
void set(long value)
|
||||
void operator=(long value)
|
||||
{
|
||||
printToImpl = &printLongTo;
|
||||
content.asLong = value;
|
||||
}
|
||||
|
||||
void set(int value)
|
||||
void operator=(int value)
|
||||
{
|
||||
printToImpl = &printLongTo;
|
||||
content.asLong = value;
|
||||
}
|
||||
|
||||
void set(Printable& value)
|
||||
void operator=(const Printable& value)
|
||||
{
|
||||
printToImpl = &printPrintableTo;
|
||||
content.asPrintable = &value;
|
||||
}
|
||||
|
||||
void set(const char* value)
|
||||
void operator=(const char* value)
|
||||
{
|
||||
printToImpl = &printStringTo;
|
||||
content.asString.set(value);
|
||||
content.asString = value;
|
||||
}
|
||||
|
||||
void set(double value)
|
||||
void operator=(double value)
|
||||
{
|
||||
set<2>(value);
|
||||
}
|
||||
|
||||
template<int DIGITS>
|
||||
template <int DIGITS>
|
||||
void set(double value)
|
||||
{
|
||||
printToImpl = &printDoubleTo<DIGITS>;
|
||||
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;
|
||||
long asLong;
|
||||
Printable* asPrintable;
|
||||
EscapedString asString;
|
||||
double asDouble;
|
||||
bool asBool;
|
||||
double asDouble;
|
||||
long asLong;
|
||||
const Printable* asPrintable;
|
||||
const char* asString;
|
||||
};
|
||||
|
||||
Content content;
|
||||
@ -84,7 +125,7 @@ namespace ArduinoJson
|
||||
static size_t printPrintableTo(const Content&, Print&);
|
||||
static size_t printStringTo(const Content&, Print&);
|
||||
|
||||
template<int DIGITS>
|
||||
template <int DIGITS>
|
||||
static size_t printDoubleTo(const Content& c, Print& p)
|
||||
{
|
||||
return p.print(c.asDouble, DIGITS);
|
||||
|
@ -32,4 +32,9 @@ size_t Print::print(long value)
|
||||
return print(tmp);
|
||||
}
|
||||
|
||||
size_t Print::println()
|
||||
{
|
||||
return write('\r') + write('\n');
|
||||
}
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@ public:
|
||||
size_t print(const char[]);
|
||||
size_t print(double, int = 2);
|
||||
size_t print(long);
|
||||
size_t println();
|
||||
};
|
||||
|
||||
#else
|
||||
|
@ -1,9 +1,9 @@
|
||||
Arduino JSON library - Generator
|
||||
================================
|
||||
|
||||
This library is a simple JSON encoder for embedded systems.
|
||||
*An elegant and efficient JSON encoder for embedded systems.*
|
||||
|
||||
It's design to be very lightweight, works without any allocation on the heap (no malloc) and supports nested objects.
|
||||
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.
|
||||
|
||||
@ -11,11 +11,12 @@ It has been written with Arduino in mind, but it isn't linked to Arduino librari
|
||||
Features
|
||||
--------
|
||||
|
||||
* Supports nested objects
|
||||
* Elegant API, very easy to use
|
||||
* Fixed memory allocation (no malloc)
|
||||
* Small footprint
|
||||
* Implements Arduino's Printable interface
|
||||
* Supports nested objects
|
||||
* Supports indented output
|
||||
* Implements Arduino's `Printable interface
|
||||
* MIT License
|
||||
|
||||
|
||||
@ -23,13 +24,13 @@ Example
|
||||
-------
|
||||
|
||||
JsonArray<2> array;
|
||||
array.add<6>(48.756080);
|
||||
array.add<6>(2.302038);
|
||||
array.add<6>(48.756080); // <6> specifies the number of digits in the output
|
||||
array.add<6>(2.302038); // (the default is 2)
|
||||
|
||||
JsonHashTable<3> root;
|
||||
root.add("sensor", "gps");
|
||||
root.add("time", 1351824120);
|
||||
root.add("data", array);
|
||||
JsonObject<3> root;
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
root["data"] = array;
|
||||
|
||||
Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
|
||||
@ -50,12 +51,19 @@ 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 an array or an hash-table.
|
||||
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.
|
||||
|
||||
#### Array
|
||||
#### JSON Array
|
||||
|
||||
You create an array with the following line:
|
||||
|
||||
@ -73,7 +81,7 @@ Then you can add strings, integer, booleans, etc:
|
||||
array.add(42);
|
||||
array.add(true);
|
||||
|
||||
There are two syntaxes for the floating point values:
|
||||
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"
|
||||
@ -91,37 +99,69 @@ Finally you can add nested object to the array:
|
||||
|
||||
or
|
||||
|
||||
JsonHashTable<8> nestedHash;
|
||||
array.add(nestedHash);
|
||||
JsonObject<8> nestedObject;
|
||||
array.add(nestedObject);
|
||||
|
||||
#### Hash-table
|
||||
> ##### 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
|
||||
|
||||
You create a hash-table with the following line:
|
||||
#### JSON Object
|
||||
|
||||
JsonHashTable<8> hash;
|
||||
You create a JSON object (ie hash-table/dictionary) with the following line:
|
||||
|
||||
Like with the array class, there is a template parameter that gives the capacity of the hash-table.
|
||||
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:
|
||||
|
||||
hash.add("key1", "bazinga!");
|
||||
hash.add("key2", 42);
|
||||
hash.add("key3", true);
|
||||
object["key1"] = "bazinga!";
|
||||
object["key2"] = 42;
|
||||
object["key3"] = true;
|
||||
|
||||
As for the arrays, there are two syntaxes for the floating point values:
|
||||
|
||||
array.add<4>("key4", 3.1415); // 4 digits: "3.1415"
|
||||
array.add("key5", 3.14); // 2 digits: "3.14"
|
||||
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;
|
||||
hash.add("key6", nestedArray);
|
||||
object["key6"] = nestedArray;
|
||||
|
||||
or
|
||||
|
||||
JsonHashTable<8> nestedHash;
|
||||
hash.add("key7", nestedHash);
|
||||
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
|
||||
|
||||
@ -133,11 +173,18 @@ Both ways are the easy way :-)
|
||||
|
||||
#### Use a classic `char[]`
|
||||
|
||||
Whether you have a `JsonArray` or a `JsonHashTable`, simply call `printTo()` with the destination buffer, like so:
|
||||
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:
|
||||
@ -149,9 +196,9 @@ or
|
||||
array.printTo(Serial);
|
||||
|
||||
> ##### About the Printable interface
|
||||
> `JsonArray` and `JsonHashTable` implement Arduino's `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`...
|
||||
> You can do the same with any other implementation of `Print`: `HardwareSerial`, `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`...
|
||||
|
||||
|
||||
Memory usage
|
||||
@ -161,7 +208,40 @@ 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 |
|
||||
| JsonHashTable<N> | 8 + 8 x N |
|
||||
| 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 |
|
@ -16,8 +16,7 @@ namespace JsonGeneratorTests
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t returnValue;
|
||||
EscapedString escapedString;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(Null)
|
||||
@ -83,9 +82,8 @@ namespace JsonGeneratorTests
|
||||
private:
|
||||
void whenInputIs(const char* input)
|
||||
{
|
||||
StringBuilder sb(buffer, sizeof(buffer));
|
||||
escapedString.set(input);
|
||||
returnValue = escapedString.printTo(sb);
|
||||
StringBuilder sb(buffer, sizeof(buffer));
|
||||
returnValue = EscapedString::printTo(input, sb);
|
||||
}
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
|
73
JsonGeneratorTests/Issue10.cpp
Normal file
73
JsonGeneratorTests/Issue10.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#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);
|
||||
}
|
||||
};
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonHashTable.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
@ -14,7 +14,7 @@ namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonArrayTests)
|
||||
{
|
||||
JsonArray<2> arr;
|
||||
JsonArray<2> array;
|
||||
char buffer[256];
|
||||
|
||||
public:
|
||||
@ -26,111 +26,117 @@ namespace JsonGeneratorTests
|
||||
|
||||
TEST_METHOD(Null)
|
||||
{
|
||||
add((char*)0);
|
||||
array.add((char*) 0);
|
||||
|
||||
outputMustBe("[null]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneString)
|
||||
{
|
||||
add("hello");
|
||||
array.add("hello");
|
||||
|
||||
outputMustBe("[\"hello\"]");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
add("hello");
|
||||
add("world");
|
||||
array.add("hello");
|
||||
array.add("world");
|
||||
|
||||
outputMustBe("[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneStringOverCapacity)
|
||||
{
|
||||
add("hello");
|
||||
add("world");
|
||||
add("lost");
|
||||
array.add("hello");
|
||||
array.add("world");
|
||||
array.add("lost");
|
||||
|
||||
outputMustBe("[\"hello\",\"world\"]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleDefaultDigits)
|
||||
{
|
||||
add(3.14159265358979323846);
|
||||
array.add(3.14159265358979323846);
|
||||
outputMustBe("[3.14]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleFourDigits)
|
||||
{
|
||||
add<4>(3.14159265358979323846);
|
||||
array.add<4>(3.14159265358979323846);
|
||||
outputMustBe("[3.1416]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneInteger)
|
||||
{
|
||||
add(1);
|
||||
array.add(1);
|
||||
|
||||
outputMustBe("[1]");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoIntegers)
|
||||
{
|
||||
add(1);
|
||||
add(2);
|
||||
array.add(1);
|
||||
array.add(2);
|
||||
|
||||
outputMustBe("[1,2]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneIntegerOverCapacity)
|
||||
{
|
||||
add(1);
|
||||
add(2);
|
||||
add(3);
|
||||
array.add(1);
|
||||
array.add(2);
|
||||
array.add(3);
|
||||
|
||||
outputMustBe("[1,2]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneTrue)
|
||||
{
|
||||
add(true);
|
||||
array.add(true);
|
||||
|
||||
outputMustBe("[true]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneFalse)
|
||||
{
|
||||
add(false);
|
||||
array.add(false);
|
||||
|
||||
outputMustBe("[false]");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoBooleans)
|
||||
{
|
||||
add(false);
|
||||
add(true);
|
||||
array.add(false);
|
||||
array.add(true);
|
||||
|
||||
outputMustBe("[false,true]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneBooleanOverCapacity)
|
||||
{
|
||||
add(false);
|
||||
add(true);
|
||||
add(false);
|
||||
array.add(false);
|
||||
array.add(true);
|
||||
array.add(false);
|
||||
|
||||
outputMustBe("[false,true]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedArray)
|
||||
{
|
||||
addNested(JsonArray<1>());
|
||||
JsonArray<1> nestedArray;
|
||||
|
||||
array.add(nestedArray);
|
||||
|
||||
outputMustBe("[[]]");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedHash)
|
||||
{
|
||||
addNested(JsonHashTable<1>());
|
||||
JsonObject<1> nestedObject;
|
||||
|
||||
array.add(nestedObject);
|
||||
|
||||
outputMustBe("[{}]");
|
||||
}
|
||||
|
||||
@ -139,33 +145,16 @@ namespace JsonGeneratorTests
|
||||
JsonArray<1> nestedArray;
|
||||
nestedArray.add(1);
|
||||
|
||||
addNested(nestedArray);
|
||||
array.add(nestedArray);
|
||||
|
||||
outputMustBe("[[1]]");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void addNested(JsonObjectBase& value)
|
||||
{
|
||||
arr.add<JsonObjectBase&>(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void add(T value)
|
||||
{
|
||||
arr.add(value);
|
||||
}
|
||||
|
||||
template<int DIGITS>
|
||||
void add(double value)
|
||||
{
|
||||
arr.add<DIGITS>(value);
|
||||
}
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
{
|
||||
size_t n = arr.printTo(buffer, sizeof(buffer));
|
||||
size_t n = array.printTo(buffer, sizeof(buffer));
|
||||
Assert::AreEqual(expected, buffer);
|
||||
Assert::AreEqual(strlen(expected), n);
|
||||
}
|
||||
|
@ -55,7 +55,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>ARDUINO_JSON_NO_DEPRECATION_WARNING;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -84,29 +84,22 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\JsonGenerator\EscapedString.cpp" />
|
||||
<ClCompile Include="..\JsonGenerator\JsonArrayBase.cpp" />
|
||||
<ClCompile Include="..\JsonGenerator\JsonHashTableBase.cpp" />
|
||||
<ClCompile Include="..\JsonGenerator\JsonValue.cpp" />
|
||||
<ClCompile Include="..\JsonGenerator\StringBuilder.cpp" />
|
||||
<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="JsonHashTableTests.cpp" />
|
||||
<ClCompile Include="JsonValueTests.cpp" />
|
||||
<ClCompile Include="Print.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>
|
||||
<ClInclude Include="..\JsonGenerator\EscapedString.h" />
|
||||
<ClInclude Include="..\JsonGenerator\JsonArray.h" />
|
||||
<ClInclude Include="..\JsonGenerator\JsonArrayBase.h" />
|
||||
<ClInclude Include="..\JsonGenerator\JsonHashTable.h" />
|
||||
<ClInclude Include="..\JsonGenerator\JsonHashTableBase.h" />
|
||||
<ClInclude Include="..\JsonGenerator\JsonObjectBase.h" />
|
||||
<ClInclude Include="..\JsonGenerator\JsonValue.h" />
|
||||
<ClInclude Include="..\JsonGenerator\Print.h" />
|
||||
<ClInclude Include="..\JsonGenerator\Printable.h" />
|
||||
<ClInclude Include="..\JsonGenerator\StringBuilder.h" />
|
||||
<ProjectReference Include="..\JsonGenerator\JsonGenerator.vcxproj">
|
||||
<Project>{c6536d27-738d-4ceb-a2bc-e13c8897d894}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -18,67 +18,35 @@
|
||||
<ClCompile Include="JsonArrayTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonHashTableTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonValueTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonGenerator\JsonValue.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonGenerator\StringBuilder.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="StringBuilderTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Print.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonGenerator\EscapedString.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonGenerator\JsonHashTableBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonGenerator\JsonArrayBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EscapedStringTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\JsonGenerator\JsonArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\JsonHashTable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\JsonObjectBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\JsonValue.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\Print.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\Printable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\StringBuilder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\EscapedString.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\JsonHashTableBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonGenerator\JsonArrayBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<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,124 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonHashTable.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonHashTableTests)
|
||||
{
|
||||
JsonHashTable<2> hash;
|
||||
char buffer[256];
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(Empty)
|
||||
{
|
||||
outputMustBe("{}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneString)
|
||||
{
|
||||
add("key", "value");
|
||||
outputMustBe("{\"key\":\"value\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
add("key1", "value1");
|
||||
add("key2", "value2");
|
||||
|
||||
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneStringOverCapacity)
|
||||
{
|
||||
add("key1", "value1");
|
||||
add("key2", "value2");
|
||||
add("key3", "value3");
|
||||
|
||||
outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneInteger)
|
||||
{
|
||||
add("key", 1);
|
||||
outputMustBe("{\"key\":1}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleFourDigits)
|
||||
{
|
||||
add<4>("key", 3.14159265358979323846);
|
||||
outputMustBe("{\"key\":3.1416}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDoubleDefaultDigits)
|
||||
{
|
||||
add("key", 3.14159265358979323846);
|
||||
outputMustBe("{\"key\":3.14}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneNull)
|
||||
{
|
||||
add("key", (char*) 0);
|
||||
outputMustBe("{\"key\":null}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneTrue)
|
||||
{
|
||||
add("key", true);
|
||||
outputMustBe("{\"key\":true}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneFalse)
|
||||
{
|
||||
add("key", false);
|
||||
outputMustBe("{\"key\":false}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedArray)
|
||||
{
|
||||
addNested("key", JsonArray<1>());
|
||||
outputMustBe("{\"key\":[]}");
|
||||
}
|
||||
|
||||
TEST_METHOD(OneEmptyNestedHash)
|
||||
{
|
||||
addNested("key", JsonHashTable<1>());
|
||||
outputMustBe("{\"key\":{}}");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void addNested(const char* key, JsonObjectBase& value)
|
||||
{
|
||||
hash.add<JsonObjectBase&>(key, value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void add(const char* key, T value)
|
||||
{
|
||||
hash.add(key, value);
|
||||
}
|
||||
|
||||
template<int DIGITS>
|
||||
void add(const char* key, double value)
|
||||
{
|
||||
hash.add<DIGITS>(key, value);
|
||||
}
|
||||
|
||||
void outputMustBe(const char* expected)
|
||||
{
|
||||
size_t actual = hash.printTo(buffer, sizeof(buffer));
|
||||
Assert::AreEqual(expected, buffer);
|
||||
Assert::AreEqual(strlen(expected), actual);
|
||||
}
|
||||
};
|
||||
}
|
73
JsonGeneratorTests/JsonObject_Indexer_Tests.cpp
Normal file
73
JsonGeneratorTests/JsonObject_Indexer_Tests.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
}
|
152
JsonGeneratorTests/JsonObject_PrintTo_Tests.cpp
Normal file
152
JsonGeneratorTests/JsonObject_PrintTo_Tests.cpp
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
}
|
78
JsonGeneratorTests/JsonValue_Cast_Tests.cpp
Normal file
78
JsonGeneratorTests/JsonValue_Cast_Tests.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
}
|
@ -8,11 +8,12 @@
|
||||
#include "JsonValue.h"
|
||||
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Generator;
|
||||
using namespace ArduinoJson::Internals;
|
||||
|
||||
namespace JsonGeneratorTests
|
||||
{
|
||||
TEST_CLASS(JsonValueTests)
|
||||
TEST_CLASS(JsonValue_PrintTo_Tests)
|
||||
{
|
||||
char buffer[1024];
|
||||
size_t returnValue;
|
||||
@ -21,62 +22,62 @@ namespace JsonGeneratorTests
|
||||
|
||||
TEST_METHOD(String)
|
||||
{
|
||||
whenInputIs("hello");
|
||||
setValueTo("hello");
|
||||
outputMustBe("\"hello\"");
|
||||
}
|
||||
|
||||
TEST_METHOD(Float)
|
||||
{
|
||||
whenInputIs(3.1415f);
|
||||
setValueTo(3.1415f);
|
||||
outputMustBe("3.14");
|
||||
}
|
||||
|
||||
TEST_METHOD(DoubleZeroDigits)
|
||||
{
|
||||
whenInputIs<0>(3.14159265358979323846);
|
||||
setValueTo<0>(3.14159265358979323846);
|
||||
outputMustBe("3");
|
||||
}
|
||||
|
||||
TEST_METHOD(DoubleOneDigit)
|
||||
{
|
||||
whenInputIs<1>(3.14159265358979323846);
|
||||
setValueTo<1>(3.14159265358979323846);
|
||||
outputMustBe("3.1");
|
||||
}
|
||||
|
||||
TEST_METHOD(DoubleTwoDigits)
|
||||
{
|
||||
whenInputIs<2>(3.14159265358979323846);
|
||||
setValueTo<2>(3.14159265358979323846);
|
||||
outputMustBe("3.14");
|
||||
}
|
||||
|
||||
TEST_METHOD(Integer)
|
||||
{
|
||||
whenInputIs(314);
|
||||
setValueTo(314);
|
||||
outputMustBe("314");
|
||||
}
|
||||
|
||||
TEST_METHOD(Char)
|
||||
{
|
||||
whenInputIs('A');
|
||||
setValueTo('A');
|
||||
outputMustBe("65");
|
||||
}
|
||||
|
||||
TEST_METHOD(Short)
|
||||
{
|
||||
whenInputIs((short)314);
|
||||
setValueTo((short)314);
|
||||
outputMustBe("314");
|
||||
}
|
||||
|
||||
TEST_METHOD(Long)
|
||||
{
|
||||
whenInputIs(314159265L);
|
||||
setValueTo(314159265L);
|
||||
outputMustBe("314159265");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<int DIGITS>
|
||||
void whenInputIs(double value)
|
||||
void setValueTo(double value)
|
||||
{
|
||||
StringBuilder sb(buffer, sizeof(buffer));
|
||||
JsonValue jsonValue;
|
||||
@ -85,11 +86,11 @@ namespace JsonGeneratorTests
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void whenInputIs(T value)
|
||||
void setValueTo(T value)
|
||||
{
|
||||
StringBuilder sb(buffer, sizeof(buffer));
|
||||
JsonValue jsonValue;
|
||||
jsonValue.set(value);
|
||||
jsonValue = value;
|
||||
returnValue = jsonValue.printTo(sb);
|
||||
}
|
||||
|
91
JsonGeneratorTests/PrettyPrint_Array_Tests.cpp
Normal file
91
JsonGeneratorTests/PrettyPrint_Array_Tests.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
}
|
89
JsonGeneratorTests/PrettyPrint_Object_Tests.cpp
Normal file
89
JsonGeneratorTests/PrettyPrint_Object_Tests.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
};
|
||||
}
|
76
JsonGeneratorTests/PrettyPrint_String_Tests.cpp
Normal file
76
JsonGeneratorTests/PrettyPrint_String_Tests.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* 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,11 +1,13 @@
|
||||
/*
|
||||
* malloc-free JSON parser for Arduino
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
* 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/JsonHashTable.cpp"
|
||||
#include "JsonParser/JsonObjectBase.cpp"
|
||||
#include "JsonParser/Jsmn.cpp"
|
||||
#include "JsonParser/JsonObject.cpp"
|
||||
#include "JsonParser/JsonParserBase.cpp"
|
||||
#include "JsonParser/JsonValue.cpp"
|
||||
#include "JsonParser/JsonToken.cpp"
|
||||
#include "JsonParser/jsmn.cpp"
|
@ -4,66 +4,11 @@
|
||||
*/
|
||||
|
||||
#include "JsonArray.h"
|
||||
#include "JsonHashTable.h"
|
||||
#include "JsonObject.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
JsonArray::JsonArray(char* json, jsmntok_t* tokens)
|
||||
: JsonObjectBase(json, tokens)
|
||||
DEPRECATED JsonObject JsonArray::getHashTable(int index)
|
||||
{
|
||||
if (tokens == 0 || tokens[0].type != JSMN_ARRAY)
|
||||
makeInvalid();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Returns the token for the value at the specified index
|
||||
*/
|
||||
jsmntok_t* JsonArray::getToken(int index)
|
||||
{
|
||||
// sanity check
|
||||
if (json == 0 || tokens == 0 || index < 0 || index >= tokens[0].size)
|
||||
return 0;
|
||||
|
||||
// skip first token, it's the whole object
|
||||
jsmntok_t* currentToken = tokens + 1;
|
||||
|
||||
// skip all tokens before the specified index
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
// move forward: current + nested tokens
|
||||
currentToken += 1 + getNestedTokenCount(currentToken);
|
||||
}
|
||||
|
||||
return currentToken;
|
||||
}
|
||||
|
||||
JsonArray JsonArray::getArray(int index)
|
||||
{
|
||||
return JsonArray(json, getToken(index));
|
||||
}
|
||||
|
||||
bool JsonArray::getBool(int index)
|
||||
{
|
||||
return getBoolFromToken(getToken(index));
|
||||
}
|
||||
|
||||
double JsonArray::getDouble(int index)
|
||||
{
|
||||
return getDoubleFromToken(getToken(index));
|
||||
}
|
||||
|
||||
JsonHashTable JsonArray::getHashTable(int index)
|
||||
{
|
||||
return JsonHashTable(json, getToken(index));
|
||||
}
|
||||
|
||||
long JsonArray::getLong(int index)
|
||||
{
|
||||
return getLongFromToken(getToken(index));
|
||||
}
|
||||
|
||||
char* JsonArray::getString(int index)
|
||||
{
|
||||
return getStringFromToken(getToken(index));
|
||||
return operator[](index);
|
||||
}
|
@ -5,41 +5,99 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonObjectBase.h"
|
||||
#include "JsonValue.h"
|
||||
#include "JsonArrayIterator.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
class JsonHashTable;
|
||||
|
||||
class JsonArray : public JsonObjectBase
|
||||
{
|
||||
template <int N>
|
||||
friend class JsonParser;
|
||||
|
||||
friend class JsonHashTable;
|
||||
|
||||
class JsonObject;
|
||||
|
||||
// A JSON array
|
||||
class JsonArray : JsonValue
|
||||
{
|
||||
public:
|
||||
|
||||
JsonArray() {}
|
||||
|
||||
int getLength()
|
||||
// Create an invalid array
|
||||
JsonArray()
|
||||
{
|
||||
}
|
||||
|
||||
// Convert a JsonValue into a JsonArray
|
||||
JsonArray(JsonValue value)
|
||||
: JsonValue(value)
|
||||
{
|
||||
return tokens != 0 ? tokens[0].size : 0;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
JsonArray getArray(int index);
|
||||
bool getBool(int index);
|
||||
double getDouble(int index);
|
||||
JsonHashTable getHashTable(int index);
|
||||
long getLong(int index);
|
||||
char* getString(int index);
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED bool getBool(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
private:
|
||||
// Obsolete: Use operator[] instead
|
||||
DEPRECATED double getDouble(int index)
|
||||
{
|
||||
return operator[](index);
|
||||
}
|
||||
|
||||
JsonArray(char* json, jsmntok_t* tokens);
|
||||
jsmntok_t* getToken(int 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
46
JsonParser/JsonArrayIterator.h
Normal file
46
JsonParser/JsonArrayIterator.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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,85 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include <string.h> // for strcmp()
|
||||
#include "JsonArray.h"
|
||||
#include "JsonHashTable.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
JsonHashTable::JsonHashTable(char* json, jsmntok_t* tokens)
|
||||
: JsonObjectBase(json, tokens)
|
||||
{
|
||||
if (tokens == 0 || tokens[0].type != JSMN_OBJECT)
|
||||
makeInvalid();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the token for the value associated with the specified key
|
||||
*/
|
||||
jsmntok_t* JsonHashTable::getToken(const char* desiredKey)
|
||||
{
|
||||
// sanity check
|
||||
if (json == 0 || tokens == 0 || desiredKey == 0)
|
||||
return 0;
|
||||
|
||||
// skip first token, it's the whole object
|
||||
jsmntok_t* currentToken = tokens + 1;
|
||||
|
||||
// scan each keys
|
||||
for (int i = 0; i < tokens[0].size / 2 ; i++)
|
||||
{
|
||||
// get key token string
|
||||
char* key = getStringFromToken(currentToken);
|
||||
|
||||
// compare with desired name
|
||||
if (strcmp(desiredKey, key) == 0)
|
||||
{
|
||||
// return the value token that follows the key token
|
||||
return currentToken + 1;
|
||||
}
|
||||
|
||||
// move forward: key + value + nested tokens
|
||||
currentToken += 2 + getNestedTokenCount(currentToken + 1);
|
||||
}
|
||||
|
||||
// nothing found, return NULL
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool JsonHashTable::containsKey(const char* key)
|
||||
{
|
||||
return getToken(key) != 0;
|
||||
}
|
||||
|
||||
JsonArray JsonHashTable::getArray(const char* key)
|
||||
{
|
||||
return JsonArray(json, getToken(key));
|
||||
}
|
||||
|
||||
bool JsonHashTable::getBool(const char* key)
|
||||
{
|
||||
return getBoolFromToken(getToken(key));
|
||||
}
|
||||
|
||||
double JsonHashTable::getDouble(const char* key)
|
||||
{
|
||||
return getDoubleFromToken(getToken(key));
|
||||
}
|
||||
|
||||
JsonHashTable JsonHashTable::getHashTable(const char* key)
|
||||
{
|
||||
return JsonHashTable(json, getToken(key));
|
||||
}
|
||||
|
||||
long JsonHashTable::getLong(const char* key)
|
||||
{
|
||||
return getLongFromToken(getToken(key));
|
||||
}
|
||||
|
||||
char* JsonHashTable::getString(const char* key)
|
||||
{
|
||||
return getStringFromToken(getToken(key));
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonObjectBase.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
class JsonArray;
|
||||
|
||||
class JsonHashTable : public JsonObjectBase
|
||||
{
|
||||
template <int N>
|
||||
friend class JsonParser;
|
||||
|
||||
friend class JsonArray;
|
||||
|
||||
public:
|
||||
|
||||
JsonHashTable() {}
|
||||
|
||||
bool containsKey(const char* key);
|
||||
|
||||
JsonArray getArray(const char* key);
|
||||
bool getBool(const char* key);
|
||||
double getDouble(const char* key);
|
||||
JsonHashTable getHashTable(const char* key);
|
||||
long getLong(const char* key);
|
||||
char* getString(const char* key);
|
||||
|
||||
private:
|
||||
|
||||
JsonHashTable(char* json, jsmntok_t* tokens);
|
||||
jsmntok_t* getToken(const char* key);
|
||||
};
|
||||
}
|
||||
}
|
15
JsonParser/JsonObject.cpp
Normal file
15
JsonParser/JsonObject.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
102
JsonParser/JsonObject.h
Normal file
102
JsonParser/JsonObject.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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,67 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include <stdlib.h> // for strtol, strtod
|
||||
#include "JsonObjectBase.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
int JsonObjectBase::getNestedTokenCount(jsmntok_t* token)
|
||||
{
|
||||
int end = token->end;
|
||||
int count = 0;
|
||||
|
||||
token++;
|
||||
|
||||
while (token->start < end)
|
||||
{
|
||||
token++;
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool JsonObjectBase::getBoolFromToken(jsmntok_t* token)
|
||||
{
|
||||
if (token->type != JSMN_PRIMITIVE) return 0;
|
||||
|
||||
// "true"
|
||||
if (json[token->start] == 't') return true;
|
||||
|
||||
// "false"
|
||||
if (json[token->start] == 'f') return false;
|
||||
|
||||
// "null"
|
||||
if (json[token->start] == 'n') return false;
|
||||
|
||||
// number
|
||||
return strtol(json + token->start, 0, 0) != 0;
|
||||
}
|
||||
|
||||
double JsonObjectBase::getDoubleFromToken(jsmntok_t* token)
|
||||
{
|
||||
if (token == 0 || token->type != JSMN_PRIMITIVE) return 0;
|
||||
|
||||
return strtod(json + token->start, 0);
|
||||
}
|
||||
|
||||
long JsonObjectBase::getLongFromToken(jsmntok_t* token)
|
||||
{
|
||||
if (token == 0 || token->type != JSMN_PRIMITIVE) return 0;
|
||||
|
||||
return strtol(json + token->start, 0, 0);
|
||||
}
|
||||
|
||||
char* JsonObjectBase::getStringFromToken(jsmntok_t* token)
|
||||
{
|
||||
if (token == 0 || token->type != JSMN_PRIMITIVE && token->type != JSMN_STRING)
|
||||
return 0;
|
||||
|
||||
// add null terminator to the string
|
||||
json[token->end] = 0;
|
||||
|
||||
return json + token->start;
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsmn.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
class JsonObjectBase
|
||||
{
|
||||
public:
|
||||
|
||||
JsonObjectBase()
|
||||
{
|
||||
makeInvalid();
|
||||
}
|
||||
|
||||
bool success()
|
||||
{
|
||||
return json != 0 && tokens != 0;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
JsonObjectBase(char* json, jsmntok_t* tokens)
|
||||
{
|
||||
this->json = json;
|
||||
this->tokens = tokens;
|
||||
}
|
||||
|
||||
void makeInvalid()
|
||||
{
|
||||
json = 0;
|
||||
tokens = 0;
|
||||
}
|
||||
|
||||
static int getNestedTokenCount(jsmntok_t* token);
|
||||
|
||||
bool getBoolFromToken(jsmntok_t* token);
|
||||
double getDoubleFromToken(jsmntok_t* token);
|
||||
long getLongFromToken(jsmntok_t* token);
|
||||
char* getStringFromToken(jsmntok_t* token);
|
||||
|
||||
char* json;
|
||||
jsmntok_t* tokens;
|
||||
};
|
||||
}
|
||||
}
|
58
JsonParser/JsonObjectIterator.h
Normal file
58
JsonParser/JsonObjectIterator.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
37
JsonParser/JsonPair.h
Normal file
37
JsonParser/JsonPair.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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,70 +1,34 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonHashTable.h"
|
||||
#include "JsonArray.h"
|
||||
#include "JsonParserBase.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
/*
|
||||
* The JSON parser.
|
||||
*
|
||||
* You need to specifiy the number of token to be allocated for that parser.
|
||||
* Values from 16 to 32 are recommended.
|
||||
* The parser size will be MAX_TOKEN*8 bytes.
|
||||
* Don't forget that the memory size of standard Arduino board is only 2KB
|
||||
*
|
||||
* CAUTION: JsonArray and JsonHashTable 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 and JsonHashTable that have a
|
||||
* longer life that the JsonParser.
|
||||
*/
|
||||
// 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
|
||||
class JsonParser : public JsonParserBase
|
||||
{
|
||||
public:
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
JsonArray parseArray(char* json)
|
||||
JsonParser()
|
||||
: JsonParserBase(tokens, MAX_TOKENS)
|
||||
{
|
||||
return JsonArray(json, parse(json));
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
JsonHashTable parseHashTable(char* json)
|
||||
{
|
||||
return JsonHashTable(json, parse(json));
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
jsmntok_t* parse(char* json)
|
||||
{
|
||||
jsmn_parser parser;
|
||||
jsmn_init(&parser);
|
||||
|
||||
if (JSMN_SUCCESS != jsmn_parse(&parser, json, tokens, MAX_TOKENS))
|
||||
return 0;
|
||||
|
||||
return tokens;
|
||||
}
|
||||
|
||||
jsmntok_t tokens[MAX_TOKENS];
|
||||
};
|
||||
}
|
||||
|
96
JsonParser/JsonParser.vcxproj
Normal file
96
JsonParser/JsonParser.vcxproj
Normal file
@ -0,0 +1,96 @@
|
||||
<?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>
|
69
JsonParser/JsonParser.vcxproj.filters
Normal file
69
JsonParser/JsonParser.vcxproj.filters
Normal file
@ -0,0 +1,69 @@
|
||||
<?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>
|
20
JsonParser/JsonParserBase.cpp
Normal file
20
JsonParser/JsonParserBase.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
49
JsonParser/JsonParserBase.h
Normal file
49
JsonParser/JsonParserBase.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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;
|
||||
};
|
||||
}
|
||||
}
|
71
JsonParser/JsonToken.cpp
Normal file
71
JsonParser/JsonToken.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
99
JsonParser/JsonToken.h
Normal file
99
JsonParser/JsonToken.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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);
|
||||
};
|
||||
}
|
||||
}
|
110
JsonParser/JsonValue.cpp
Normal file
110
JsonParser/JsonValue.cpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* 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();
|
||||
}
|
72
JsonParser/JsonValue.h
Normal file
72
JsonParser/JsonValue.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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);
|
||||
};
|
||||
}
|
||||
}
|
@ -22,17 +22,15 @@ Features
|
||||
Example
|
||||
-------
|
||||
|
||||
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
JsonParser<32> parser;
|
||||
char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
|
||||
|
||||
JsonParser<32> parser;
|
||||
JsonObject root = parser.parse(json);
|
||||
|
||||
JsonHashTable root = parser.parseHashTable(json);
|
||||
|
||||
char* sensor = root.getString("sensor");
|
||||
|
||||
long time = root.getLong("time");
|
||||
|
||||
JsonArray coords = root.getArray("data");
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
|
||||
How to use ?
|
||||
@ -51,6 +49,13 @@ 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
|
||||
|
||||
@ -60,7 +65,7 @@ To extract data from the JSON string, you need to create a `JsonParser`, and spe
|
||||
|
||||
> #### How to choose the number of tokens ?
|
||||
|
||||
> A token is an element of the JSON object: either a key, a value, an hash-table or an array.
|
||||
> 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.
|
||||
@ -73,28 +78,24 @@ To extract data from the JSON string, you need to create a `JsonParser`, and spe
|
||||
|
||||
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 a hash-table (like `{"key":"value"}`) or an array (like `[1,2]`).
|
||||
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, hash-tables, numbers or strings.
|
||||
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.
|
||||
|
||||
#### Hash-table
|
||||
#### Object
|
||||
|
||||
Consider we have a `char json[]` containing to the following JSON string:
|
||||
|
||||
{
|
||||
"Name":"Blanchon",
|
||||
"Skills":[
|
||||
"C",
|
||||
"C++",
|
||||
"C#"],
|
||||
"Age":32,
|
||||
"Online":true
|
||||
"sensor":"gps",
|
||||
"time":1351824120,
|
||||
"data":[48.756080,2.302038]
|
||||
}
|
||||
|
||||
In this case the root object of the JSON string is a hash-table, so you need to extract a `JsonHashTable`:
|
||||
In this case the string contains a JSON object, so you need to extract a `JsonObject`:
|
||||
|
||||
JsonHashTable root = parser.parseHashTable(json);
|
||||
JsonObject root = parser.parse(json);
|
||||
|
||||
To check if the parsing was successful, you must check:
|
||||
|
||||
@ -105,13 +106,18 @@ To check if the parsing was successful, you must check:
|
||||
|
||||
And then extract the member you need:
|
||||
|
||||
char* name = hashTable.getString("Name");
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
JsonArray skills = hashTable.getArray("Skills");
|
||||
You can also iterate through the key-value pairs of the object:
|
||||
|
||||
int age = hashTable.getLong("Age");
|
||||
|
||||
bool online = hashTable.getBool("Online");
|
||||
for (JsonObjectIterator i=root.begin(); i!=root.end(); ++i)
|
||||
{
|
||||
Serial.println(i.key());
|
||||
Serial.println((char*)i.value());
|
||||
}
|
||||
|
||||
#### Array
|
||||
|
||||
@ -124,7 +130,7 @@ Consider we have a `char json[]` containing to the following JSON string:
|
||||
|
||||
In this case the root object of the JSON string is an array, so you need to extract a `JsonArray`:
|
||||
|
||||
JsonArray root = parser.parseArray(json);
|
||||
JsonArray root = parser.parse(json);
|
||||
|
||||
To check if the parsing was successful, you must check:
|
||||
|
||||
@ -135,20 +141,24 @@ To check if the parsing was successful, you must check:
|
||||
|
||||
And then extract the content by its index in the array:
|
||||
|
||||
JsonArray row0 = root.getArray(0);
|
||||
double a = row0.getDouble(0);
|
||||
|
||||
or simply:
|
||||
|
||||
double a = root.getArray(0).getDouble(0);
|
||||
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::parseArray()` or `JsonParser::parseHashTable()` failed.
|
||||
By design, the library has no way to tell you why `JsonParser::parse()` failed.
|
||||
|
||||
There are basically two reasons why they may fail:
|
||||
|
||||
@ -175,7 +185,7 @@ That is why an 8-bit processor is not able to parse long and complex JSON string
|
||||
|
||||
### 3. JsonParser not in memory
|
||||
|
||||
To reduce the memory consumption, `JsonArray` and `JsonHashTable` contains pointer to the token that are inside the `JsonParser`. This can only work if the `JsonParser` is still 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:
|
||||
|
||||
@ -191,7 +201,7 @@ because the local variable `parser` will be *removed* from memory when the funct
|
||||
|
||||
This will probably never be an issue, but you need to be aware of this feature.
|
||||
|
||||
When you pass a `char[]` to `JsonParser::parseArray()` or `JsonParser::parseHashTable()`, the content of the string will be altered to add `\0` at the end of the tokens.
|
||||
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.
|
||||
|
||||
@ -203,202 +213,38 @@ 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.
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Type</th>
|
||||
<th>Size in bytes</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Parser<N></td>
|
||||
<td>8 x N</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
| Type | Size in bytes |
|
||||
| ------------ | ------------- |
|
||||
| `Parser<N>` | 4 + 8 x N |
|
||||
| `JsonArray` | 4 |
|
||||
| `JsonObject` | 4 |
|
||||
| `JsonValue` | 4 |
|
||||
|
||||
Code size
|
||||
---------
|
||||
|
||||
Theses tables has been created by analyzing the map file generated by AVR-GCC after adding `-Wl,-Map,foo.map` to the command line.
|
||||
|
||||
As you'll see the code size is between 1680 and 3528 bytes, depending on the features you use.
|
||||
The sizes have been obtained with Arduino IDE 1.0.5 for a Duemilanove.
|
||||
|
||||
### Minimum setup
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Function</th>
|
||||
<th>Size in bytes</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>strcmp(char*,char*)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jsmn_init(jsmn_parser*)</td>
|
||||
<td>20</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>jsmn_parse(jsmn_parser*, char const*, jsmntok_t*, unsigned int)</td>
|
||||
<td>960</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonParser::parse(char*)</td>
|
||||
<td>106</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonObjectBase::getNestedTokenCount(jsmntok_t*)</td>
|
||||
<td>84</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonObjectBase::getStringFromToken(jsmntok_t*)</td>
|
||||
<td>68</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::JsonArray(char*, jsmntok_t*)</td>
|
||||
<td>42</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::getToken(int)</td>
|
||||
<td>112</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::getString(int)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::JsonHashTable(char*, jsmntok_t*)</td>
|
||||
<td>42</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::getToken(char*)</td>
|
||||
<td>180</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::getString(char*)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TOTAL</td>
|
||||
<td>1680</td>
|
||||
</tr>
|
||||
</table>
|
||||
| Function | Size |
|
||||
| ------------------------------------ | ---- |
|
||||
| `jsmn_parse()` | 962 |
|
||||
| `JsonValue::operator[](char const*)` | 218 |
|
||||
| `JsonParserBase::parse()` | 116 |
|
||||
| `JsonValue::operator[](int)` | 108 |
|
||||
| `strcmp()` | 18 |
|
||||
|
||||
### Additional space to parse nested objects
|
||||
### Additional space for integers
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Function</th>
|
||||
<th>Size in bytes</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::getArray(int)</td>
|
||||
<td>42</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::getHashTable(int)</td>
|
||||
<td>64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::getArray(char*)</td>
|
||||
<td>64</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::getHashTable(char*)</td>
|
||||
<td>42</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TOTAL</td>
|
||||
<td>212</td>
|
||||
</tr>
|
||||
</table>
|
||||
| Function | Size |
|
||||
| ---------------------------- | ---- |
|
||||
| `strtol()` | 606 |
|
||||
| `JsonValue::operator long()` | 94 |
|
||||
|
||||
### Additional space to parse `bool` values
|
||||
### Additional space for floating points
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Function</th>
|
||||
<th>Size in bytes</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonObjectBase::getBoolFromToken(jsmntok_t*)</td>
|
||||
<td>82</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::getBool(int)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::getBool(char*)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TOTAL</td>
|
||||
<td>130</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Additional space to parse `double` values
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Function</th>
|
||||
<th>Size in bytes</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>strtod(char*,int)</td>
|
||||
<td>704</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonObjectBase::getDoubleFromToken(jsmntok_t*)</td>
|
||||
<td>44</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::getDouble(int)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::getDouble(char*)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TOTAL</td>
|
||||
<td>796</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
### Additional space to parse `long` values
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>Function</th>
|
||||
<th>Size in bytes</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>strtol(char*,char**,int)</td>
|
||||
<td>606</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonObjectBase::getLongFromToken(jsmntok_t*)</td>
|
||||
<td>56</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonArray::getLong(int)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>JsonHashTable::getLong(char*)</td>
|
||||
<td>18</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>TOTAL</td>
|
||||
<td>710</td>
|
||||
</tr>
|
||||
</table>
|
||||
| Function | Size |
|
||||
| -------------------------------- | ----- |
|
||||
| `strtod()` | 1369 |
|
||||
| `JsonValue::operator double()` | 82 |
|
||||
|
@ -13,7 +13,7 @@ using namespace ArduinoJson::Parser;
|
||||
|
||||
namespace ArduinoJsonParserTests
|
||||
{
|
||||
TEST_CLASS(TestGbathreeSample1)
|
||||
TEST_CLASS(GbathreeBug)
|
||||
{
|
||||
char json[1024];
|
||||
JsonParser<200> parser;
|
67
JsonParserTests/JsonArrayIteratorTests.cpp
Normal file
67
JsonParserTests/JsonArrayIteratorTests.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
189
JsonParserTests/JsonArrayTests.cpp
Normal file
189
JsonParserTests/JsonArrayTests.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
};
|
||||
}
|
71
JsonParserTests/JsonObjectIteratorTests.cpp
Normal file
71
JsonParserTests/JsonObjectIteratorTests.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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++;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
165
JsonParserTests/JsonObjectTests.cpp
Normal file
165
JsonParserTests/JsonObjectTests.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
};
|
||||
}
|
@ -56,7 +56,7 @@
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessorDefinitions>ARDUINO_JSON_NO_DEPRECATION_WARNING;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<UseFullPaths>true</UseFullPaths>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@ -85,21 +85,17 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\JsonParser\jsmn.cpp" />
|
||||
<ClCompile Include="..\JsonParser\JsonArray.cpp" />
|
||||
<ClCompile Include="..\JsonParser\JsonHashTable.cpp" />
|
||||
<ClCompile Include="..\JsonParser\JsonObjectBase.cpp" />
|
||||
<ClCompile Include="TestArrayExample.cpp" />
|
||||
<ClCompile Include="TestArrays.cpp" />
|
||||
<ClCompile Include="TestHashTableExample.cpp" />
|
||||
<ClCompile Include="TestGbathreeStrings.cpp" />
|
||||
<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>
|
||||
<ClInclude Include="..\JsonParser\jsmn.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonArray.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonHashTable.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonObjectBase.h" />
|
||||
<ClInclude Include="..\JsonParser\JsonParser.h" />
|
||||
<ProjectReference Include="..\JsonParser\JsonParser.vcxproj">
|
||||
<Project>{c15274de-2695-4dfe-8520-4424223fe6da}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
@ -15,46 +15,23 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="TestHashTableExample.cpp">
|
||||
<ClCompile Include="GbathreeBug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestArrayExample.cpp">
|
||||
<ClCompile Include="JsonObjectTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestGbathreeStrings.cpp">
|
||||
<ClCompile Include="JsonArrayIteratorTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="TestArrays.cpp">
|
||||
<ClCompile Include="JsonObjectIteratorTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonParser\jsmn.cpp">
|
||||
<ClCompile Include="JsonArrayTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonParser\JsonArray.cpp">
|
||||
<ClCompile Include="JsonStringTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonParser\JsonHashTable.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonParser\JsonObjectBase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\JsonParser\jsmn.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonParser\JsonArray.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonParser\JsonHashTable.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonParser\JsonObjectBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\JsonParser\JsonParser.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
107
JsonParserTests/JsonStringTests.cpp
Normal file
107
JsonParserTests/JsonStringTests.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* 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,56 +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(TestArrayExample)
|
||||
{
|
||||
char json[128];
|
||||
JsonParser<32> parser;
|
||||
JsonArray array;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD_INITIALIZE(Initialize)
|
||||
{
|
||||
strcpy(json, "[[1.2,3.4],[5.6,7.8]]");
|
||||
array = parser.parseArray(json);
|
||||
}
|
||||
|
||||
TEST_METHOD(Array_Success_ReturnsTrue)
|
||||
{
|
||||
Assert::IsTrue(array.success());
|
||||
}
|
||||
|
||||
TEST_METHOD(Array_GetLength_Returns2)
|
||||
{
|
||||
Assert::AreEqual(2, array.getLength());
|
||||
}
|
||||
|
||||
TEST_METHOD(Array_GetArray0_ReturnsInnerArray0)
|
||||
{
|
||||
JsonArray innerArray = array.getArray(0);
|
||||
|
||||
Assert::AreEqual(2, innerArray.getLength());
|
||||
Assert::AreEqual(1.2, innerArray.getDouble(0));
|
||||
Assert::AreEqual(3.4, innerArray.getDouble(1));
|
||||
}
|
||||
|
||||
TEST_METHOD(Array_GetArray1_ReturnsInnerArray1)
|
||||
{
|
||||
JsonArray innerArray = array.getArray(1);
|
||||
|
||||
Assert::AreEqual(2, innerArray.getLength());
|
||||
Assert::AreEqual(5.6, innerArray.getDouble(0));
|
||||
Assert::AreEqual(7.8, innerArray.getDouble(1));
|
||||
}
|
||||
};
|
||||
}
|
@ -1,147 +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(TestArrays)
|
||||
{
|
||||
JsonParser<32> parser;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(EmptyString)
|
||||
{
|
||||
char json[] = "";
|
||||
|
||||
JsonArray array = parser.parseArray(json);
|
||||
Assert::IsFalse(array.success());
|
||||
}
|
||||
|
||||
TEST_METHOD(EmptyArray)
|
||||
{
|
||||
char json[] = "[]";
|
||||
|
||||
JsonArray array = parser.parseArray(json);
|
||||
Assert::IsTrue(array.success());
|
||||
}
|
||||
|
||||
TEST_METHOD(TooFewClosingBrackets)
|
||||
{
|
||||
char json[] = "[[]";
|
||||
|
||||
JsonArray array = parser.parseArray(json);
|
||||
Assert::IsFalse(array.success());
|
||||
}
|
||||
|
||||
TEST_METHOD(TooManyClosingBrackets)
|
||||
{
|
||||
char json[] = "[]]";
|
||||
|
||||
JsonArray array = parser.parseArray(json);
|
||||
Assert::IsFalse(array.success());
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDimensionArray)
|
||||
{
|
||||
char json [] = "[0,0]";
|
||||
|
||||
JsonArray array = parser.parseArray(json);
|
||||
Assert::IsTrue(array.success());
|
||||
Assert::AreEqual(2, array.getLength());
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
Assert::AreEqual(0L, array.getLong(i));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoDimensionsArray)
|
||||
{
|
||||
char json[] = "[[0,0],[0,0]]";
|
||||
|
||||
JsonArray array1 = parser.parseArray(json);
|
||||
Assert::IsTrue(array1.success());
|
||||
Assert::AreEqual(2, array1.getLength());
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
JsonArray array2 = array1.getArray(i);
|
||||
|
||||
Assert::AreEqual(2, array2.getLength());
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
Assert::AreEqual(0L, array2.getLong(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(TreeDimensionsArray)
|
||||
{
|
||||
char json[] = "[[[0,0],[0,0]],[[0,0],[0,0]]]";
|
||||
|
||||
JsonArray array1 = parser.parseArray(json);
|
||||
Assert::IsTrue(array1.success());
|
||||
Assert::AreEqual(2, array1.getLength());
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
JsonArray array2 = array1.getArray(i);
|
||||
|
||||
Assert::AreEqual(2, array2.getLength());
|
||||
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
JsonArray array3 = array2.getArray(j);
|
||||
|
||||
Assert::AreEqual(2, array3.getLength());
|
||||
|
||||
for (int k = 0; k < 2; k++)
|
||||
{
|
||||
Assert::AreEqual(0L, array3.getLong(k));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_METHOD(OneDimensionArrayInHashTable)
|
||||
{
|
||||
char json[] = "{a:[0,0],b:[0,0]}";
|
||||
|
||||
JsonHashTable root = parser.parseHashTable(json);
|
||||
Assert::IsTrue(root.success());
|
||||
|
||||
JsonArray arrayA = root.getArray("a");
|
||||
Assert::IsTrue(arrayA.success());
|
||||
Assert::AreEqual(2, arrayA.getLength());
|
||||
|
||||
JsonArray arrayB = root.getArray("b");
|
||||
Assert::IsTrue(arrayB.success());
|
||||
Assert::AreEqual(2, arrayB.getLength());
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoDimensionsArrayInHashTable)
|
||||
{
|
||||
char json[] = "{a:[[0],[0]],b:[[0],[0]]}";
|
||||
|
||||
JsonHashTable root = parser.parseHashTable(json);
|
||||
Assert::IsTrue(root.success());
|
||||
|
||||
JsonArray arrayA = root.getArray("a");
|
||||
Assert::IsTrue(arrayA.success());
|
||||
Assert::AreEqual(2, arrayA.getLength());
|
||||
|
||||
JsonArray arrayB = root.getArray("b");
|
||||
Assert::IsTrue(arrayB.success());
|
||||
Assert::AreEqual(2, arrayB.getLength());
|
||||
}
|
||||
};
|
||||
}
|
@ -1,67 +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(TestHashTableExample)
|
||||
{
|
||||
char json[128];
|
||||
JsonParser<32> parser;
|
||||
JsonHashTable hashTable;
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD_INITIALIZE(Initialize)
|
||||
{
|
||||
strcpy(json, "{\"Name\":\"Blanchon\",\"Skills\":[\"C\",\"C++\",\"C#\"],\"Age\":32,\"Online\":true}");
|
||||
hashTable = parser.parseHashTable(json);
|
||||
}
|
||||
|
||||
TEST_METHOD(HashTable_Success_ReturnsTrue)
|
||||
{
|
||||
Assert::IsTrue(hashTable.success());
|
||||
}
|
||||
|
||||
TEST_METHOD(HashTable_GetString_ReturnsExpectedValue)
|
||||
{
|
||||
string name = hashTable.getString("Name");
|
||||
Assert::AreEqual(name, string("Blanchon"));
|
||||
}
|
||||
|
||||
TEST_METHOD(HashTable_GetArray_ReturnsExpectedValue)
|
||||
{
|
||||
JsonArray skills = hashTable.getArray("Skills");
|
||||
|
||||
string skill0 = skills.getString(0);
|
||||
Assert::AreEqual(skill0, string("C"));
|
||||
|
||||
string skill1 = skills.getString(1);
|
||||
Assert::AreEqual(skill1, string("C++"));
|
||||
|
||||
string skill2 = skills.getString(2);
|
||||
Assert::AreEqual(skill2, string("C#"));
|
||||
}
|
||||
|
||||
TEST_METHOD(HashTable_GetLong_ReturnsExpectedValue)
|
||||
{
|
||||
int age = hashTable.getLong("Age");
|
||||
Assert::AreEqual(32, age);
|
||||
}
|
||||
|
||||
TEST_METHOD(HashTable_GetBool_ReturnsExpectedValue)
|
||||
{
|
||||
bool online = hashTable.getBool("Online");
|
||||
Assert::AreEqual(true, online);
|
||||
}
|
||||
};
|
||||
}
|
10
LICENSE.md
Normal file
10
LICENSE.md
Normal file
@ -0,0 +1,10 @@
|
||||
The MIT License (MIT)
|
||||
---------------------
|
||||
|
||||
Copyright © 2014 Benoit BLANCHON
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
README.md
22
README.md
@ -1,17 +1,17 @@
|
||||
Arduino JSON library
|
||||
====================
|
||||
|
||||
*A simple and efficient JSON library for embedded systems.*
|
||||
*An elegant and efficient JSON library for embedded systems.*
|
||||
|
||||
It's design to be very lightweight, 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).
|
||||
|
||||
It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* JSON decoding: [more details here](/JsonParser/)
|
||||
* JSON encoding: [more details here](/JsonGenerator/)
|
||||
* JSON decoding: [see documentation here](/JsonParser/)
|
||||
* JSON encoding: [see documentation here](/JsonGenerator/)
|
||||
* Elegant API, very easy to use
|
||||
* Fixed memory allocation (no malloc)
|
||||
* Small footprint
|
||||
@ -22,9 +22,9 @@ Feature comparison
|
||||
|
||||
| Library | Memory allocation | Nested objects | Parser size | Encoder size |
|
||||
| ------------ | ----------------- | -------------- | ----------- | ------------- |
|
||||
| Arduino JSON | static | yes | 2616 Bytes | 628 bytes |
|
||||
| json-arduino | dynamic | no | 3348 (+28%) | not supported |
|
||||
| aJson | dynamic | yes | 5088 (+94%) | 4678 (+640%) |
|
||||
| Arduino JSON | static | yes | 2760 Bytes | 862 bytes |
|
||||
| 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}`.
|
||||
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).
|
||||
@ -49,8 +49,10 @@ From Arduino's Forum user `gbathree`:
|
||||
From StackOverflow user `thegreendroid`:
|
||||
> It has a really elegant, simple API and it works like a charm on embedded and Windows/Linux platforms. We recently started using this on an embedded project and I can vouch for its quality.
|
||||
|
||||
Links
|
||||
Related blog posts
|
||||
-----
|
||||
|
||||
* [The project for which I made me this library](http://blog.benoitblanchon.fr/rfid-payment-terminal/)
|
||||
* [Blog post on the motivation for this library](http://blog.benoitblanchon.fr/arduino-json-parser/)
|
||||
* [The project I originally wrote this library for](http://blog.benoitblanchon.fr/rfid-payment-terminal/)
|
||||
* [Motivation for this library](http://blog.benoitblanchon.fr/arduino-json-parser/)
|
||||
* [Release of version 2](http://blog.benoitblanchon.fr/arduino-json-v2-0/)
|
||||
* [Release of version 3](http://blog.benoitblanchon.fr/arduino-json-v3-0/)
|
43
examples/IndentedPrintExample/IndentedPrintExample.ino
Normal file
43
examples/IndentedPrintExample/IndentedPrintExample.ino
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Arduino JSON library - IndentedPrint example
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include <JsonGenerator.h>
|
||||
|
||||
using namespace ArduinoJson::Generator;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(9600);
|
||||
|
||||
JsonObject<1> json;
|
||||
json["key"] = "value";
|
||||
|
||||
IndentedPrint serial(Serial);
|
||||
serial.setTabSize(4);
|
||||
|
||||
serial.println("This is at indentation 0");
|
||||
serial.indent();
|
||||
serial.println("This is at indentation 1");
|
||||
serial.println("This is also at indentation 1");
|
||||
serial.indent();
|
||||
serial.println("This is at indentation 2");
|
||||
|
||||
serial.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()
|
||||
{
|
||||
|
||||
}
|
@ -15,12 +15,15 @@ void setup()
|
||||
array.add<6>(48.756080); // 6 is the number of decimals to print
|
||||
array.add<6>(2.302038); // if not specified, 2 digits are printed
|
||||
|
||||
JsonHashTable<3> root;
|
||||
root.add("sensor", "gps");
|
||||
root.add("time", 1351824120);
|
||||
root.add("data", array);
|
||||
JsonObject<3> root;
|
||||
root["sensor"] = "gps";
|
||||
root["time"] = 1351824120;
|
||||
root["data"] = array;
|
||||
|
||||
Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||
|
||||
Serial.println();
|
||||
root.prettyPrintTo(Serial); // same string indented
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
@ -11,31 +11,27 @@ void setup()
|
||||
{
|
||||
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;
|
||||
|
||||
JsonHashTable root = parser.parseHashTable(json);
|
||||
JsonObject root = parser.parse(json);
|
||||
|
||||
if (!root.success())
|
||||
{
|
||||
Serial.println("JsonParser.parseHashTable() failed");
|
||||
Serial.println("JsonParser.parse() failed");
|
||||
return;
|
||||
}
|
||||
|
||||
char* sensor = root.getString("sensor");
|
||||
Serial.println(sensor);
|
||||
char* sensor = root["sensor"];
|
||||
long time = root["time"];
|
||||
double latitude = root["data"][0];
|
||||
double longitude = root["data"][1];
|
||||
|
||||
long time = root.getLong("time");
|
||||
Serial.println(sensor);
|
||||
Serial.println(time);
|
||||
|
||||
JsonArray coords = root.getArray("data");
|
||||
|
||||
for (int i = 0; i < coords.getLength(); i++)
|
||||
{
|
||||
double value = coords.getDouble(i);
|
||||
Serial.println(value, 6);
|
||||
}
|
||||
Serial.println(latitude, 6);
|
||||
Serial.println(longitude, 6);
|
||||
}
|
||||
|
||||
void loop()
|
||||
|
12
keywords.txt
12
keywords.txt
@ -1,10 +1,6 @@
|
||||
JsonParser KEYWORD1
|
||||
JsonArray KEYWORD1
|
||||
JsonHashTable KEYWORD1
|
||||
getArray KEYWORD2
|
||||
getBool KEYWORD2
|
||||
getDouble KEYWORD2
|
||||
getHashTableKEYWORD2
|
||||
getLong KEYWORD2
|
||||
parseArray KEYWORD2
|
||||
parseHashTable KEYWORD2
|
||||
JsonObject KEYWORD1
|
||||
add KEYWORD2
|
||||
parse KEYWORD2
|
||||
success KEYWORD2
|
||||
|
Reference in New Issue
Block a user