forked from bblanchon/ArduinoJson
Compare commits
137 Commits
Author | SHA1 | Date | |
---|---|---|---|
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 |
@ -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
|
63
CHANGELOG.md
63
CHANGELOG.md
@ -1,6 +1,69 @@
|
||||
Arduino JSON: change log
|
||||
========================
|
||||
|
||||
v3.3
|
||||
----
|
||||
|
||||
* Added indented output for the JSON generator, 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()`
|
||||
|
||||
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`
|
||||
|
||||
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
|
||||
----
|
||||
|
||||
|
@ -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;
|
||||
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,61 +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 capacity, count;
|
||||
};
|
||||
}
|
||||
}
|
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,12 +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/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,39 +5,99 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonObjectBase.h"
|
||||
#include "JsonValue.h"
|
||||
#include "JsonArrayIterator.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
class JsonHashTable;
|
||||
|
||||
class JsonArray : public JsonObjectBase
|
||||
{
|
||||
friend class JsonParserBase;
|
||||
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,40 +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
|
||||
{
|
||||
friend class JsonParserBase;
|
||||
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 tokensToVisit = token->size;
|
||||
int count = 0;
|
||||
|
||||
while (tokensToVisit)
|
||||
{
|
||||
count++;
|
||||
token++;
|
||||
tokensToVisit--;
|
||||
tokensToVisit += token->size;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool JsonObjectBase::getBoolFromToken(jsmntok_t* token)
|
||||
{
|
||||
if (token == 0 || 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,7 +1,7 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -11,19 +11,14 @@ 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 : public JsonParserBase
|
||||
{
|
||||
|
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>
|
@ -4,16 +4,17 @@
|
||||
*/
|
||||
|
||||
#include "JsonParserBase.h"
|
||||
#include "JsonToken.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
jsmntok_t* JsonParserBase::parse(char* json)
|
||||
JsonValue JsonParserBase::parse(char* json)
|
||||
{
|
||||
jsmn_parser parser;
|
||||
jsmn_init(&parser);
|
||||
|
||||
if (JSMN_SUCCESS != jsmn_parse(&parser, json, tokens, maxTokens))
|
||||
return 0;
|
||||
return JsonToken::null();
|
||||
|
||||
return tokens;
|
||||
return JsonToken(json, tokens);
|
||||
}
|
||||
|
@ -1,53 +1,49 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "JsonHashTable.h"
|
||||
#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
|
||||
*/
|
||||
JsonArray parseArray(char* 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
|
||||
JsonValue parse(char* json);
|
||||
|
||||
// Obsolete: use parse() instead
|
||||
DEPRECATED JsonArray parseArray(char* json)
|
||||
{
|
||||
return JsonArray(json, parse(json));
|
||||
return 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)
|
||||
// Obsolete: use parse() instead
|
||||
DEPRECATED JsonObject parseHashTable(char* json)
|
||||
{
|
||||
return JsonHashTable(json, parse(json));
|
||||
return parse(json);
|
||||
}
|
||||
|
||||
private:
|
||||
jsmntok_t* tokens;
|
||||
int maxTokens;
|
||||
|
||||
jsmntok_t* parse(char* json);
|
||||
};
|
||||
}
|
||||
}
|
27
JsonParser/JsonToken.cpp
Normal file
27
JsonParser/JsonToken.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#include "JsonToken.h"
|
||||
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
JsonToken JsonToken::nextSibling() const
|
||||
{
|
||||
// start with current token
|
||||
jsmntok_t* t = token;
|
||||
|
||||
// count the number of token to skip
|
||||
int yetToVisit = 1;
|
||||
|
||||
// skip all nested tokens
|
||||
while (yetToVisit)
|
||||
{
|
||||
yetToVisit += t->size - 1;
|
||||
t++;
|
||||
}
|
||||
|
||||
// build a JsonToken at the new location
|
||||
return JsonToken(json, t);
|
||||
}
|
100
JsonParser/JsonToken.h
Normal file
100
JsonParser/JsonToken.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Arduino JSON library
|
||||
* Benoit Blanchon 2014 - MIT License
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "jsmn.h"
|
||||
|
||||
namespace ArduinoJson
|
||||
{
|
||||
namespace Parser
|
||||
{
|
||||
// A pointer to a JSON token
|
||||
class JsonToken
|
||||
{
|
||||
public:
|
||||
|
||||
// Create a "null" pointer
|
||||
JsonToken()
|
||||
: token(0)
|
||||
{
|
||||
}
|
||||
|
||||
// Create a pointer to the specified JSON token
|
||||
JsonToken(char* json, jsmntok_t* token)
|
||||
: json(json), token(token)
|
||||
{
|
||||
}
|
||||
|
||||
// Get content of the JSON token
|
||||
char* getText()
|
||||
{
|
||||
json[token->end] = 0;
|
||||
return json + token->start;
|
||||
}
|
||||
|
||||
// Get the number of children tokens
|
||||
int childrenCount()
|
||||
{
|
||||
return token->size;
|
||||
}
|
||||
|
||||
// Get a pointer to the first child of the current token
|
||||
JsonToken firstChild() const
|
||||
{
|
||||
return JsonToken(json, token + 1);
|
||||
}
|
||||
|
||||
// Get a pointer to the next sibling token (ie skiping the children tokens)
|
||||
JsonToken nextSibling() const;
|
||||
|
||||
// Test equality
|
||||
bool operator!=(const JsonToken& other) const
|
||||
{
|
||||
return token != other.token;
|
||||
}
|
||||
|
||||
// Tell if the pointer is "null"
|
||||
bool isValid()
|
||||
{
|
||||
return token != 0;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a JSON object
|
||||
bool isObject()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_OBJECT;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a JSON array
|
||||
bool isArray()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_ARRAY;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a primitive
|
||||
bool isPrimitive()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_PRIMITIVE;
|
||||
}
|
||||
|
||||
// Tell if the JSON token is a string
|
||||
bool isString()
|
||||
{
|
||||
return token != 0 && token->type == JSMN_STRING;
|
||||
}
|
||||
|
||||
// Explicit wait to create a "null" JsonToken
|
||||
static JsonToken null()
|
||||
{
|
||||
return JsonToken();
|
||||
}
|
||||
|
||||
private:
|
||||
char* json;
|
||||
jsmntok_t* token;
|
||||
};
|
||||
}
|
||||
}
|
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>4 + 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 |
|
||||
|
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
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++;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -1,40 +1,40 @@
|
||||
/*
|
||||
* 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:
|
||||
|
||||
*/
|
||||
|
||||
#include "CppUnitTest.h"
|
||||
#include "JsonParser.h"
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||
using namespace ArduinoJson::Parser;
|
||||
|
||||
namespace ArduinoJsonParserTests
|
||||
{
|
||||
TEST_CLASS(JsonHashTableTests)
|
||||
{
|
||||
JsonHashTable hashTable;
|
||||
JsonArray nestedArray;
|
||||
char json[256];
|
||||
jsmntok_t tokens[32];
|
||||
JsonParserBase parser = JsonParserBase(tokens, 32);
|
||||
|
||||
public:
|
||||
|
||||
TEST_METHOD(EmptyString)
|
||||
{
|
||||
whenInputIs("");
|
||||
parseMustFail();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD(EmptyHashTable)
|
||||
{
|
||||
whenInputIs("{}");
|
||||
parseMustSucceed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD(NotEnoughTokens)
|
||||
{
|
||||
setTokenCountTo(2);
|
||||
@ -43,8 +43,8 @@ namespace ArduinoJsonParserTests
|
||||
|
||||
parseMustFail();
|
||||
itemMustNotExist("key");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoIntegers)
|
||||
{
|
||||
setTokenCountTo(5);
|
||||
@ -55,8 +55,8 @@ namespace ArduinoJsonParserTests
|
||||
itemMustBe("key1", 1L);
|
||||
itemMustBe("key2", 2L);
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoBooleans)
|
||||
{
|
||||
setTokenCountTo(5);
|
||||
@ -67,8 +67,8 @@ namespace ArduinoJsonParserTests
|
||||
itemMustBe("key1", true);
|
||||
itemMustBe("key2", false);
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoStrings)
|
||||
{
|
||||
setTokenCountTo(5);
|
||||
@ -79,8 +79,8 @@ namespace ArduinoJsonParserTests
|
||||
itemMustBe("key1", "hello");
|
||||
itemMustBe("key2", "world");
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TEST_METHOD(TwoNestedArrays)
|
||||
{
|
||||
setTokenCountTo(9);
|
||||
@ -101,15 +101,15 @@ namespace ArduinoJsonParserTests
|
||||
arrayItemMustBe(2, 0L);
|
||||
|
||||
itemMustNotExist("key3");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void setTokenCountTo(int n)
|
||||
{
|
||||
parser = JsonParserBase(tokens, n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void setTokenCountTo(int n)
|
||||
{
|
||||
parser = JsonParserBase(tokens, n);
|
||||
}
|
||||
|
||||
void whenInputIs(const char* input)
|
||||
{
|
||||
strcpy(json, input);
|
||||
@ -119,53 +119,53 @@ namespace ArduinoJsonParserTests
|
||||
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));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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,22 +85,16 @@
|
||||
</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="..\JsonParser\JsonParserBase.cpp" />
|
||||
<ClCompile Include="JsonObjectIteratorTests.cpp" />
|
||||
<ClCompile Include="JsonArrayTests.cpp" />
|
||||
<ClCompile Include="JsonHashTableTests.cpp" />
|
||||
<ClCompile Include="JsonArrayIteratorTests.cpp" />
|
||||
<ClCompile Include="JsonObjectTests.cpp" />
|
||||
<ClCompile Include="GbathreeBug.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" />
|
||||
<ClInclude Include="..\JsonParser\JsonParserBase.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,49 +15,20 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\JsonParser\jsmn.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonParser\JsonArray.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>
|
||||
<ClCompile Include="JsonArrayTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GbathreeBug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonHashTableTests.cpp">
|
||||
<ClCompile Include="JsonObjectTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\JsonParser\JsonParserBase.cpp">
|
||||
<ClCompile Include="JsonArrayIteratorTests.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="JsonObjectIteratorTests.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>
|
||||
<ClInclude Include="..\JsonParser\JsonParserBase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
18
README.md
18
README.md
@ -1,9 +1,9 @@
|
||||
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.
|
||||
|
||||
@ -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 | 2642 Bytes | 862 bytes |
|
||||
| json-arduino | dynamic | no | 3348 (+27%) | not supported |
|
||||
| aJson | dynamic | yes | 5088 (+93%) | 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