mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Merge branch '4.0'
Conflicts: JsonGenerator.cpp JsonGenerator.h JsonGenerator/EscapedString.cpp JsonGenerator/EscapedString.h JsonGenerator/IndentedPrint.cpp JsonGenerator/IndentedPrint.h JsonGenerator/JsonArray.h JsonGenerator/JsonArrayBase.cpp JsonGenerator/JsonArrayBase.h JsonGenerator/JsonObject.h JsonGenerator/JsonObjectBase.cpp JsonGenerator/JsonObjectBase.h JsonGenerator/JsonPrettyPrint.cpp JsonGenerator/JsonPrettyPrint.h JsonGenerator/JsonPrintable.cpp JsonGenerator/JsonPrintable.h JsonGenerator/JsonValue.cpp JsonGenerator/JsonValue.h JsonGenerator/Print.cpp JsonGenerator/Print.h JsonGenerator/Printable.h JsonGenerator/StringBuilder.cpp JsonGenerator/StringBuilder.h JsonGeneratorTests/EscapedStringTests.cpp JsonGeneratorTests/Issue10.cpp JsonGeneratorTests/JsonArrayTests.cpp JsonGeneratorTests/JsonObject_Indexer_Tests.cpp JsonGeneratorTests/JsonObject_PrintTo_Tests.cpp JsonGeneratorTests/JsonValue_Cast_Tests.cpp JsonGeneratorTests/JsonValue_PrintTo_Tests.cpp JsonGeneratorTests/PrettyPrint_Array_Tests.cpp JsonGeneratorTests/PrettyPrint_Object_Tests.cpp JsonGeneratorTests/PrettyPrint_String_Tests.cpp JsonGeneratorTests/StringBuilderTests.cpp JsonParser.cpp JsonParser.h JsonParser/JsonArray.cpp JsonParser/JsonArray.h JsonParser/JsonArrayIterator.h JsonParser/JsonObject.cpp JsonParser/JsonObject.h JsonParser/JsonObjectIterator.h JsonParser/JsonPair.h JsonParser/JsonParser.h JsonParser/JsonParserBase.cpp JsonParser/JsonParserBase.h JsonParser/JsonToken.cpp JsonParser/JsonToken.h JsonParser/JsonValue.cpp JsonParser/JsonValue.h JsonParser/README.md JsonParserTests/GbathreeBug.cpp JsonParserTests/JsonArrayIteratorTests.cpp JsonParserTests/JsonArrayTests.cpp JsonParserTests/JsonObjectIteratorTests.cpp JsonParserTests/JsonObjectTests.cpp JsonParserTests/JsonStringTests.cpp JsonParserTests/TestHashGenerator.cpp README.md library.json
This commit is contained in:
		
							
								
								
									
										11
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,5 @@ | ||||
| *.sdf | ||||
| *.user | ||||
| *.suo | ||||
| Debug | ||||
| ipch | ||||
| *.opensdf | ||||
| .DS_Store | ||||
| /.idea | ||||
| /build | ||||
| /bin | ||||
| /lib | ||||
|   | ||||
							
								
								
									
										6
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.travis.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| language: c++ | ||||
| compiler: | ||||
|   - gcc | ||||
|   - clang | ||||
| before_script: cmake . | ||||
| script: make && make test | ||||
| @@ -1,40 +0,0 @@ | ||||
|  | ||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
| # Visual Studio 2013 | ||||
| VisualStudioVersion = 12.0.21005.1 | ||||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonGeneratorTests", "JsonGeneratorTests\JsonGeneratorTests.vcxproj", "{B9545D97-E084-4A19-8E48-929157064360}" | ||||
| EndProject | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonParserTests", "JsonParserTests\JsonParserTests.vcxproj", "{4DD596EF-0185-4AB4-A3C2-F20C496F7806}" | ||||
| EndProject | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonParser", "JsonParser\JsonParser.vcxproj", "{C15274DE-2695-4DFE-8520-4424223FE6DA}" | ||||
| EndProject | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JsonGenerator", "JsonGenerator\JsonGenerator.vcxproj", "{C6536D27-738D-4CEB-A2BC-E13C8897D894}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|Win32 = Debug|Win32 | ||||
| 		Release|Win32 = Release|Win32 | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||
| 		{B9545D97-E084-4A19-8E48-929157064360}.Debug|Win32.ActiveCfg = Debug|Win32 | ||||
| 		{B9545D97-E084-4A19-8E48-929157064360}.Debug|Win32.Build.0 = Debug|Win32 | ||||
| 		{B9545D97-E084-4A19-8E48-929157064360}.Release|Win32.ActiveCfg = Release|Win32 | ||||
| 		{B9545D97-E084-4A19-8E48-929157064360}.Release|Win32.Build.0 = Release|Win32 | ||||
| 		{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Debug|Win32.ActiveCfg = Debug|Win32 | ||||
| 		{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Debug|Win32.Build.0 = Debug|Win32 | ||||
| 		{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Release|Win32.ActiveCfg = Release|Win32 | ||||
| 		{4DD596EF-0185-4AB4-A3C2-F20C496F7806}.Release|Win32.Build.0 = Release|Win32 | ||||
| 		{C15274DE-2695-4DFE-8520-4424223FE6DA}.Debug|Win32.ActiveCfg = Debug|Win32 | ||||
| 		{C15274DE-2695-4DFE-8520-4424223FE6DA}.Debug|Win32.Build.0 = Debug|Win32 | ||||
| 		{C15274DE-2695-4DFE-8520-4424223FE6DA}.Release|Win32.ActiveCfg = Release|Win32 | ||||
| 		{C15274DE-2695-4DFE-8520-4424223FE6DA}.Release|Win32.Build.0 = Release|Win32 | ||||
| 		{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Debug|Win32.ActiveCfg = Debug|Win32 | ||||
| 		{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Debug|Win32.Build.0 = Debug|Win32 | ||||
| 		{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Release|Win32.ActiveCfg = Release|Win32 | ||||
| 		{C6536D27-738D-4CEB-A2BC-E13C8897D894}.Release|Win32.Build.0 = Release|Win32 | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
| 	EndGlobalSection | ||||
| EndGlobal | ||||
| @@ -1,13 +0,0 @@ | ||||
| #!/bin/bash | ||||
|  | ||||
| ZIP="C:\Program Files\7-Zip\7z.exe" | ||||
|  | ||||
| TAG=$(git describe) | ||||
| OUTPUT="ArduinoJson-$TAG.zip" | ||||
|  | ||||
| cd .. | ||||
|  | ||||
| INPUT=$(find ArduinoJson -regex ".*\.\(cpp\|h\|md\|txt\|ino\)$" -not -regex ".*Tests/.*") | ||||
|  | ||||
| rm -f $OUTPUT | ||||
| "$ZIP" a $OUTPUT $INPUT | ||||
| @@ -1,6 +1,15 @@ | ||||
| Arduino JSON: change log | ||||
| ======================== | ||||
|  | ||||
| v4.0 | ||||
| ---- | ||||
|  | ||||
| * Unified parser and generator API (issue #23) | ||||
| * Updated library layout, now requires Arduino 1.0.6 or newer | ||||
|  | ||||
| **BREAKING CHANGE**: API changed significantly, see `doc/Migrating to the new API.md`. | ||||
|  | ||||
|  | ||||
| v3.4 | ||||
| ---- | ||||
|  | ||||
|   | ||||
							
								
								
									
										15
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| cmake_minimum_required(VERSION 2.8.4) | ||||
| project(ArduinoJson) | ||||
|  | ||||
| enable_testing() | ||||
|  | ||||
| set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) | ||||
| set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib) | ||||
| set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) | ||||
|  | ||||
| if(MSVC) | ||||
| 	add_definitions(-D_CRT_SECURE_NO_WARNINGS -W4) | ||||
| endif() | ||||
|  | ||||
| add_subdirectory(src) | ||||
| add_subdirectory(test) | ||||
| @@ -1 +0,0 @@ | ||||
| find \( -iname '*.cpp' -o -iname '*.h' \) -exec sed -i -e '$a\' {} \; | ||||
| @@ -1,15 +0,0 @@ | ||||
| /* | ||||
| * malloc-free JSON parser for Arduino | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| // This file is here to help the Arduino IDE find the .cpp files | ||||
|  | ||||
| #include "JsonGenerator/EscapedString.cpp" | ||||
| #include "JsonGenerator/IndentedPrint.cpp" | ||||
| #include "JsonGenerator/JsonArrayBase.cpp" | ||||
| #include "JsonGenerator/JsonObjectBase.cpp" | ||||
| #include "JsonGenerator/JsonValue.cpp" | ||||
| #include "JsonGenerator/JsonPrettyPrint.cpp" | ||||
| #include "JsonGenerator/JsonPrintable.cpp" | ||||
| #include "JsonGenerator/StringBuilder.cpp" | ||||
| @@ -1,7 +0,0 @@ | ||||
| /* | ||||
| * malloc-free JSON parser for Arduino | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonGenerator/JsonArray.h" | ||||
| #include "JsonGenerator/JsonObject.h" | ||||
| @@ -1,45 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #include "EscapedString.h" | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| static inline char getSpecialChar(char c) | ||||
| { | ||||
|     // Optimized for code size on a 8-bit AVR | ||||
|  | ||||
|     const char* p = "\"\"\\\\\bb\ff\nn\rr\tt\0"; | ||||
|  | ||||
|     while (p[0] && p[0] != c) | ||||
|     { | ||||
|         p += 2; | ||||
|     } | ||||
|  | ||||
|     return p[1]; | ||||
| } | ||||
|  | ||||
| static inline size_t printCharTo(char c, Print& p) | ||||
| { | ||||
|     char specialChar = getSpecialChar(c); | ||||
|  | ||||
|     return specialChar != 0 | ||||
|         ? p.write('\\') + p.write(specialChar) | ||||
|         : p.write(c); | ||||
| } | ||||
|  | ||||
| size_t EscapedString::printTo(const char* s, Print& p) | ||||
| { | ||||
|     if (!s) return p.print("null"); | ||||
|      | ||||
|     size_t n = p.write('\"'); | ||||
|  | ||||
|     while (*s) | ||||
|     { | ||||
|         n += printCharTo(*s++, p); | ||||
|     } | ||||
|  | ||||
|     return n + p.write('\"'); | ||||
| } | ||||
| @@ -1,20 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Print.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Internals | ||||
|     { | ||||
|         class EscapedString | ||||
|         { | ||||
|         public: | ||||
|             static size_t printTo(const char*, Print&); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,45 +0,0 @@ | ||||
| #include "IndentedPrint.h" | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
|  | ||||
| void IndentedPrint::indent() | ||||
| { | ||||
|     if (_level < MAX_LEVEL) | ||||
|         _level++; | ||||
| } | ||||
|  | ||||
| void IndentedPrint::unindent() | ||||
| { | ||||
|     if (_level > 0) | ||||
|         _level--; | ||||
| } | ||||
|  | ||||
| void IndentedPrint::setTabSize(uint8_t n) | ||||
| { | ||||
|     if (n < MAX_TAB_SIZE) | ||||
|         _tabSize = n; | ||||
| } | ||||
|  | ||||
| size_t IndentedPrint::write(uint8_t c) | ||||
| { | ||||
|     size_t n = 0; | ||||
|  | ||||
|     if (_isNewLine) | ||||
|         n += writeTabs(); | ||||
|  | ||||
|     n += _sink.write(c); | ||||
|  | ||||
|     _isNewLine = c == '\n'; | ||||
|  | ||||
|     return n; | ||||
| } | ||||
|  | ||||
| inline size_t IndentedPrint::writeTabs() | ||||
| { | ||||
|     size_t n = 0; | ||||
|  | ||||
|     for (int i = 0; i < _level*_tabSize; i++) | ||||
|         n += _sink.write(' '); | ||||
|  | ||||
|     return n; | ||||
| } | ||||
| @@ -1,53 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Print.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         // Decorator on top of Print to allow indented output. | ||||
|         // This class is used by JsonPrintable::prettyPrintTo() but can also be used | ||||
|         // for your own purpose, like logging. | ||||
|         class IndentedPrint : public Print | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             IndentedPrint(Print& p) | ||||
|                 : _sink(p) | ||||
|             { | ||||
|                 _level = 0; | ||||
|                 _tabSize = 2; | ||||
|                 _isNewLine = true; | ||||
|             } | ||||
|  | ||||
|             virtual size_t write(uint8_t); | ||||
|  | ||||
|             // Adds one level of indentation | ||||
|             void indent(); | ||||
|  | ||||
|             // Removes one level of indentation | ||||
|             void unindent(); | ||||
|  | ||||
|             // Set the number of space printed for each level of indentation | ||||
|             void setTabSize(uint8_t n); | ||||
|  | ||||
|         private: | ||||
|             Print& _sink; | ||||
|             uint8_t _level : 4; | ||||
|             uint8_t _tabSize : 3; | ||||
|             bool _isNewLine : 1; | ||||
|              | ||||
|             size_t writeTabs(); | ||||
|  | ||||
|             static const int MAX_LEVEL = 15; // because it's only 4 bits | ||||
|             static const int MAX_TAB_SIZE = 7; // because it's only 3 bits | ||||
|         }; | ||||
|     } | ||||
| } | ||||
|  | ||||
| @@ -1,28 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonArrayBase.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         template<int N> | ||||
|         class JsonArray : public JsonArrayBase | ||||
|         { | ||||
|         public: | ||||
|             JsonArray() | ||||
|                 : JsonArrayBase(_items, N) | ||||
|             { | ||||
|  | ||||
|             }          | ||||
|  | ||||
|         private: | ||||
|             JsonValue _items[N]; | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,34 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonArrayBase.h" | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| size_t JsonArrayBase::printTo(Print& p) const | ||||
| { | ||||
|     size_t n = 0; | ||||
|  | ||||
|     n += p.write('['); | ||||
|  | ||||
|     // NB: the code has been optimized for a small size on a 8-bit AVR | ||||
|  | ||||
|     const JsonValue* current = _items; | ||||
|     for (int i = _count; i > 0; i--) | ||||
|     {        | ||||
|         n += current->printTo(p); | ||||
|         current++; | ||||
|  | ||||
|         if (i > 1) | ||||
|         { | ||||
|             n += p.write(','); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     n += p.write(']'); | ||||
|  | ||||
|     return n; | ||||
| } | ||||
| @@ -1,79 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonPrintable.h" | ||||
| #include "JsonValue.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         class JsonArrayBase : public JsonPrintable | ||||
|         { | ||||
|         public: | ||||
|             JsonArrayBase(JsonValue* items, int capacity) | ||||
|                 : _items(items), _capacity(capacity), _count(0) | ||||
|             { | ||||
|  | ||||
|             } | ||||
|  | ||||
|             void add(const Printable& value) | ||||
|             { | ||||
|                 addIfPossible<const Printable&>(value); | ||||
|             } | ||||
|  | ||||
|             void add(bool value) | ||||
|             { | ||||
|                 addIfPossible<bool>(value); | ||||
|             } | ||||
|  | ||||
|             void add(int value) | ||||
|             { | ||||
|                 addIfPossible<long>(value); | ||||
|             } | ||||
|  | ||||
|             void add(long value) | ||||
|             { | ||||
|                 addIfPossible<long>(value); | ||||
|             } | ||||
|  | ||||
|             void add(double value) | ||||
|             { | ||||
|                 addIfPossible<double>(value); | ||||
|             } | ||||
|  | ||||
|             void add(const char* value) | ||||
|             { | ||||
|                 addIfPossible<const char*>(value); | ||||
|             } | ||||
|  | ||||
|             template<int DIGITS> | ||||
|             void add(double value) | ||||
|             { | ||||
|                 if (_count >= _capacity) return; | ||||
|  | ||||
|                 JsonValue& v = _items[_count++]; | ||||
|                 v.set<DIGITS>(value); | ||||
|             } | ||||
|  | ||||
|             virtual size_t printTo(Print& p) const; | ||||
|  | ||||
|             using JsonPrintable::printTo; | ||||
|  | ||||
|         private: | ||||
|             JsonValue* _items; | ||||
|             int _capacity, _count; | ||||
|  | ||||
|             template<typename T> | ||||
|             void addIfPossible(T value) | ||||
|             { | ||||
|                 if (_count < _capacity) | ||||
|                     _items[_count++] = value; | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,101 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup Label="ProjectConfigurations"> | ||||
|     <ProjectConfiguration Include="Debug|Win32"> | ||||
|       <Configuration>Debug</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|     <ProjectConfiguration Include="Release|Win32"> | ||||
|       <Configuration>Release</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="EscapedString.h" /> | ||||
|     <ClInclude Include="IndentedPrint.h" /> | ||||
|     <ClInclude Include="JsonPrettyPrint.h" /> | ||||
|     <ClInclude Include="JsonArray.h" /> | ||||
|     <ClInclude Include="JsonArrayBase.h" /> | ||||
|     <ClInclude Include="JsonObject.h" /> | ||||
|     <ClInclude Include="JsonObjectBase.h" /> | ||||
|     <ClInclude Include="JsonPrintable.h" /> | ||||
|     <ClInclude Include="JsonValue.h" /> | ||||
|     <ClInclude Include="Print.h" /> | ||||
|     <ClInclude Include="Printable.h" /> | ||||
|     <ClInclude Include="StringBuilder.h" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="EscapedString.cpp" /> | ||||
|     <ClCompile Include="IndentedPrint.cpp" /> | ||||
|     <ClCompile Include="JsonPrettyPrint.cpp" /> | ||||
|     <ClCompile Include="JsonArrayBase.cpp" /> | ||||
|     <ClCompile Include="JsonObjectBase.cpp" /> | ||||
|     <ClCompile Include="JsonPrintable.cpp" /> | ||||
|     <ClCompile Include="JsonValue.cpp" /> | ||||
|     <ClCompile Include="Print.cpp" /> | ||||
|     <ClCompile Include="StringBuilder.cpp" /> | ||||
|   </ItemGroup> | ||||
|   <PropertyGroup Label="Globals"> | ||||
|     <ProjectGuid>{C6536D27-738D-4CEB-A2BC-E13C8897D894}</ProjectGuid> | ||||
|     <Keyword>Win32Proj</Keyword> | ||||
|     <RootNamespace>JsonGenerator</RootNamespace> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>true</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>false</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
|   <ImportGroup Label="ExtensionSettings"> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <PropertyGroup Label="UserMacros" /> | ||||
|   <PropertyGroup /> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <ClCompile> | ||||
|       <PrecompiledHeader> | ||||
|       </PrecompiledHeader> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <Optimization>Disabled</Optimization> | ||||
|       <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <ClCompile> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <PrecompiledHeader> | ||||
|       </PrecompiledHeader> | ||||
|       <Optimization>MaxSpeed</Optimization> | ||||
|       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||
|       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||
|       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||
|       <OptimizeReferences>true</OptimizeReferences> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
|   <ImportGroup Label="ExtensionTargets"> | ||||
|   </ImportGroup> | ||||
| </Project> | ||||
| @@ -1,84 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup> | ||||
|     <Filter Include="Source Files"> | ||||
|       <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | ||||
|       <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Header Files"> | ||||
|       <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | ||||
|       <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Resource Files"> | ||||
|       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | ||||
|       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | ||||
|     </Filter> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="EscapedString.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonArray.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonArrayBase.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonPrintable.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonValue.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Print.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="Printable.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="StringBuilder.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonObjectBase.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonObject.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="IndentedPrint.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonPrettyPrint.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="EscapedString.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonArrayBase.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonValue.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="StringBuilder.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="Print.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonObjectBase.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="IndentedPrint.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonPrettyPrint.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonPrintable.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
| @@ -1,44 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonObjectBase.h" | ||||
|  | ||||
| #ifndef ARDUINO_JSON_NO_DEPRECATION_WARNING | ||||
| #ifdef __GNUC__ | ||||
| #define DEPRECATED __attribute__((deprecated)) | ||||
| #elif defined(_MSC_VER) | ||||
| #define DEPRECATED __declspec(deprecated) | ||||
| #endif | ||||
| #else | ||||
| #define DEPRECATED | ||||
| #endif | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         template <int N> | ||||
|         class JsonObject : public JsonObjectBase | ||||
|         { | ||||
|         public: | ||||
|             JsonObject() | ||||
|                 : JsonObjectBase(_items, N) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|         private: | ||||
|             KeyValuePair _items[N]; | ||||
|         }; | ||||
|  | ||||
|          | ||||
|         // Obsolete: use JsonObject instead | ||||
|         template <int N> | ||||
|         class DEPRECATED JsonHashTable : public JsonObject<N> | ||||
|         {             | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,92 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonObjectBase.h" | ||||
| #include <string.h> // for strcmp | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| JsonValue JsonObjectBase::_nullValue; | ||||
|  | ||||
| size_t JsonObjectBase::printTo(Print& p) const | ||||
| { | ||||
|     size_t n = 0; | ||||
|  | ||||
|     n += p.write('{'); | ||||
|  | ||||
|     // NB: the code has been optimized for a small size on a 8-bit AVR | ||||
|  | ||||
|     const KeyValuePair* current = _items; | ||||
|     for (int i = _count; i > 0; i--) | ||||
|     {        | ||||
|         n += EscapedString::printTo(current->key, p); | ||||
|         n += p.write(':'); | ||||
|         n += current->value.printTo(p); | ||||
|  | ||||
|         current++; | ||||
|  | ||||
|         if (i > 1) | ||||
|         { | ||||
|             n += p.write(','); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     n += p.write('}'); | ||||
|  | ||||
|     return n; | ||||
| } | ||||
|  | ||||
| JsonObjectBase::KeyValuePair* JsonObjectBase::getMatchingPair(JsonKey key) const | ||||
| { | ||||
|     KeyValuePair* p = _items; | ||||
|  | ||||
|     for (int i = _count; i > 0; --i) | ||||
|     { | ||||
|         if (!strcmp(p->key, key)) | ||||
|             return p; | ||||
|  | ||||
|         p++; | ||||
|     } | ||||
|  | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| JsonValue& JsonObjectBase::operator[](JsonKey key) | ||||
| { | ||||
|     KeyValuePair* match = getMatchingPair(key); | ||||
|  | ||||
|     if (match) | ||||
|         return match->value; | ||||
|  | ||||
|     JsonValue* value; | ||||
|  | ||||
|     if (_count < _capacity) | ||||
|     { | ||||
|         _items[_count].key = key; | ||||
|         value = &_items[_count].value; | ||||
|         _count++; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         value = &_nullValue; | ||||
|     } | ||||
|  | ||||
|     value->reset(); | ||||
|     return *value; | ||||
| } | ||||
|  | ||||
| bool JsonObjectBase::containsKey(JsonKey key) const | ||||
| { | ||||
|     return getMatchingPair(key) != 0; | ||||
| } | ||||
|  | ||||
| void JsonObjectBase::remove(JsonKey key) | ||||
| { | ||||
|     KeyValuePair* match = getMatchingPair(key);     | ||||
|     if (match == 0) return; | ||||
|  | ||||
|     *match = _items[--_count]; | ||||
| } | ||||
| @@ -1,62 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonPrintable.h" | ||||
| #include "JsonValue.h" | ||||
| #include "EscapedString.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         typedef const char* JsonKey; | ||||
|  | ||||
|         class JsonObjectBase : public JsonPrintable | ||||
|         { | ||||
|         public: | ||||
|             JsonValue& operator[](JsonKey); | ||||
|             bool containsKey(JsonKey) const; | ||||
|             void remove(JsonKey key); | ||||
|  | ||||
|             template<typename T> | ||||
|             void add(JsonKey key, T value) | ||||
|             { | ||||
|                 operator[](key) = value; | ||||
|             } | ||||
|  | ||||
|             template<int DIGITS> | ||||
|             void add(JsonKey key, double value) | ||||
|             { | ||||
|                 operator[](key).set<DIGITS>(value); | ||||
|             } | ||||
|  | ||||
|             using JsonPrintable::printTo; | ||||
|  | ||||
|             virtual size_t printTo(Print& p) const; | ||||
|  | ||||
|         protected: | ||||
|  | ||||
|             struct KeyValuePair | ||||
|             { | ||||
|                 JsonKey     key; | ||||
|                 JsonValue   value; | ||||
|             }; | ||||
|  | ||||
|             JsonObjectBase(KeyValuePair* items, int capacity) | ||||
|                 : _items(items), _capacity(capacity), _count(0) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|         private: | ||||
|             KeyValuePair* _items; | ||||
|             int _capacity, _count; | ||||
|             static JsonValue _nullValue; | ||||
|  | ||||
|             KeyValuePair* getMatchingPair(JsonKey key) const; | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,97 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonPrettyPrint.h" | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
|  | ||||
| size_t JsonPrettyPrint::write(uint8_t c) | ||||
| { | ||||
|     size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);     | ||||
|     _previousChar = c; | ||||
|     return n; | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleStringChar(uint8_t c) | ||||
| { | ||||
|     bool isQuote = c == '"' && _previousChar != '\\'; | ||||
|  | ||||
|     if (isQuote) _inString = false; | ||||
|  | ||||
|     return _sink.write(c); | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleMarkupChar(uint8_t c) | ||||
| { | ||||
|     switch (c) | ||||
|     { | ||||
|     case '{': | ||||
|     case '[': | ||||
|         return handleBlockOpen(c); | ||||
|  | ||||
|     case '}': | ||||
|     case ']': | ||||
|         return handleBlockClose(c); | ||||
|  | ||||
|     case ':': | ||||
|         return handleColumn(); | ||||
|  | ||||
|     case ',': | ||||
|         return handleComma(); | ||||
|  | ||||
|     case '"': | ||||
|         return handleQuoteOpen(); | ||||
|  | ||||
|     default: | ||||
|         return handleNormalChar(c); | ||||
|     } | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleBlockOpen(uint8_t c) | ||||
| { | ||||
|     return indentIfNeeded() + _sink.write(c); | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleBlockClose(uint8_t c) | ||||
| {   | ||||
|     return unindentIfNeeded() + _sink.write(c); | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleColumn() | ||||
| { | ||||
|     return _sink.write(':') + _sink.write(' '); | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleComma()  | ||||
| { | ||||
|     return _sink.write(',') + _sink.println(); | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleQuoteOpen() | ||||
| { | ||||
|     _inString = true; | ||||
|     return indentIfNeeded() + _sink.write('"'); | ||||
| } | ||||
|  | ||||
| inline size_t JsonPrettyPrint::handleNormalChar(uint8_t c) | ||||
| { | ||||
|     return indentIfNeeded() + _sink.write(c); | ||||
| } | ||||
|  | ||||
| size_t JsonPrettyPrint::indentIfNeeded() | ||||
| { | ||||
|     if (!inEmptyBlock()) return 0; | ||||
|  | ||||
|     _sink.indent(); | ||||
|     return _sink.println(); | ||||
| } | ||||
|  | ||||
| size_t JsonPrettyPrint::unindentIfNeeded() | ||||
| { | ||||
|     if (inEmptyBlock()) return 0; | ||||
|  | ||||
|     _sink.unindent(); | ||||
|     return _sink.println(); | ||||
| } | ||||
| @@ -1,52 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Print.h" | ||||
| #include "IndentedPrint.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         // Converts a compact JSON string into an indented one. | ||||
|         class JsonPrettyPrint : public Print | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             JsonPrettyPrint(IndentedPrint& p) | ||||
|                 : _sink(p) | ||||
|             { | ||||
|                 _previousChar = 0; | ||||
|                 _inString = false; | ||||
|             } | ||||
|  | ||||
|             virtual size_t write(uint8_t); | ||||
|  | ||||
|         private:             | ||||
|             uint8_t _previousChar; | ||||
|             IndentedPrint& _sink; | ||||
|             bool _inString; | ||||
|  | ||||
|             bool inEmptyBlock() | ||||
|             { | ||||
|                 return _previousChar == '{' || _previousChar == '['; | ||||
|             } | ||||
|  | ||||
|             size_t handleStringChar(uint8_t); | ||||
|             size_t handleMarkupChar(uint8_t); | ||||
|  | ||||
|             size_t handleBlockClose(uint8_t); | ||||
|             size_t handleBlockOpen(uint8_t); | ||||
|             size_t handleColumn(); | ||||
|             size_t handleComma(); | ||||
|             size_t handleQuoteOpen(); | ||||
|             size_t handleNormalChar(uint8_t); | ||||
|             size_t indentIfNeeded(); | ||||
|             size_t unindentIfNeeded(); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,35 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonPrintable.h" | ||||
| #include "JsonPrettyPrint.h" | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| size_t JsonPrintable::printTo(char* buffer, size_t bufferSize) const | ||||
| { | ||||
|     StringBuilder sb(buffer, bufferSize); | ||||
|     return printTo(sb); | ||||
| } | ||||
|  | ||||
| size_t JsonPrintable::prettyPrintTo(char* buffer, size_t bufferSize) const | ||||
| { | ||||
|     StringBuilder sb(buffer, bufferSize); | ||||
|     return prettyPrintTo(sb); | ||||
| } | ||||
|  | ||||
| size_t JsonPrintable::prettyPrintTo(IndentedPrint& p) const | ||||
| { | ||||
|     JsonPrettyPrint prettyPrint(p); | ||||
|     return printTo(prettyPrint); | ||||
| } | ||||
|  | ||||
| size_t JsonPrintable::prettyPrintTo(Print& p) const | ||||
| { | ||||
|     IndentedPrint indentedPrint(p); | ||||
|     return prettyPrintTo(indentedPrint); | ||||
| } | ||||
| @@ -1,40 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Print.h" | ||||
| #include "Printable.h" | ||||
| #include "IndentedPrint.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         // Contains methods to generate a JSON string. | ||||
|         // Implemented by both JsonObject and JsonArray | ||||
|         class JsonPrintable : public Printable | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             // Generates the compact JSON string and sends it to a Print stream  | ||||
|             virtual size_t printTo(Print& p) const = 0; | ||||
|  | ||||
|             // Generates the compact JSON string and writes it in a buffer | ||||
|             size_t printTo(char* buffer, size_t bufferSize) const; | ||||
|  | ||||
|             // Generates the indented JSON string and sends it to a Print stream | ||||
|             size_t prettyPrintTo(Print& p) const; | ||||
|  | ||||
|             // Generates the indented JSON string and sends it to a IndentedPrint stream | ||||
|             // This overload allows a finer control of the output because you can customize | ||||
|             // the IndentedPrint. | ||||
|             size_t prettyPrintTo(IndentedPrint& p) const; | ||||
|  | ||||
|             // Generates the indented JSON string and writes it in a buffer | ||||
|             size_t prettyPrintTo(char* buffer, size_t bufferSize) const; | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,33 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #include "EscapedString.h" | ||||
| #include "JsonValue.h" | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| size_t JsonValue::printBoolTo(const Content& c, Print& p) | ||||
| { | ||||
|     return p.print(c.asBool ? "true" : "false"); | ||||
| } | ||||
|  | ||||
| size_t JsonValue::printLongTo(const Content& c, Print& p) | ||||
| { | ||||
|     return p.print(c.asLong); | ||||
| } | ||||
|  | ||||
| size_t JsonValue::printPrintableTo(const Content& c, Print& p) | ||||
| { | ||||
|     if (c.asPrintable) | ||||
|         return c.asPrintable->printTo(p); | ||||
|     else | ||||
|         return p.print("null"); | ||||
| } | ||||
|  | ||||
| size_t JsonValue::printStringTo(const Content& c, Print& p) | ||||
| { | ||||
|     return EscapedString::printTo(c.asString, p); | ||||
| } | ||||
| @@ -1,135 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "EscapedString.h" | ||||
| #include "Printable.h" | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Generator | ||||
|     { | ||||
|         class JsonValue | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             void operator=(bool value) | ||||
|             { | ||||
|                 _printToImpl = &printBoolTo; | ||||
|                 _content.asBool = value; | ||||
|             } | ||||
|  | ||||
|             void operator=(long value) | ||||
|             { | ||||
|                 _printToImpl = &printLongTo; | ||||
|                 _content.asLong = value; | ||||
|             } | ||||
|  | ||||
|             void operator=(int value) | ||||
|             { | ||||
|                 _printToImpl = &printLongTo; | ||||
|                 _content.asLong = value; | ||||
|             } | ||||
|  | ||||
|             void operator=(const Printable& value) | ||||
|             { | ||||
|                 _printToImpl = &printPrintableTo; | ||||
|                 _content.asPrintable = &value; | ||||
|             } | ||||
|  | ||||
|             void operator=(const char* value) | ||||
|             { | ||||
|                 _printToImpl = &printStringTo; | ||||
|                 _content.asString = value; | ||||
|             } | ||||
|  | ||||
|             void operator=(double value) | ||||
|             { | ||||
|                 set<2>(value); | ||||
|             } | ||||
|  | ||||
|             template <int DIGITS> | ||||
|             void set(double value) | ||||
|             { | ||||
|                 _printToImpl = &printDoubleTo < DIGITS > ; | ||||
|                 _content.asDouble = value; | ||||
|             } | ||||
|  | ||||
|             operator bool() | ||||
|             { | ||||
|                 return _content.asBool; | ||||
|             } | ||||
|  | ||||
|             operator const char*() | ||||
|             { | ||||
|                 return _content.asString; | ||||
|             } | ||||
|  | ||||
|             operator double() | ||||
|             { | ||||
|                 return _content.asDouble; | ||||
|             } | ||||
|  | ||||
|             operator float() | ||||
|             { | ||||
|                 return static_cast<float>(_content.asDouble); | ||||
|             } | ||||
|  | ||||
|             operator int() | ||||
|             { | ||||
|                 return _content.asLong; | ||||
|             } | ||||
|  | ||||
|             operator long() | ||||
|             { | ||||
|                 return _content.asLong; | ||||
|             } | ||||
|  | ||||
|             operator const Printable&() | ||||
|             { | ||||
|                 return *_content.asPrintable; | ||||
|             } | ||||
|  | ||||
|             size_t printTo(Print& p) const | ||||
|             { | ||||
|                 // handmade polymorphism | ||||
|                 return _printToImpl(_content, p); | ||||
|             } | ||||
|  | ||||
|             void reset() | ||||
|             { | ||||
|                 _content.asDouble = 0; | ||||
|                 _printToImpl = printStringTo; | ||||
|             } | ||||
|  | ||||
|         private: | ||||
|             union Content | ||||
|             { | ||||
|                 bool                asBool; | ||||
|                 double              asDouble; | ||||
|                 long                asLong; | ||||
|                 const Printable*    asPrintable; | ||||
|                 const char*         asString; | ||||
|             }; | ||||
|  | ||||
|             Content _content; | ||||
|  | ||||
|             size_t(*_printToImpl)(const Content&, Print&); | ||||
|  | ||||
|             static size_t printBoolTo(const Content&, Print&); | ||||
|             static size_t printLongTo(const Content&, Print&); | ||||
|             static size_t printPrintableTo(const Content&, Print&); | ||||
|             static size_t printStringTo(const Content&, Print&); | ||||
|  | ||||
|             template <int DIGITS> | ||||
|             static size_t printDoubleTo(const Content& c, Print& p) | ||||
|             { | ||||
|                 return p.print(c.asDouble, DIGITS); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,56 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #ifndef ARDUINO | ||||
|  | ||||
| #include "Print.h" | ||||
| #include <string> // for sprintf, strchr and strcat | ||||
|  | ||||
| size_t Print::print(const char s[]) | ||||
| { | ||||
|     size_t n = 0; | ||||
|     while (*s) | ||||
|     { | ||||
|         n += write(*s++); | ||||
|     } | ||||
|     return n; | ||||
| } | ||||
|  | ||||
| static inline void ensureStringContainsPoint(char* s) | ||||
| { | ||||
|     // Ensures that the decimal point is present. | ||||
|     // For example, we don't want "0" but "0.0". | ||||
|     // Otherwise, the value would be considered as an integer by some parsers | ||||
|     // See issue #22 | ||||
|  | ||||
|     if (!strchr(s, '.')) | ||||
|         strcat(s, ".0"); | ||||
| } | ||||
|  | ||||
| size_t Print::print(double value, int digits) | ||||
| { | ||||
|     char tmp[32]; | ||||
|  | ||||
|     sprintf(tmp, "%.*lg", digits+1, value); | ||||
|  | ||||
|     if (digits>0) | ||||
|         ensureStringContainsPoint(tmp); | ||||
|  | ||||
|     return print(tmp); | ||||
| } | ||||
|  | ||||
| size_t Print::print(long value) | ||||
| { | ||||
|     char tmp[32]; | ||||
|     sprintf(tmp, "%ld", value); | ||||
|     return print(tmp); | ||||
| } | ||||
|  | ||||
| size_t Print::println() | ||||
| { | ||||
|     return write('\r') + write('\n'); | ||||
| } | ||||
|  | ||||
| #endif | ||||
| @@ -1,30 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #ifndef ARDUINO | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| // This class reproduces Arduino's Print | ||||
| class Print | ||||
| { | ||||
| public: | ||||
|  | ||||
|     virtual size_t write(uint8_t) = 0; | ||||
|  | ||||
|     size_t print(const char[]); | ||||
|     size_t print(double, int = 2); | ||||
|     size_t print(long); | ||||
|     size_t println(); | ||||
| }; | ||||
|  | ||||
| #else | ||||
|  | ||||
| #include <Print.h> | ||||
|  | ||||
| #endif | ||||
| @@ -1,23 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #ifndef ARDUINO | ||||
|  | ||||
| class Print; | ||||
|  | ||||
| class Printable | ||||
| { | ||||
| public: | ||||
|  | ||||
|     virtual size_t printTo(Print& p) const = 0; | ||||
| }; | ||||
|  | ||||
| #else | ||||
|  | ||||
| #include <Printable.h> | ||||
|  | ||||
| #endif | ||||
| @@ -1,247 +0,0 @@ | ||||
| Arduino JSON library - Generator | ||||
| ================================ | ||||
|  | ||||
| *An elegant and efficient JSON encoder for embedded systems.* | ||||
|  | ||||
| It's design to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc). | ||||
|  | ||||
| It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project. | ||||
|  | ||||
|  | ||||
| Features | ||||
| -------- | ||||
|  | ||||
| * Elegant API, very easy to use  | ||||
| * Fixed memory allocation (no malloc) | ||||
| * Small footprint | ||||
| * Supports nested objects | ||||
| * Supports indented output | ||||
| * Implements Arduino's `Printable interface | ||||
| * MIT License | ||||
|  | ||||
|  | ||||
| Example | ||||
| ------- | ||||
|  | ||||
|     JsonArray<2> array; | ||||
|     array.add<6>(48.756080);  // <6> specifies the number of digits in the output | ||||
|     array.add<6>(2.302038);   // (the default is 2) | ||||
|  | ||||
|     JsonObject<3> root; | ||||
|     root["sensor"] = "gps"; | ||||
|     root["time"] = 1351824120; | ||||
|     root["data"] = array; | ||||
|  | ||||
|     Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||
|  | ||||
|  | ||||
| How to  use? | ||||
| ------------ | ||||
|  | ||||
| ### 1. Install the library | ||||
|  | ||||
| Download the library and extract it to: | ||||
|  | ||||
|     <your Arduino Sketch folder>/libraries/ArduinoJson | ||||
|  | ||||
| ### 2. Import in your sketch | ||||
|  | ||||
| Just add the following lines at the top of your `.ino` file: | ||||
|  | ||||
|     #include <JsonGenerator.h> | ||||
|  | ||||
|     using namespace ArduinoJson::Generator; | ||||
|  | ||||
| > ##### Having a namespace conflict? | ||||
| > To be able to use both `ArduinoJson::Generator` and `ArduinoJson::Parser` in the same file, you need to do one of the followings: | ||||
| >  | ||||
| > * Put the `using` statements into different functions | ||||
| > * `using namespace ArduinoJson`, then prefix the type names by `Generator::` or `Parser::` | ||||
| > * Create aliases for the namespaces or the types (C++11 only) | ||||
|     | ||||
| ### 3. Create object tree | ||||
|  | ||||
| In order to generate a JSON string, you need to build the equivalent object tree. You usually start by the root which can be either a JSON Array or a JSON Object. | ||||
|  | ||||
| #### JSON Array | ||||
|  | ||||
| You create an array with the following line: | ||||
|  | ||||
|     JsonArray<8> array; | ||||
|  | ||||
| See the little `<8>`? It's a template parameter that gives the capacity of the array, it's the maximum number of elements you can put in it.  | ||||
|  | ||||
| > ##### About the capacity | ||||
| > As stated in the feature list, this library works with a fixed memory allocation. | ||||
| > This means that the size of the object must be know at the compilation time, therefore you can **not** use a variable to set the capacity of the array. | ||||
|  | ||||
| Then you can add strings, integer, booleans, etc:  | ||||
|  | ||||
|     array.add("bazinga!"); | ||||
|     array.add(42); | ||||
|     array.add(true); | ||||
|  | ||||
| There are two syntaxes for floating point values: | ||||
|  | ||||
| 	array.add<4>(3.1415);  // 4 digits: "3.1415"  | ||||
|     array.add(3.14);	   // 2 digits: "3.14" | ||||
|  | ||||
| > ##### About floating point precision | ||||
| > The overload of `add()` with 2 parameters allows you to specify the number of decimals to save in the JSON string.  | ||||
| > When you use the overload with one parameter, you use the default number of decimals which is two. | ||||
| > Note that this behavior is the exact same as Arduino's `Print::print(double,int);` which is implemented by `Serial`.  | ||||
| > So you may already be familiar with it.  | ||||
|  | ||||
| Finally you can add nested object to the array: | ||||
|  | ||||
|     JsonArray<8> nestedArray; | ||||
|     array.add(nestedArray); | ||||
|  | ||||
| or | ||||
|  | ||||
|     JsonObject<8> nestedObject; | ||||
|     array.add(nestedObject); | ||||
|  | ||||
| > ##### CAUTION! Nested objects must be in memory | ||||
| > Calling `add()` makes the `JsonArray` store a pointer to the nested object. | ||||
| > This is designed to avoid memory duplication. | ||||
| > But it can only work if the object is in memory when `printTo()` is executed. | ||||
| > For instance, don't do this: | ||||
| >  | ||||
| >     void addNestedObject() | ||||
| >     { | ||||
| >         JsonObject<2> nestedObject; | ||||
| >         // ... | ||||
| >         array.add(nestedObject); // <- DON'T !! | ||||
| >          | ||||
| >         // array now contains a pointer to a local variable that will be | ||||
| >         // discarded as soon as the function exits  | ||||
| >     }  | ||||
| >      | ||||
| > For the same reason, don't do this either: | ||||
| >  | ||||
| >     for( int i=0; i<100; i++) | ||||
| >     { | ||||
| >         JsonObject<2> nestedObject; | ||||
| >         // ... | ||||
| >         array.add(nestedObject); // <- DON'T !! | ||||
| >     }   | ||||
| >     // array now contains 100 pointers to the same a local variable | ||||
| >     // that is out of the scope anyway | ||||
|  | ||||
| #### JSON Object | ||||
|  | ||||
| You create a JSON object (ie hash-table/dictionary) with the following line: | ||||
|  | ||||
|     JsonObject<8> object; | ||||
|  | ||||
| Like with the array class, there is a template parameter that gives the capacity of the object. | ||||
|  | ||||
| Then you can add strings, integer, booleans, etc:  | ||||
|  | ||||
|     object["key1"] = "bazinga!"; | ||||
|     object["key2"] = 42; | ||||
|     object["key3"] = true; | ||||
|  | ||||
| As for the arrays, there are two syntaxes for the floating point values: | ||||
|  | ||||
| 	object["key4"].set<4>(3.1415);  // 4 digits "3.1415"  | ||||
|     object["key5"] = 3.1415;	    // default: 2 digits "3.14" | ||||
|  | ||||
| Finally you can add nested objects: | ||||
|  | ||||
|     JsonArray<8> nestedArray; | ||||
|     object["key6"] = nestedArray; | ||||
|  | ||||
| or | ||||
|  | ||||
|     JsonObject<8> nestedObject; | ||||
|     object["key7"] = nestedObject; | ||||
|  | ||||
| > ##### Other JsonObject functions | ||||
| > * `object.add(key, value)` is a synonym for `object[key] = value` | ||||
| > * `object.containsKey(key)` returns `true` is the `key` is present in `object` | ||||
| > * `object.remove(key)` removes the `value` associated with `key` | ||||
|  | ||||
| ### 4. Get the JSON string | ||||
|  | ||||
| There are two ways tho get the resulting JSON string. | ||||
|  | ||||
| Depending on your project, you may need to dump the string in a classic `char[]` or send it to a stream like `Serial` or `EthernetClient `. | ||||
|  | ||||
| Both ways are the easy way :-) | ||||
|  | ||||
| #### Use a classic `char[]` | ||||
|  | ||||
| Whether you have a `JsonArray` or a `JsonObject`, simply call `printTo()` with the destination buffer, like so: | ||||
|  | ||||
| 	char buffer[256]; | ||||
|     array.printTo(buffer, sizeof(buffer)); | ||||
|  | ||||
| > ##### Want an indented output? | ||||
| > By default the generated JSON is as small as possible. It contains no extra space, nor line break. | ||||
| > But if you want an indented, more readable output, you can. | ||||
| > Simply call `prettyPrintTo` instead of `printTo()`: | ||||
| >  | ||||
| >     array.prettyPrintTo(buffer, sizeof(buffer)); | ||||
|  | ||||
| #### Send to a stream | ||||
|  | ||||
| It's very likely that the generated JSON will end up in a stream like `Serial` or `EthernetClient `, so you can save some time and memory by doing this: | ||||
|  | ||||
| 	Serial.print(array); | ||||
|  | ||||
| or | ||||
|    | ||||
|     array.printTo(Serial); | ||||
|  | ||||
| > ##### About the Printable interface | ||||
| > `JsonArray` and `JsonObject` implement Arduino's `Printable` interface. | ||||
| > This is why you can call `Serial.print()` like in the example above. | ||||
| > You can do the same with any other implementation of `Print`:  `HardwareSerial`,  `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`... | ||||
|     | ||||
|  | ||||
| Memory usage | ||||
| ------------ | ||||
|  | ||||
| Here are the size of the main classes of the library. | ||||
|  | ||||
| This table is for an 8-bit Arduino, types would be bigger on a 32-bit processor. | ||||
|  | ||||
| | Type                | Size in bytes | | ||||
| | --------------------| ------------- | | ||||
| | JsonArray<N>  | 8 + 6 x N     | | ||||
| | JsonObject<N> | 8 + 8 x N     | | ||||
|  | ||||
|  | ||||
| Code size | ||||
| --------- | ||||
|  | ||||
| The following values has been obtained with Arduino IDE 1.0.5, targeting an Arduino Duelmilanove with an ATmega 328. | ||||
|  | ||||
| ### Minimum setup | ||||
|  | ||||
| | Function                            | Size | | ||||
| | ----------------------------------- | ---- | | ||||
| | `JsonObjectBase::printTo()`         | 234  | | ||||
| | `EscapedString::printTo()`          | 196  | | ||||
| | `JsonArrayBase::printTo()`          | 164  | | ||||
| | `Print::print(char const*)`         | 146  | | ||||
| | `JsonObjectBase::operator[]`        | 114  | | ||||
| | `JsonObjectBase::getMatchingPair()` | 72   | | ||||
| | `JsonValue::printPrintableTo()`     | 40   | | ||||
| | `JsonValue::printStringTo()`        | 12   | | ||||
|  | ||||
| ### Additional space for integers | ||||
|  | ||||
| | Function                     | Size | | ||||
| | ---------------------------- | ---- | | ||||
| | `Print::print(long, int)`    | 328  | | ||||
| | `JsonValue::printLongTo()`   | 22   | | ||||
|  | ||||
| ### Additional space for floating point | ||||
|  | ||||
| | Function                       | Size | | ||||
| | ------------------------------ | ---- | | ||||
| | `Print::print(double, int)`    | 1548 | | ||||
| | `JsonValue::printDouleTo<2>()` | 22   | | ||||
| @@ -1,17 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| size_t StringBuilder::write(uint8_t c) | ||||
| { | ||||
|     if (_length >= _capacity) return 0; | ||||
|  | ||||
|     _buffer[_length++] = c; | ||||
|     _buffer[_length] = 0; | ||||
|     return 1; | ||||
| } | ||||
| @@ -1,31 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Print.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Internals | ||||
|     { | ||||
|         class StringBuilder : public Print | ||||
|         { | ||||
|         public: | ||||
|             StringBuilder(char* buf, int size) | ||||
|                 : _buffer(buf), _capacity(size - 1), _length(0) | ||||
|             { | ||||
|                 _buffer[0] = 0; | ||||
|             } | ||||
|  | ||||
|             virtual size_t write(uint8_t c); | ||||
|  | ||||
|         private: | ||||
|             char* _buffer; | ||||
|             int _capacity; | ||||
|             int _length; | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,95 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "EscapedString.h" | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(EscapedStringTests) | ||||
|     { | ||||
|         char buffer[1024]; | ||||
|         size_t returnValue; | ||||
|          | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(Null) | ||||
|         { | ||||
|             whenInputIs(0); | ||||
|             outputMustBe("null"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EmptyString) | ||||
|         { | ||||
|             whenInputIs(""); | ||||
|             outputMustBe("\"\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(QuotationMark) | ||||
|         { | ||||
|             whenInputIs("\""); | ||||
|             outputMustBe("\"\\\"\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ReverseSolidus) | ||||
|         { | ||||
|             whenInputIs("\\"); | ||||
|             outputMustBe("\"\\\\\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Solidus) | ||||
|         { | ||||
|             whenInputIs("/"); | ||||
|             outputMustBe("\"/\""); // but the JSON format allows \/ | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Backspace) | ||||
|         { | ||||
|             whenInputIs("\b"); | ||||
|             outputMustBe("\"\\b\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Formfeed) | ||||
|         { | ||||
|             whenInputIs("\f"); | ||||
|             outputMustBe("\"\\f\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Newline) | ||||
|         { | ||||
|             whenInputIs("\n"); | ||||
|             outputMustBe("\"\\n\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(CarriageReturn) | ||||
|         { | ||||
|             whenInputIs("\r"); | ||||
|             outputMustBe("\"\\r\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(HorizontalTab) | ||||
|         { | ||||
|             whenInputIs("\t"); | ||||
|             outputMustBe("\"\\t\""); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         void whenInputIs(const char* input) | ||||
|         { | ||||
|             StringBuilder sb(buffer, sizeof(buffer));   | ||||
|             returnValue = EscapedString::printTo(input, sb); | ||||
|         } | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|             Assert::AreEqual(strlen(expected), returnValue); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,73 +0,0 @@ | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(Issue10) | ||||
|     { | ||||
|         struct Person { | ||||
|             int id; | ||||
|             char name[32]; | ||||
|         }; | ||||
|  | ||||
|         Person persons[2]; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD_INITIALIZE(Initialize) | ||||
|         { | ||||
|             Person boss; | ||||
|             boss.id = 1; | ||||
|             strcpy(boss.name, "Jeff"); | ||||
|             Person employee; | ||||
|             employee.id = 2; | ||||
|             strcpy(employee.name, "John"); | ||||
|             persons[0] = boss; | ||||
|             persons[1] = employee; | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(WrongWayToAddObjectInAnArray) | ||||
|         { | ||||
|             JsonArray<2> json; | ||||
|  | ||||
|             for (int i = 0; i < 2; i++) | ||||
|             { | ||||
|                 JsonObject<2> object; | ||||
|                  | ||||
|                 object["id"] = persons[i].id; | ||||
|                 object["name"] = persons[i].name; | ||||
|  | ||||
|                 json.add(object); // <- Adding a reference to a temporary variable | ||||
|             } | ||||
|  | ||||
|             char buffer[256]; | ||||
|             json.printTo(buffer, sizeof(buffer)); | ||||
|  | ||||
|             // the same values are repeated, that's normal | ||||
|             Assert::AreEqual("[{\"id\":2,\"name\":\"John\"},{\"id\":2,\"name\":\"John\"}]", buffer);   | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(RightWayToAddObjectInAnArray) | ||||
|         { | ||||
|             JsonArray<2> json; | ||||
|             JsonObject<2> object[2]; | ||||
|  | ||||
|             for (int i = 0; i < 2; i++)  | ||||
|             { | ||||
|                 object[i]["id"] = persons[i].id; | ||||
|                 object[i]["name"] = persons[i].name; | ||||
|  | ||||
|                 json.add(object[i]); | ||||
|             } | ||||
|  | ||||
|             char buffer[256]; | ||||
|             json.printTo(buffer, sizeof(buffer)); | ||||
|  | ||||
|             Assert::AreEqual("[{\"id\":1,\"name\":\"Jeff\"},{\"id\":2,\"name\":\"John\"}]", buffer); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,162 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Generator; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| {		 | ||||
|     TEST_CLASS(JsonArrayTests) | ||||
|     { | ||||
|         JsonArray<2> array; | ||||
|         char buffer[256]; | ||||
|  | ||||
|     public: | ||||
|          | ||||
|         TEST_METHOD(Empty) | ||||
|         { | ||||
|             outputMustBe("[]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Null) | ||||
|         { | ||||
|             array.add(static_cast<char*>(0)); | ||||
|  | ||||
|             outputMustBe("[null]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneString) | ||||
|         { | ||||
|             array.add("hello"); | ||||
|  | ||||
|             outputMustBe("[\"hello\"]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoStrings) | ||||
|         { | ||||
|             array.add("hello"); | ||||
|             array.add("world"); | ||||
|  | ||||
|             outputMustBe("[\"hello\",\"world\"]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneStringOverCapacity) | ||||
|         { | ||||
|             array.add("hello"); | ||||
|             array.add("world"); | ||||
|             array.add("lost"); | ||||
|  | ||||
|             outputMustBe("[\"hello\",\"world\"]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneDoubleDefaultDigits) | ||||
|         { | ||||
|             array.add(3.14159265358979323846); | ||||
|             outputMustBe("[3.14]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneDoubleFourDigits) | ||||
|         { | ||||
|             array.add<4>(3.14159265358979323846); | ||||
|             outputMustBe("[3.1416]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneInteger) | ||||
|         { | ||||
|             array.add(1); | ||||
|  | ||||
|             outputMustBe("[1]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoIntegers) | ||||
|         { | ||||
|             array.add(1); | ||||
|             array.add(2); | ||||
|  | ||||
|             outputMustBe("[1,2]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneIntegerOverCapacity) | ||||
|         { | ||||
|             array.add(1); | ||||
|             array.add(2); | ||||
|             array.add(3); | ||||
|  | ||||
|             outputMustBe("[1,2]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneTrue) | ||||
|         { | ||||
|             array.add(true); | ||||
|  | ||||
|             outputMustBe("[true]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneFalse) | ||||
|         { | ||||
|             array.add(false); | ||||
|  | ||||
|             outputMustBe("[false]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoBooleans) | ||||
|         { | ||||
|             array.add(false); | ||||
|             array.add(true); | ||||
|  | ||||
|             outputMustBe("[false,true]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneBooleanOverCapacity) | ||||
|         { | ||||
|             array.add(false); | ||||
|             array.add(true); | ||||
|             array.add(false); | ||||
|  | ||||
|             outputMustBe("[false,true]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneEmptyNestedArray) | ||||
|         { | ||||
|             JsonArray<1> nestedArray; | ||||
|              | ||||
|             array.add(nestedArray); | ||||
|  | ||||
|             outputMustBe("[[]]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneEmptyNestedHash) | ||||
|         { | ||||
|             JsonObject<1> nestedObject; | ||||
|  | ||||
|             array.add(nestedObject); | ||||
|  | ||||
|             outputMustBe("[{}]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneNestedArrayWithOneInteger) | ||||
|         { | ||||
|             JsonArray<1> nestedArray; | ||||
|             nestedArray.add(1); | ||||
|  | ||||
|             array.add(nestedArray); | ||||
|  | ||||
|             outputMustBe("[[1]]"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         {       | ||||
|             size_t n = array.printTo(buffer, sizeof(buffer)); | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|             Assert::AreEqual(strlen(expected), n); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,107 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup Label="ProjectConfigurations"> | ||||
|     <ProjectConfiguration Include="Debug|Win32"> | ||||
|       <Configuration>Debug</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|     <ProjectConfiguration Include="Release|Win32"> | ||||
|       <Configuration>Release</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|   </ItemGroup> | ||||
|   <PropertyGroup Label="Globals"> | ||||
|     <ProjectGuid>{B9545D97-E084-4A19-8E48-929157064360}</ProjectGuid> | ||||
|     <Keyword>Win32Proj</Keyword> | ||||
|     <RootNamespace>JsonGeneratorTests</RootNamespace> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>true</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|     <UseOfMfc>false</UseOfMfc> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>false</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|     <UseOfMfc>false</UseOfMfc> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
|   <ImportGroup Label="ExtensionSettings"> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <PropertyGroup Label="UserMacros" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <LinkIncremental>true</LinkIncremental> | ||||
|     <IncludePath>$(ProjectDir)/../JsonGenerator;$(IncludePath)</IncludePath> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <LinkIncremental>true</LinkIncremental> | ||||
|     <IncludePath>$(ProjectDir)/../JsonGenerator;$(IncludePath)</IncludePath> | ||||
|   </PropertyGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <ClCompile> | ||||
|       <PrecompiledHeader>NotUsing</PrecompiledHeader> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <Optimization>Disabled</Optimization> | ||||
|       <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <PreprocessorDefinitions>ARDUINO_JSON_NO_DEPRECATION_WARNING;_DEBUG;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|       <UseFullPaths>true</UseFullPaths> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <ClCompile> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <PrecompiledHeader>Use</PrecompiledHeader> | ||||
|       <Optimization>MaxSpeed</Optimization> | ||||
|       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||
|       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||
|       <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|       <UseFullPaths>true</UseFullPaths> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||
|       <OptimizeReferences>true</OptimizeReferences> | ||||
|       <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="EscapedStringTests.cpp" /> | ||||
|     <ClCompile Include="PrettyPrint_Array_Tests.cpp" /> | ||||
|     <ClCompile Include="PrettyPrint_Object_Tests.cpp" /> | ||||
|     <ClCompile Include="PrettyPrint_String_Tests.cpp" /> | ||||
|     <ClCompile Include="Issue10.cpp" /> | ||||
|     <ClCompile Include="JsonArrayTests.cpp" /> | ||||
|     <ClCompile Include="JsonObject_Indexer_Tests.cpp" /> | ||||
|     <ClCompile Include="JsonObject_PrintTo_Tests.cpp" /> | ||||
|     <ClCompile Include="JsonValue_Cast_Tests.cpp" /> | ||||
|     <ClCompile Include="JsonValue_PrintTo_Tests.cpp" /> | ||||
|     <ClCompile Include="StringBuilderTests.cpp" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\JsonGenerator\JsonGenerator.vcxproj"> | ||||
|       <Project>{c6536d27-738d-4ceb-a2bc-e13c8897d894}</Project> | ||||
|     </ProjectReference> | ||||
|   </ItemGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
|   <ImportGroup Label="ExtensionTargets"> | ||||
|   </ImportGroup> | ||||
| </Project> | ||||
| @@ -1,52 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup> | ||||
|     <Filter Include="Source Files"> | ||||
|       <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | ||||
|       <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Header Files"> | ||||
|       <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | ||||
|       <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Resource Files"> | ||||
|       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | ||||
|       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | ||||
|     </Filter> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="JsonArrayTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="StringBuilderTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="EscapedStringTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonObject_PrintTo_Tests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonObject_Indexer_Tests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonValue_PrintTo_Tests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonValue_Cast_Tests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="Issue10.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="PrettyPrint_Array_Tests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="PrettyPrint_Object_Tests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="PrettyPrint_String_Tests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
| @@ -1,73 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Generator; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(JsonObject_Indexer_Tests) | ||||
|     { | ||||
|         JsonObject<2> object; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(Empty) | ||||
|         { | ||||
|             mustNotContain("key"); | ||||
|         } | ||||
|          | ||||
|         TEST_METHOD(TwoStrings) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|  | ||||
|             mustContain("key1", "value1"); | ||||
|             mustContain("key2", "value2"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(RemoveFirst) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|             object.remove("key1"); | ||||
|  | ||||
|             mustNotContain("key1"); | ||||
|             mustContain("key2", "value2"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(RemoveLast) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|             object.remove("key2"); | ||||
|  | ||||
|             mustContain("key1", "value1"); | ||||
|             mustNotContain("key2"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void mustContain(const char* key, const char* expected) | ||||
|         { | ||||
|             Assert::IsTrue(object.containsKey(key)); | ||||
|  | ||||
|             const char* actual = object[key]; | ||||
|             Assert::AreEqual(expected, actual); | ||||
|         } | ||||
|  | ||||
|         void mustNotContain(const char* key) | ||||
|         { | ||||
|             Assert::IsFalse(object.containsKey(key)); | ||||
|  | ||||
|             const char* actual = object[key]; | ||||
|             Assert::IsNull(actual); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,152 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Generator; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(JsonObject_PrintTo_Tests) | ||||
|     { | ||||
|         JsonObject<2> object; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(Empty) | ||||
|         { | ||||
|             outputMustBe("{}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneString) | ||||
|         { | ||||
|             object["key"] = "value"; | ||||
|  | ||||
|             outputMustBe("{\"key\":\"value\"}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoStrings) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|  | ||||
|             outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(RemoveFirst) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|             object.remove("key1"); | ||||
|  | ||||
|             outputMustBe("{\"key2\":\"value2\"}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(RemoveLast) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|             object.remove("key2"); | ||||
|  | ||||
|             outputMustBe("{\"key1\":\"value1\"}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(RemoveUnexistingKey) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|             object.remove("key3"); | ||||
|  | ||||
|             outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ReplaceExistingKey) | ||||
|         { | ||||
|             object["key"] = "value1"; | ||||
|             object["key"] = "value2"; | ||||
|  | ||||
|             outputMustBe("{\"key\":\"value2\"}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneStringOverCapacity) | ||||
|         { | ||||
|             object["key1"] = "value1"; | ||||
|             object["key2"] = "value2"; | ||||
|             object["key3"] = "value3"; | ||||
|  | ||||
|             outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneInteger) | ||||
|         { | ||||
|             object["key"] = 1; | ||||
|             outputMustBe("{\"key\":1}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneDoubleFourDigits) | ||||
|         { | ||||
|             object["key"].set<4>(3.14159265358979323846); | ||||
|             outputMustBe("{\"key\":3.1416}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneDoubleDefaultDigits) | ||||
|         { | ||||
|             object["key"] = 3.14159265358979323846; | ||||
|             outputMustBe("{\"key\":3.14}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneNull) | ||||
|         { | ||||
|             object["key"] = static_cast<char*>(0); | ||||
|             outputMustBe("{\"key\":null}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneTrue) | ||||
|         { | ||||
|             object["key"] = true; | ||||
|             outputMustBe("{\"key\":true}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneFalse) | ||||
|         { | ||||
|             object["key"] = false; | ||||
|             outputMustBe("{\"key\":false}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneEmptyNestedArray) | ||||
|         { | ||||
|             auto nestedArray = JsonArray<1>(); | ||||
|  | ||||
|             object["key"] = nestedArray; | ||||
|              | ||||
|             outputMustBe("{\"key\":[]}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneEmptyNestedObject) | ||||
|         { | ||||
|             auto nestedObject = JsonObject<1>(); | ||||
|  | ||||
|             object["key"] = nestedObject; | ||||
|  | ||||
|             outputMustBe("{\"key\":{}}"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             char buffer[256]; | ||||
|             size_t result; | ||||
|              | ||||
|             result = object.printTo(buffer, sizeof(buffer)); | ||||
|              | ||||
|             Assert::AreEqual(strlen(expected), result); | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,80 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "StringBuilder.h" | ||||
| #include "JsonValue.h" | ||||
| #include "JsonArray.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(JsonValue_Cast_Tests) | ||||
|     { | ||||
|         JsonValue value; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(Bool) | ||||
|         { | ||||
|             setValueAndCheckCast(true); | ||||
|             setValueAndCheckCast(false); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Double) | ||||
|         { | ||||
|             setValueAndCheckCast(3.14156); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Float) | ||||
|         { | ||||
|             setValueAndCheckCast(3.14f); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Integer) | ||||
|         { | ||||
|             setValueAndCheckCast(42); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Long) | ||||
|         { | ||||
|             setValueAndCheckCast(42L); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Array) | ||||
|         { | ||||
|             JsonArray<2> array; | ||||
|             setValueAndCheckCast(array); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(String) | ||||
|         { | ||||
|             setValueAndCheckCast("hello"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         template<typename T> | ||||
|         void setValueAndCheckCast(T expected) | ||||
|         { | ||||
|             value = expected; | ||||
|             T actual = value; | ||||
|             Assert::AreEqual(expected, actual); | ||||
|         } | ||||
|  | ||||
|         template<int N> | ||||
|         void setValueAndCheckCast(JsonArray<N>& expected) | ||||
|         { | ||||
|             value = expected; | ||||
|             const Printable& actual = value; | ||||
|             Assert::AreEqual( | ||||
|                 reinterpret_cast<const void*>(&expected),  | ||||
|                 reinterpret_cast<const void*>(&actual)); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,109 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "StringBuilder.h" | ||||
| #include "JsonValue.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(JsonValue_PrintTo_Tests) | ||||
|     { | ||||
|         char buffer[1024]; | ||||
|         size_t returnValue; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(String) | ||||
|         { | ||||
|             setValueTo("hello"); | ||||
|             outputMustBe("\"hello\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ZeroFloat) | ||||
|         { | ||||
|             setValueTo(0.0f); | ||||
|             outputMustBe("0.0"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Float) | ||||
|         { | ||||
|             setValueTo(3.1415f); | ||||
|             outputMustBe("3.14"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(DoubleZeroDigits) | ||||
|         { | ||||
|             setValueTo<0>(3.14159265358979323846); | ||||
|             outputMustBe("3"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(DoubleOneDigit) | ||||
|         { | ||||
|             setValueTo<1>(3.14159265358979323846); | ||||
|             outputMustBe("3.1"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(DoubleTwoDigits) | ||||
|         { | ||||
|             setValueTo<2>(3.14159265358979323846); | ||||
|             outputMustBe("3.14"); | ||||
|         } | ||||
|          | ||||
|         TEST_METHOD(Integer) | ||||
|         { | ||||
|             setValueTo(314); | ||||
|             outputMustBe("314"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Char) | ||||
|         { | ||||
|             setValueTo('A'); | ||||
|             outputMustBe("65"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Short) | ||||
|         { | ||||
|             setValueTo(static_cast<short>(314)); | ||||
|             outputMustBe("314"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(Long) | ||||
|         { | ||||
|             setValueTo(314159265L); | ||||
|             outputMustBe("314159265"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         template<int DIGITS> | ||||
|         void setValueTo(double value) | ||||
|         { | ||||
|             StringBuilder sb(buffer, sizeof(buffer)); | ||||
|             JsonValue jsonValue; | ||||
|             jsonValue.set<DIGITS>(value); | ||||
|             returnValue = jsonValue.printTo(sb); | ||||
|         } | ||||
|  | ||||
|         template<typename T> | ||||
|         void setValueTo(T value) | ||||
|         { | ||||
|             StringBuilder sb(buffer, sizeof(buffer)); | ||||
|             JsonValue jsonValue; | ||||
|             jsonValue = value; | ||||
|             returnValue = jsonValue.printTo(sb); | ||||
|         } | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|             Assert::AreEqual(strlen(expected), returnValue); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,91 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonPrettyPrint.h" | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(PrettyPrint_Array_Tests) | ||||
|     { | ||||
|         char buffer[1024]; | ||||
|         size_t returnValue; | ||||
|  | ||||
|     public: | ||||
|          | ||||
|         TEST_METHOD(EmptyArray) | ||||
|         { | ||||
|             whenInputIs("[]"); | ||||
|             outputMustBe("[]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneElement) | ||||
|         { | ||||
|             whenInputIs("[1]"); | ||||
|             outputMustBe( | ||||
|                 "[\r\n" | ||||
|                 "  1\r\n" | ||||
|                 "]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoElements) | ||||
|         { | ||||
|             whenInputIs("[1,2]"); | ||||
|             outputMustBe( | ||||
|                 "[\r\n" | ||||
|                 "  1,\r\n" | ||||
|                 "  2\r\n" | ||||
|                 "]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EmptyNestedArrays) | ||||
|         { | ||||
|             whenInputIs("[[],[]]"); | ||||
|             outputMustBe( | ||||
|                 "[\r\n" | ||||
|                 "  [],\r\n" | ||||
|                 "  []\r\n" | ||||
|                 "]"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(NestedArrays) | ||||
|         { | ||||
|             whenInputIs("[[1,2],[3,4]]"); | ||||
|             outputMustBe( | ||||
|                 "[\r\n" | ||||
|                 "  [\r\n" | ||||
|                 "    1,\r\n" | ||||
|                 "    2\r\n" | ||||
|                 "  ],\r\n" | ||||
|                 "  [\r\n" | ||||
|                 "    3,\r\n" | ||||
|                 "    4\r\n" | ||||
|                 "  ]\r\n" | ||||
|                 "]"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void whenInputIs(const char input[]) | ||||
|         { | ||||
|             StringBuilder sb(buffer, sizeof(buffer)); | ||||
|             IndentedPrint indentedPrint(sb); | ||||
|             JsonPrettyPrint decorator(indentedPrint); | ||||
|  | ||||
|             returnValue = decorator.print(input); | ||||
|         } | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|             Assert::AreEqual(strlen(expected), returnValue); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,89 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonPrettyPrint.h" | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(PrettyPrint_Object_Tests) | ||||
|     { | ||||
|         char buffer[1024]; | ||||
|         size_t returnValue; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(EmptyObject) | ||||
|         { | ||||
|             whenInputIs("{}"); | ||||
|             outputMustBe("{}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneMember) | ||||
|         { | ||||
|             whenInputIs("{\"key\":\"value\"}"); | ||||
|             outputMustBe( | ||||
|                 "{\r\n" | ||||
|                 "  \"key\": \"value\"\r\n" | ||||
|                 "}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoMembers) | ||||
|         { | ||||
|             whenInputIs("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
|             outputMustBe( | ||||
|                 "{\r\n" | ||||
|                 "  \"key1\": \"value1\",\r\n" | ||||
|                 "  \"key2\": \"value2\"\r\n" | ||||
|                 "}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EmptyNestedObjects) | ||||
|         { | ||||
|             whenInputIs("{\"key1\":{},\"key2\":{}}"); | ||||
|             outputMustBe( | ||||
|                 "{\r\n" | ||||
|                 "  \"key1\": {},\r\n" | ||||
|                 "  \"key2\": {}\r\n" | ||||
|                 "}"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(NestedObjects) | ||||
|         { | ||||
|             whenInputIs("{\"key1\":{\"a\":1},\"key2\":{\"b\":2}}"); | ||||
|             outputMustBe( | ||||
|                 "{\r\n" | ||||
|                 "  \"key1\": {\r\n" | ||||
|                 "    \"a\": 1\r\n" | ||||
|                 "  },\r\n" | ||||
|                 "  \"key2\": {\r\n" | ||||
|                 "    \"b\": 2\r\n" | ||||
|                 "  }\r\n" | ||||
|                 "}"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void whenInputIs(const char input[]) | ||||
|         { | ||||
|             StringBuilder sb(buffer, sizeof(buffer)); | ||||
|             IndentedPrint indentedPrint(sb); | ||||
|             JsonPrettyPrint decorator(indentedPrint); | ||||
|  | ||||
|             returnValue = decorator.print(input); | ||||
|         } | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|             Assert::AreEqual(strlen(expected), returnValue); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,76 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonPrettyPrint.h" | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(PrettyPrint_String_Tests) | ||||
|     { | ||||
|         char buffer[1024]; | ||||
|         size_t returnValue; | ||||
|  | ||||
|     public: | ||||
|          | ||||
|         TEST_METHOD(EmptyString) | ||||
|         { | ||||
|             whenInputIs(""); | ||||
|             outputMustBe(""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TrickyCharacters) | ||||
|         { | ||||
|             whenInputIs ("\":\\\"',\""); | ||||
|             outputMustBe("\":\\\"',\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OpeningCurlyBrace) | ||||
|         { | ||||
|             whenInputIs ("\"{\""); | ||||
|             outputMustBe("\"{\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OpeningSquareBrace) | ||||
|         { | ||||
|             whenInputIs("\"[\""); | ||||
|             outputMustBe("\"[\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ClosingCurlyBrace) | ||||
|         { | ||||
|             whenInputIs("\"}\""); | ||||
|             outputMustBe("\"}\""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ClosingSquareBrace) | ||||
|         { | ||||
|             whenInputIs("\"]\""); | ||||
|             outputMustBe("\"]\""); | ||||
|         } | ||||
|                 | ||||
|     private: | ||||
|  | ||||
|         void whenInputIs(const char input[]) | ||||
|         { | ||||
|             StringBuilder sb(buffer, sizeof(buffer)); | ||||
|             IndentedPrint indentedPrint(sb); | ||||
|             JsonPrettyPrint decorator(indentedPrint); | ||||
|  | ||||
|             returnValue = decorator.print(input); | ||||
|         } | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|             Assert::AreEqual(strlen(expected), returnValue); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,85 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "StringBuilder.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| namespace JsonGeneratorTests | ||||
| { | ||||
|     TEST_CLASS(StringBuilderTests) | ||||
|     { | ||||
|         char buffer[20]; | ||||
|         Print* sb; | ||||
|         size_t returnValue; | ||||
|  | ||||
|     public: | ||||
|          | ||||
|         TEST_METHOD_INITIALIZE(Initialize) | ||||
|         { | ||||
|             sb = new StringBuilder(buffer, sizeof(buffer)); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(InitialState) | ||||
|         { | ||||
|             outputMustBe(""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OverCapacity) | ||||
|         { | ||||
|             print("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); | ||||
|             resultMustBe(19); | ||||
|  | ||||
|             print("ABC"); | ||||
|             resultMustBe(0); | ||||
|  | ||||
|             outputMustBe("ABCDEFGHIJKLMNOPQRS"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EmptyString) | ||||
|         { | ||||
|             print(""); | ||||
|             resultMustBe(0); | ||||
|             outputMustBe(""); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(OneString) | ||||
|         { | ||||
|             print("ABCD"); | ||||
|             resultMustBe(4); | ||||
|             outputMustBe("ABCD"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoStrings) | ||||
|         { | ||||
|             print("ABCD"); | ||||
|             resultMustBe(4); | ||||
|  | ||||
|             print("EFGH"); | ||||
|             resultMustBe(4); | ||||
|  | ||||
|             outputMustBe("ABCDEFGH"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void print(const char* value) | ||||
|         { | ||||
|             returnValue = sb->print(value); | ||||
|         } | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, buffer); | ||||
|         } | ||||
|  | ||||
|         void resultMustBe(size_t expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, returnValue); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,13 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| // This file is here to help the Arduino IDE find the .cpp files | ||||
|  | ||||
| #include "JsonParser/JsonArray.cpp" | ||||
| #include "JsonParser/JsonObject.cpp" | ||||
| #include "JsonParser/JsonParserBase.cpp" | ||||
| #include "JsonParser/JsonValue.cpp" | ||||
| #include "JsonParser/JsonToken.cpp" | ||||
| #include "JsonParser/jsmn.cpp" | ||||
| @@ -1,6 +0,0 @@ | ||||
| /* | ||||
| * malloc-free JSON parser for Arduino | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonParser/JsonParser.h" | ||||
| @@ -1,14 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
|  | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| DEPRECATED JsonObject JsonArray::getHashTable(int index) | ||||
| { | ||||
|     return operator[](index); | ||||
| } | ||||
| @@ -1,103 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonValue.h" | ||||
| #include "JsonArrayIterator.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         class JsonObject; | ||||
|                  | ||||
|         // A JSON array | ||||
|         class JsonArray : JsonValue | ||||
|         {           | ||||
|         public: | ||||
|  | ||||
|             // Create an invalid array | ||||
|             JsonArray()  | ||||
|             {             | ||||
|             } | ||||
|  | ||||
|             // Convert a JsonValue into a JsonArray | ||||
|             JsonArray(JsonValue value) | ||||
|                 : JsonValue(value) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Tell if the array is valid | ||||
|             bool success() | ||||
|             { | ||||
|                 return isArray(); | ||||
|             } | ||||
|  | ||||
|             // Get the JsonValue at specified index | ||||
|             JsonValue operator[](int index) | ||||
|             { | ||||
|                 return JsonValue::operator[](index); | ||||
|             } | ||||
|  | ||||
|             // Get the size of the array | ||||
|             int size() | ||||
|             { | ||||
|                 return isArray() ? childrenCount() : 0; | ||||
|             } | ||||
|  | ||||
|             // Get an iterator pointing to the beginning of the array | ||||
|             JsonArrayIterator begin() | ||||
|             { | ||||
|                 return isArray() ? firstChild() : null(); | ||||
|             } | ||||
|  | ||||
|             // Gets an iterator pointing to the end of the array | ||||
|             JsonArrayIterator end() | ||||
|             { | ||||
|                 return isArray() ? nextSibling() : null(); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use size() instead | ||||
|             DEPRECATED int getLength() | ||||
|             { | ||||
|                 return size(); | ||||
|             } | ||||
|                     | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED JsonArray getArray(int index) | ||||
|             { | ||||
|                 return operator[](index); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED bool getBool(int index) | ||||
|             { | ||||
|                 return operator[](index); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED double getDouble(int index) | ||||
|             { | ||||
|                 return operator[](index); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED JsonObject getHashTable(int index); | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED long getLong(int index) | ||||
|             { | ||||
|                 return operator[](index); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED char* getString(int index) | ||||
|             { | ||||
|                 return operator[](index); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,46 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonValue.h" | ||||
| #include "JsonToken.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         // An iterator for JsonArray | ||||
|         class JsonArrayIterator : JsonToken | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             // Create an iterator pointing at the specified JsonToken | ||||
|             JsonArrayIterator(JsonToken token) | ||||
|                 : JsonToken(token) | ||||
|             { | ||||
|  | ||||
|             } | ||||
|  | ||||
|             // Move iterator forward | ||||
|             void operator++() | ||||
|             { | ||||
|                 *this = JsonArrayIterator(nextSibling()); | ||||
|             } | ||||
|  | ||||
|             // Get the value pointed by the iterator | ||||
|             JsonValue operator*() const | ||||
|             { | ||||
|                 return JsonValue(*this); | ||||
|             } | ||||
|  | ||||
|             // Test iterator equality | ||||
|             bool operator!= (const JsonArrayIterator& other) const | ||||
|             { | ||||
|                 return JsonToken::operator!=(other); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,15 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
| #include "JsonValue.h" | ||||
|  | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| DEPRECATED JsonArray JsonObject::getArray(const char* key) | ||||
| { | ||||
|     return operator[](key); | ||||
| } | ||||
| @@ -1,102 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonValue.h" | ||||
| #include "JsonObjectIterator.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         class JsonArray; | ||||
|  | ||||
|         // A JSON Object (ie hash-table/dictionary) | ||||
|         class JsonObject : JsonValue | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             // Create an invalid JsonObject | ||||
|             JsonObject() | ||||
|             { | ||||
|  | ||||
|             } | ||||
|  | ||||
|             // Convert a JsonValue into a JsonObject | ||||
|             JsonObject(JsonValue value) | ||||
|                 : JsonValue(value) | ||||
|             { | ||||
|  | ||||
|             } | ||||
|  | ||||
|             // Tell if the object is valid | ||||
|             bool success() | ||||
|             { | ||||
|                 return isObject(); | ||||
|             }            | ||||
|  | ||||
|             // Get the value associated with the specified key. | ||||
|             JsonValue operator[](const char* key) | ||||
|             { | ||||
|                 return JsonValue::operator[](key); | ||||
|             } | ||||
|  | ||||
|             // Tell if the specified key exists in the object. | ||||
|             bool containsKey(const char* key) | ||||
|             { | ||||
|                 return operator[](key).success(); | ||||
|             } | ||||
|  | ||||
|             // Get an iterator pointing at the beginning of the object | ||||
|             JsonObjectIterator begin() | ||||
|             { | ||||
|                 return isObject() ? firstChild() : null(); | ||||
|             } | ||||
|  | ||||
|             // Get an iterator pointing at the end of the object | ||||
|             JsonObjectIterator end() | ||||
|             { | ||||
|                 return isObject() ? nextSibling() : null(); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED JsonArray getArray(const char* key); | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED bool getBool(const char* key) | ||||
|             { | ||||
|                 return operator[](key); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED double getDouble(const char* key) | ||||
|             { | ||||
|                 return operator[](key); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED JsonObject getHashTable(const char* key) | ||||
|             { | ||||
|                 return operator[](key); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED long getLong(const char* key) | ||||
|             { | ||||
|                 return operator[](key); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: Use operator[] instead | ||||
|             DEPRECATED char* getString(const char* key) | ||||
|             { | ||||
|                 return operator[](key); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         // Obsolete: Use JsonObject instead | ||||
|         DEPRECATED typedef JsonObject JsonHashTable; | ||||
|     } | ||||
| } | ||||
| @@ -1,58 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonValue.h" | ||||
| #include "JsonPair.h" | ||||
| #include "JsonToken.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         // An iterator for JsonObject | ||||
|         class JsonObjectIterator : JsonToken | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             // Create an iterator pointing at the specified token | ||||
|             JsonObjectIterator(JsonToken token) | ||||
|                 : JsonToken(token) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Move to the next JsonPair | ||||
|             void operator++() | ||||
|             { | ||||
|                 *this = JsonObjectIterator(nextSibling().nextSibling()); | ||||
|             } | ||||
|  | ||||
|             // Get the JsonPair pointed by the iterator | ||||
|             JsonPair operator*() const | ||||
|             { | ||||
|                 return JsonPair(*this); | ||||
|             } | ||||
|  | ||||
|             // Test iterator equality | ||||
|             bool operator!= (const JsonObjectIterator& other) const | ||||
|             { | ||||
|                 return JsonToken::operator!=(other); | ||||
|             } | ||||
|  | ||||
|             // Get the key of the JsonPair pointed by the iterator | ||||
|             const char* key() const | ||||
|             { | ||||
|                 return operator*().key(); | ||||
|             } | ||||
|  | ||||
|             // Get the key of the JsonPair pointed by the iterator | ||||
|             JsonValue value() const | ||||
|             { | ||||
|                 return operator*().value(); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,37 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonValue.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         // A JSON key-value pair, as a part of a JSON object | ||||
|         class JsonPair : JsonToken | ||||
|         { | ||||
|         public: | ||||
|             // Convert a JsonToken to a JsonPair | ||||
|             JsonPair(JsonToken token) | ||||
|                 : JsonToken(token) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Get the key | ||||
|             const char* key() | ||||
|             { | ||||
|                 return getText(); | ||||
|             } | ||||
|  | ||||
|             // Get the value | ||||
|             JsonValue value() | ||||
|             { | ||||
|                 return nextSibling(); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,35 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonParserBase.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         // The JSON parser. | ||||
|         // | ||||
|         // You need to specifiy the number of token to be allocated for that parser. | ||||
|         // | ||||
|         // CAUTION: JsonArray, JsonObject and JsonValue contain pointers to tokens of the | ||||
|         // JsonParser, so they need the JsonParser to be in memory to work. | ||||
|         // As a result, you must not create JsonArray, JsonObject or JsonValue that have a | ||||
|         // longer life that the JsonParser. | ||||
|         template <int MAX_TOKENS> | ||||
|         class JsonParser : public JsonParserBase | ||||
|         { | ||||
|         public: | ||||
|             JsonParser() | ||||
|                 : JsonParserBase(_tokens, MAX_TOKENS) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|         private: | ||||
|             jsmntok_t _tokens[MAX_TOKENS]; | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,96 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup Label="ProjectConfigurations"> | ||||
|     <ProjectConfiguration Include="Debug|Win32"> | ||||
|       <Configuration>Debug</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|     <ProjectConfiguration Include="Release|Win32"> | ||||
|       <Configuration>Release</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|   </ItemGroup> | ||||
|   <PropertyGroup Label="Globals"> | ||||
|     <ProjectGuid>{C15274DE-2695-4DFE-8520-4424223FE6DA}</ProjectGuid> | ||||
|     <Keyword>Win32Proj</Keyword> | ||||
|     <RootNamespace>JsonParser</RootNamespace> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>true</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>StaticLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>false</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
|   <ImportGroup Label="ExtensionSettings"> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <PropertyGroup Label="UserMacros" /> | ||||
|   <PropertyGroup /> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <ClCompile> | ||||
|       <PrecompiledHeader> | ||||
|       </PrecompiledHeader> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <Optimization>Disabled</Optimization> | ||||
|       <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <ClCompile> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <PrecompiledHeader> | ||||
|       </PrecompiledHeader> | ||||
|       <Optimization>MaxSpeed</Optimization> | ||||
|       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||
|       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||
|       <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||
|       <OptimizeReferences>true</OptimizeReferences> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="jsmn.h" /> | ||||
|     <ClInclude Include="JsonArray.h" /> | ||||
|     <ClInclude Include="JsonArrayIterator.h" /> | ||||
|     <ClInclude Include="JsonObject.h" /> | ||||
|     <ClInclude Include="JsonObjectIterator.h" /> | ||||
|     <ClInclude Include="JsonPair.h" /> | ||||
|     <ClInclude Include="JsonParser.h" /> | ||||
|     <ClInclude Include="JsonParserBase.h" /> | ||||
|     <ClInclude Include="JsonToken.h" /> | ||||
|     <ClInclude Include="JsonValue.h" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="jsmn.cpp" /> | ||||
|     <ClCompile Include="JsonArray.cpp" /> | ||||
|     <ClCompile Include="JsonObject.cpp" /> | ||||
|     <ClCompile Include="JsonParserBase.cpp" /> | ||||
|     <ClCompile Include="JsonToken.cpp" /> | ||||
|     <ClCompile Include="JsonValue.cpp" /> | ||||
|   </ItemGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
|   <ImportGroup Label="ExtensionTargets"> | ||||
|   </ImportGroup> | ||||
| </Project> | ||||
| @@ -1,69 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup> | ||||
|     <Filter Include="Source Files"> | ||||
|       <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | ||||
|       <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Header Files"> | ||||
|       <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | ||||
|       <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Resource Files"> | ||||
|       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | ||||
|       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | ||||
|     </Filter> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="JsonParserBase.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonToken.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonValue.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonParser.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="jsmn.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonArray.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonArrayIterator.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonObject.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonObjectIterator.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="JsonPair.h"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="jsmn.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonArray.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonObject.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonParserBase.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonToken.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonValue.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
| @@ -1,20 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonParserBase.h" | ||||
| #include "JsonToken.h" | ||||
|  | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| JsonValue JsonParserBase::parse(char* json) | ||||
| { | ||||
|     jsmn_parser parser; | ||||
|     jsmn_init(&parser); | ||||
|  | ||||
|     if (JSMN_SUCCESS != jsmn_parse(&parser, json, _tokens, _maxTokens)) | ||||
|         return JsonToken::null(); | ||||
|  | ||||
|     return JsonToken(json, _tokens); | ||||
| } | ||||
| @@ -1,49 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         // Base class for the JSON parser, in case you want to provide your own buffer | ||||
|         class JsonParserBase | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             // Create a JSON parser using the provided buffer | ||||
|             JsonParserBase(jsmntok_t* tokens, int maxTokens) | ||||
|                 : _tokens(tokens), _maxTokens(maxTokens) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Parse the JSON string and return a array | ||||
|             // | ||||
|             // The content of the string may be altered to add '\0' at the | ||||
|             // end of string tokens             | ||||
|             JsonValue parse(char* json); | ||||
|  | ||||
|             // Obsolete: use parse() instead | ||||
|             DEPRECATED JsonArray parseArray(char* json) | ||||
|             { | ||||
|                 return parse(json); | ||||
|             } | ||||
|  | ||||
|             // Obsolete: use parse() instead | ||||
|             DEPRECATED JsonObject parseHashTable(char* json) | ||||
|             { | ||||
|                 return parse(json); | ||||
|             } | ||||
|  | ||||
|         private: | ||||
|             jsmntok_t* _tokens; | ||||
|             int _maxTokens; | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,71 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "JsonToken.h" | ||||
|  | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| char* JsonToken::getText() | ||||
| { | ||||
|     char* s = _json + _token->start; | ||||
|     _json[_token->end] = 0; | ||||
|  | ||||
|     unescapeString(s); | ||||
|  | ||||
|     return s; | ||||
| } | ||||
|  | ||||
| inline void JsonToken::unescapeString(char* s) | ||||
| { | ||||
|     char* readPtr = s; | ||||
|     char* writePtr = s; | ||||
|     char c; | ||||
|  | ||||
|     do | ||||
|     { | ||||
|         c = *readPtr++; | ||||
|  | ||||
|         if (c == '\\') | ||||
|         { | ||||
|             c = unescapeChar(*readPtr++); | ||||
|         } | ||||
|  | ||||
|         *writePtr++ = c; | ||||
|  | ||||
|     } while (c != 0); | ||||
| } | ||||
|  | ||||
| inline char JsonToken::unescapeChar(char c) | ||||
| { | ||||
|     // Optimized for code size on a 8-bit AVR | ||||
|  | ||||
|     const char* p = "b\bf\fn\nr\rt\t"; | ||||
|  | ||||
|     while (true) | ||||
|     { | ||||
|         if (p[0] == 0) return c; | ||||
|         if (p[0] == c) return p[1]; | ||||
|         p += 2; | ||||
|     } | ||||
| } | ||||
|  | ||||
| JsonToken JsonToken::nextSibling() const | ||||
| { | ||||
|     // start with current token | ||||
|     jsmntok_t* t = _token; | ||||
|  | ||||
|     // count the number of token to skip | ||||
|     int yetToVisit = 1; | ||||
|      | ||||
|     // skip all nested tokens | ||||
|     while (yetToVisit) | ||||
|     { | ||||
|         yetToVisit += t->size - 1; | ||||
|         t++; | ||||
|     } | ||||
|  | ||||
|     // build a JsonToken at the new location | ||||
|     return JsonToken(_json, t); | ||||
| } | ||||
| @@ -1,99 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "jsmn.h" | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         // A pointer to a JSON token | ||||
|         class JsonToken | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             // Create a "null" pointer | ||||
|             JsonToken() | ||||
|                 : _token(0) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Create a pointer to the specified JSON token | ||||
|             JsonToken(char* json, jsmntok_t* token) | ||||
|                 : _json(json), _token(token) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Get content of the JSON token | ||||
|             char* getText(); | ||||
|  | ||||
|             // Get the number of children tokens | ||||
|             int childrenCount() | ||||
|             { | ||||
|                 return _token->size; | ||||
|             } | ||||
|  | ||||
|             // Get a pointer to the first child of the current token | ||||
|             JsonToken firstChild() const | ||||
|             { | ||||
|                 return JsonToken(_json, _token + 1); | ||||
|             } | ||||
|  | ||||
|             // Get a pointer to the next sibling token (ie skiping the children tokens) | ||||
|             JsonToken nextSibling() const; | ||||
|  | ||||
|             // Test equality | ||||
|             bool operator!=(const JsonToken& other) const | ||||
|             { | ||||
|                 return _token != other._token; | ||||
|             } | ||||
|  | ||||
|             // Tell if the pointer is "null" | ||||
|             bool isValid() | ||||
|             { | ||||
|                 return _token != 0; | ||||
|             } | ||||
|  | ||||
|             // Tell if the JSON token is a JSON object | ||||
|             bool isObject() | ||||
|             { | ||||
|                 return _token != 0 && _token->type == JSMN_OBJECT; | ||||
|             } | ||||
|  | ||||
|             // Tell if the JSON token is a JSON array | ||||
|             bool isArray() | ||||
|             { | ||||
|                 return _token != 0 && _token->type == JSMN_ARRAY; | ||||
|             } | ||||
|  | ||||
|             // Tell if the JSON token is a primitive | ||||
|             bool isPrimitive() | ||||
|             { | ||||
|                 return _token != 0 && _token->type == JSMN_PRIMITIVE; | ||||
|             } | ||||
|  | ||||
|             // Tell if the JSON token is a string | ||||
|             bool isString() | ||||
|             { | ||||
|                 return _token != 0 && _token->type == JSMN_STRING; | ||||
|             } | ||||
|  | ||||
|             // Explicit wait to create a "null" JsonToken | ||||
|             static JsonToken null() | ||||
|             { | ||||
|                 return JsonToken(); | ||||
|             } | ||||
|  | ||||
|         private: | ||||
|             char* _json; | ||||
|             jsmntok_t* _token; | ||||
|              | ||||
|             static char unescapeChar(char c); | ||||
|             static void unescapeString(char* s); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,110 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #include <stdlib.h> // for strtol, strtod | ||||
| #include <string.h> // for strcmp() | ||||
| #include "JsonArray.h" | ||||
| #include "JsonObject.h" | ||||
| #include "JsonValue.h" | ||||
|  | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| // Convert the JsonValue to a bool. | ||||
| // Returns false if the JsonValue is not a primitve. | ||||
| JsonValue::operator bool() | ||||
| { | ||||
|     if (!isPrimitive()) return 0; | ||||
|  | ||||
|     char *text = getText(); | ||||
|  | ||||
|     // "true" | ||||
|     if (text[0] == 't') return true; | ||||
|  | ||||
|     // "false" | ||||
|     if (text[0] == 'f') return false; | ||||
|  | ||||
|     // "null" | ||||
|     if (text[0] == 'n') return false; | ||||
|  | ||||
|     // number | ||||
|     return strtol(text, 0, 0) != 0; | ||||
| } | ||||
|  | ||||
| // Convert the JsonValue to a floating point value. | ||||
| // Returns false if the JsonValue is not a number. | ||||
| JsonValue::operator double() | ||||
| { | ||||
|     return isPrimitive() ? strtod(getText(), 0) : 0; | ||||
| } | ||||
|  | ||||
| // Convert the JsonValue to a floating point value. | ||||
| // Returns false if the JsonValue is not a number. | ||||
| JsonValue::operator long() | ||||
| { | ||||
|     return isPrimitive() ? strtol(getText(), 0, 0) : 0; | ||||
| } | ||||
|  | ||||
| // Convert the JsonValue to a string. | ||||
| // Returns 0 if the JsonValue is not a string. | ||||
| JsonValue::operator char*() | ||||
| { | ||||
|     return isString() || isPrimitive() ? getText() : 0; | ||||
| } | ||||
|  | ||||
| // Get the nested value at the specified index.             | ||||
| // Returns an invalid JsonValue if the current value is not an array. | ||||
| JsonValue JsonValue::operator[](int index) | ||||
| { | ||||
|     // sanity check | ||||
|     if (index < 0 || !isArray() || index >= childrenCount()) | ||||
|         return null(); | ||||
|  | ||||
|     // skip first token, it's the whole object | ||||
|     JsonToken runningToken = firstChild(); | ||||
|  | ||||
|     // skip all tokens before the specified index | ||||
|     for (int i = 0; i < index; i++) | ||||
|     { | ||||
|         // move forward: current + nested tokens | ||||
|         runningToken = runningToken.nextSibling(); | ||||
|     } | ||||
|  | ||||
|     return runningToken; | ||||
| } | ||||
|  | ||||
| // Get the nested value matching the specified index.             | ||||
| // Returns an invalid JsonValue if the current value is not an object. | ||||
| JsonValue JsonValue::operator[](const char* desiredKey) | ||||
| { | ||||
|     // sanity check | ||||
|     if (desiredKey == 0 || !isObject()) | ||||
|         return null(); | ||||
|  | ||||
|     // skip first token, it's the whole object | ||||
|     JsonToken runningToken = firstChild(); | ||||
|  | ||||
|     // scan each keys | ||||
|     for (int i = 0; i < childrenCount() / 2; i++) | ||||
|     { | ||||
|         // get 'key' token string | ||||
|         char* key = runningToken.getText(); | ||||
|  | ||||
|         // move to the 'value' token | ||||
|         runningToken = runningToken.nextSibling(); | ||||
|  | ||||
|         // compare with desired name | ||||
|         if (strcmp(desiredKey, key) == 0) | ||||
|         { | ||||
|             // return the value token that follows the key token | ||||
|             return runningToken; | ||||
|         } | ||||
|  | ||||
|         // skip nested tokens | ||||
|         runningToken = runningToken.nextSibling(); | ||||
|     } | ||||
|  | ||||
|     // nothing found, return NULL | ||||
|     return null(); | ||||
| } | ||||
| @@ -1,72 +0,0 @@ | ||||
| /* | ||||
|  * Arduino JSON library | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonToken.h" | ||||
|  | ||||
| #ifndef ARDUINO_JSON_NO_DEPRECATION_WARNING | ||||
| #ifdef __GNUC__ | ||||
| #define DEPRECATED __attribute__((deprecated)) | ||||
| #elif defined(_MSC_VER) | ||||
| #define DEPRECATED __declspec(deprecated) | ||||
| #endif | ||||
| #else | ||||
| #define DEPRECATED | ||||
| #endif | ||||
|  | ||||
| namespace ArduinoJson | ||||
| { | ||||
|     namespace Parser | ||||
|     { | ||||
|         // A JSON value | ||||
|         // Can be converted to string, double, bool, array or object. | ||||
|         class JsonValue : protected JsonToken | ||||
|         { | ||||
|         public: | ||||
|  | ||||
|             // Create a invalid value | ||||
|             JsonValue() | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Convert a JsonToken to a JsonValue | ||||
|             JsonValue(JsonToken token) | ||||
|                 : JsonToken(token) | ||||
|             { | ||||
|             } | ||||
|  | ||||
|             // Tell is the JsonValue is valid | ||||
|             bool success() | ||||
|             { | ||||
|                 return isValid(); | ||||
|             } | ||||
|  | ||||
|             // Convert the JsonValue to a bool. | ||||
|             // Returns false if the JsonValue is not a primitve. | ||||
|             operator bool(); | ||||
|  | ||||
|             // Convert the JsonValue to a floating point value. | ||||
|             // Returns false if the JsonValue is not a number. | ||||
|             operator double(); | ||||
|  | ||||
|             // Convert the JsonValue to a long integer. | ||||
|             // Returns 0 if the JsonValue is not a number. | ||||
|             operator long(); | ||||
|  | ||||
|             // Convert the JsonValue to a string. | ||||
|             // Returns 0 if the JsonValue is not a string. | ||||
|             operator char*();             | ||||
|              | ||||
|             // Get the nested value at the specified index.             | ||||
|             // Returns an invalid JsonValue if the current value is not an array. | ||||
|             JsonValue operator[](int index); | ||||
|  | ||||
|             // Get the nested value matching the specified index.             | ||||
|             // Returns an invalid JsonValue if the current value is not an object. | ||||
|             JsonValue operator[](const char* key); | ||||
|         }; | ||||
|     } | ||||
| } | ||||
| @@ -1,250 +0,0 @@ | ||||
| Arduino JSON library - Parser | ||||
| ============================= | ||||
|  | ||||
| This library is an thin C++ wrapper around the *jsmn* tokenizer: http://zserge.com/jsmn.html | ||||
|  | ||||
| It's design to be very lightweight, works without any allocation on the heap (no malloc) and supports nested objects. | ||||
|  | ||||
| It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project. | ||||
|  | ||||
|  | ||||
| Features | ||||
| -------- | ||||
|  | ||||
| * Based on the well-proven [jsmn](http://zserge.com/jsmn.html) tokenizer | ||||
| * Supports nested objects | ||||
| * Elegant API, very easy to use  | ||||
| * Fixed memory allocation (no malloc) | ||||
| * Small footprint | ||||
| * MIT License | ||||
|  | ||||
|  | ||||
| Example | ||||
| ------- | ||||
|  | ||||
| 	JsonParser<32> parser; | ||||
|     char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";    | ||||
|  | ||||
|     JsonObject root = parser.parse(json); | ||||
|  | ||||
|     char*  sensor    = root["sensor"]; | ||||
|     long   time      = root["time"]; | ||||
|     double latitude  = root["data"][0]; | ||||
|     double longitude = root["data"][1]; | ||||
|  | ||||
|  | ||||
| How to  use ? | ||||
| ------------- | ||||
|  | ||||
| ### 1. Install the library | ||||
|  | ||||
| Download the library and extract it to: | ||||
|  | ||||
|     <your Arduino Sketch folder>/libraries/ArduinoJson | ||||
|  | ||||
| ### 2. Import in your sketch | ||||
|  | ||||
| Just add the following lines at the top of your `.ino` file: | ||||
|  | ||||
|     #include <JsonParser.h> | ||||
|  | ||||
|     using namespace ArduinoJson::Parser; | ||||
|  | ||||
| > ##### Having a namespace conflict? | ||||
| > To be able to use both `ArduinoJson::Generator` and `ArduinoJson::Parser` in the same file, you need to do one of the followings: | ||||
| >  | ||||
| > * Put the `using` statements into different functions | ||||
| > * `using namespace ArduinoJson`, then prefix the type names by `Generator::` or `Parser::` | ||||
| > * Create aliases for the namespaces or the types (C++11 only) | ||||
|      | ||||
| ### 3. Create a parser | ||||
|  | ||||
| To extract data from the JSON string, you need to create a `JsonParser`, and specify the number of token you allocate for the parser itself: | ||||
|  | ||||
|     JsonParser<32> parser; | ||||
|      | ||||
| > #### How to choose the number of tokens ? | ||||
|  | ||||
| > A token is an element of the JSON object: either a key, a value, an object or an array. | ||||
| > As an example the `char json[]` on the top of this page contains 9 tokens (don't forget to count 1 for the whole object and 1 more for the array itself). | ||||
|  | ||||
| > The more tokens you allocate, the more complex the JSON can be, but also the more memory is occupied. | ||||
| > Each token takes 8 bytes, so `sizeof(JsonParser<32>)` is 256 bytes which is quite big in an Arduino with only 2KB of RAM. | ||||
| > Don't forget that you also have to store the JSON string in RAM and it's probably big. | ||||
|  | ||||
| > 32 tokens may seem small, but it's very decent for an 8-bit processor, you wouldn't get better results with other JSON libraries. | ||||
|  | ||||
| ### 4. Extract data | ||||
|  | ||||
| To use this library, you need to know beforehand what is the type of data contained in the JSON string, which is very likely. | ||||
|  | ||||
| The root object has to be either an object (like `{"key":"value"}`) or an array (like `[1,2]`).  | ||||
|  | ||||
| The nested objects can be either arrays, booleans, objects, numbers or strings. | ||||
| If you need other type, you can get the string value and parse it yourself. | ||||
|  | ||||
| #### Object | ||||
|  | ||||
| Consider we have a `char json[]` containing to the following JSON string: | ||||
|  | ||||
|     { | ||||
|         "sensor":"gps", | ||||
| 		"time":1351824120, | ||||
| 		"data":[48.756080,2.302038] | ||||
|     } | ||||
|  | ||||
| In this case the string contains a JSON object, so you need to extract a `JsonObject`: | ||||
|     | ||||
|     JsonObject root = parser.parse(json); | ||||
|      | ||||
| To check if the parsing was successful, you must check: | ||||
|  | ||||
|     if (!root.success()) | ||||
|     { | ||||
|         // Parsing fail: could be an invalid JSON, or too many tokens | ||||
|     } | ||||
|      | ||||
| And then extract the member you need: | ||||
|      | ||||
|     char*  sensor    = root["sensor"]; | ||||
|     long   time      = root["time"]; | ||||
|     double latitude  = root["data"][0]; | ||||
|     double longitude = root["data"][1]; | ||||
|  | ||||
| You can also iterate through the key-value pairs of the object: | ||||
|  | ||||
|     for (JsonObjectIterator i=root.begin(); i!=root.end(); ++i) | ||||
|     { | ||||
|       Serial.println(i.key()); | ||||
|       Serial.println((char*)i.value()); | ||||
|     } | ||||
|      | ||||
| #### Array | ||||
|  | ||||
| Consider we have a `char json[]` containing to the following JSON string: | ||||
|  | ||||
|     [ | ||||
|         [ 1.2, 3.4 ], | ||||
|         [ 5.6, 7.8 ]                | ||||
|     ] | ||||
|  | ||||
| In this case the root object of the JSON string is an array, so you need to extract a `JsonArray`: | ||||
|     | ||||
|     JsonArray root = parser.parse(json); | ||||
|      | ||||
| To check if the parsing was successful, you must check: | ||||
|  | ||||
|     if (!root.success()) | ||||
|     { | ||||
|         // Parsing fail: could be an invalid JSON, or too many tokens | ||||
|     } | ||||
|      | ||||
| And then extract the content by its index in the array: | ||||
|      | ||||
|     double a = root[0][0]; | ||||
| 	double b = root[0][1]; | ||||
| 	double c = root[1][0]; | ||||
| 	double d = root[1][1]; | ||||
|  | ||||
| You can also iterate through the key-value pairs of the object: | ||||
|  | ||||
|     for (JsonArrayIterator i=array.begin(); i!=array.end(); ++i) | ||||
|     { | ||||
|       Serial.println((char*)*i); | ||||
|     } | ||||
| 	 | ||||
| Common pitfalls | ||||
| --------------- | ||||
|  | ||||
| ### 1. Not enough tokens | ||||
|  | ||||
| By design, the library has no way to tell you why `JsonParser::parse()` failed. | ||||
|  | ||||
| There are basically two reasons why they may fail: | ||||
|  | ||||
| 1. the JSON string is invalid | ||||
| 2. the JSON string contains more tokens that the parser can store | ||||
|  | ||||
| So, if you are sure the JSON string is correct and you still can't parse it, you should slightly increase the number of token of the parser. | ||||
|  | ||||
| ### 2. Not enough memory | ||||
|  | ||||
| You may go into unpredictable trouble if you allocate more memory than your processor really has. | ||||
| It's a very common issue in embedded development.  | ||||
|  | ||||
| To diagnose this, look at every big objects in you code and sum their size to check that they fit in RAM. | ||||
|  | ||||
| For example, don't do this: | ||||
|  | ||||
|     char json[1024];        // 1 KB | ||||
|     JsonParser<64> parser;    // 512 B | ||||
|  | ||||
| because it may be too big for a processor with only 2 KB: you need free memory to store other variables and the call stack. | ||||
|  | ||||
| That is why an 8-bit processor is not able to parse long and complex JSON strings. | ||||
|  | ||||
| ### 3. JsonParser not in memory | ||||
|  | ||||
| To reduce the memory consumption, `JsonValue`, `JsonArray` and `JsonObject` contains pointer to the token that are inside the `JsonParser`. This can only work if the `JsonParser` is still in memory. | ||||
|  | ||||
| For example, don't do this: | ||||
|  | ||||
|     JsonArray getArray(char* json) | ||||
|     { | ||||
|         JsonParser<16> parser; | ||||
|         return parser.parseArray(parser);  | ||||
|     } | ||||
|  | ||||
| because the local variable `parser` will be *removed* from memory when the function `getArray()` returns, and the pointer inside `JsonArray` will point to an invalid location. | ||||
|  | ||||
| ### 4. JSON string is altered | ||||
|  | ||||
| This will probably never be an issue, but you need to be aware of this feature. | ||||
|  | ||||
| When you pass a `char[]` to `JsonParser::parse()`, the content of the string will be altered to add `\0` at the end of the tokens. | ||||
|  | ||||
| This is because we want functions like `JsonArray::getString()` to return a null-terminating string without any memory allocation. | ||||
|     | ||||
|  | ||||
| Memory usage | ||||
| ------------ | ||||
|  | ||||
| Here are the size of the main classes of the library. | ||||
|  | ||||
| This table is for an 8-bit Arduino, types would be bigger on a 32-bit processor. | ||||
|  | ||||
| | Type         | Size in bytes | | ||||
| | ------------ | ------------- | | ||||
| | `Parser<N>`  | 4 + 8 x N     | | ||||
| | `JsonArray`  | 4             | | ||||
| | `JsonObject` | 4             | | ||||
| | `JsonValue`  | 4             | | ||||
|  | ||||
| Code size | ||||
| --------- | ||||
|  | ||||
| The sizes have been obtained with Arduino IDE 1.0.5 for a Duemilanove. | ||||
|  | ||||
| ### Minimum setup | ||||
|  | ||||
| | Function                             | Size | | ||||
| | ------------------------------------ | ---- | | ||||
| | `jsmn_parse()`                       | 962  | | ||||
| | `JsonValue::operator[](char const*)` | 218  |  | ||||
| | `JsonParserBase::parse()`            | 116  |  | ||||
| | `JsonValue::operator[](int)`         | 108  | | ||||
| | `strcmp()`                           | 18   |  | ||||
|  | ||||
| ### Additional space for integers | ||||
|  | ||||
| | Function                     | Size | | ||||
| | ---------------------------- | ---- | | ||||
| | `strtol()`                   | 606  | | ||||
| | `JsonValue::operator long()` | 94   | | ||||
|  | ||||
| ### Additional space for floating points | ||||
|  | ||||
| | Function                         | Size  | | ||||
| | -------------------------------- | ----- | | ||||
| | `strtod()`                       | 1369  | | ||||
| | `JsonValue::operator double()`   | 82    | | ||||
| @@ -1,255 +0,0 @@ | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "jsmn.h" | ||||
|  | ||||
| /** | ||||
|  * Allocates a fresh unused token from the token pull. | ||||
|  */ | ||||
| static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser,  | ||||
| 		jsmntok_t *tokens, size_t num_tokens) { | ||||
| 	jsmntok_t *tok; | ||||
| 	if (parser->toknext >= num_tokens) { | ||||
| 		return NULL; | ||||
| 	} | ||||
| 	tok = &tokens[parser->toknext++]; | ||||
| 	tok->start = tok->end = -1; | ||||
| 	tok->size = 0; | ||||
| #ifdef JSMN_PARENT_LINKS | ||||
| 	tok->parent = -1; | ||||
| #endif | ||||
| 	return tok; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Fills token type and boundaries. | ||||
|  */ | ||||
| static void jsmn_fill_token(jsmntok_t *token, jsmntype_t type,  | ||||
|                             int start, int end) { | ||||
| 	token->type = type; | ||||
| 	token->start = start; | ||||
| 	token->end = end; | ||||
| 	token->size = 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Fills next available token with JSON primitive. | ||||
|  */ | ||||
| static jsmnerr_t jsmn_parse_primitive(jsmn_parser *parser, const char *js, | ||||
| 		jsmntok_t *tokens, size_t num_tokens) { | ||||
| 	jsmntok_t *token; | ||||
| 	int start; | ||||
|  | ||||
| 	start = parser->pos; | ||||
|  | ||||
| 	for (; js[parser->pos] != '\0'; parser->pos++) { | ||||
| 		switch (js[parser->pos]) { | ||||
| #ifndef JSMN_STRICT | ||||
| 			/* In strict mode primitive must be followed by "," or "}" or "]" */ | ||||
| 			case ':': | ||||
| #endif | ||||
| 			case '\t' : case '\r' : case '\n' : case ' ' : | ||||
| 			case ','  : case ']'  : case '}' : | ||||
| 				goto found; | ||||
| 		} | ||||
| 		if (js[parser->pos] < 32 || js[parser->pos] >= 127) { | ||||
| 			parser->pos = start; | ||||
| 			return JSMN_ERROR_INVAL; | ||||
| 		} | ||||
| 	} | ||||
| #ifdef JSMN_STRICT | ||||
| 	/* In strict mode primitive must be followed by a comma/object/array */ | ||||
| 	parser->pos = start; | ||||
| 	return JSMN_ERROR_PART; | ||||
| #endif | ||||
|  | ||||
| found: | ||||
| 	token = jsmn_alloc_token(parser, tokens, num_tokens); | ||||
| 	if (token == NULL) { | ||||
| 		parser->pos = start; | ||||
| 		return JSMN_ERROR_NOMEM; | ||||
| 	} | ||||
| 	jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); | ||||
| #ifdef JSMN_PARENT_LINKS | ||||
| 	token->parent = parser->toksuper; | ||||
| #endif | ||||
| 	parser->pos--; | ||||
| 	return JSMN_SUCCESS; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Filsl next token with JSON string. | ||||
|  */ | ||||
| static jsmnerr_t jsmn_parse_string(jsmn_parser *parser, const char *js, | ||||
| 		jsmntok_t *tokens, size_t num_tokens) { | ||||
| 	jsmntok_t *token; | ||||
|  | ||||
| 	int start = parser->pos; | ||||
|  | ||||
| 	parser->pos++; | ||||
|  | ||||
| 	/* Skip starting quote */ | ||||
| 	for (; js[parser->pos] != '\0'; parser->pos++) { | ||||
| 		char c = js[parser->pos]; | ||||
|  | ||||
| 		/* Quote: end of string */ | ||||
| 		if (c == '\"') { | ||||
| 			token = jsmn_alloc_token(parser, tokens, num_tokens); | ||||
| 			if (token == NULL) { | ||||
| 				parser->pos = start; | ||||
| 				return JSMN_ERROR_NOMEM; | ||||
| 			} | ||||
| 			jsmn_fill_token(token, JSMN_STRING, start+1, parser->pos); | ||||
| #ifdef JSMN_PARENT_LINKS | ||||
| 			token->parent = parser->toksuper; | ||||
| #endif | ||||
| 			return JSMN_SUCCESS; | ||||
| 		} | ||||
|  | ||||
| 		/* Backslash: Quoted symbol expected */ | ||||
| 		if (c == '\\') { | ||||
| 			parser->pos++; | ||||
| 			switch (js[parser->pos]) { | ||||
| 				/* Allowed escaped symbols */ | ||||
| 				case '\"': case '/' : case '\\' : case 'b' : | ||||
| 				case 'f' : case 'r' : case 'n'  : case 't' : | ||||
| 					break; | ||||
| 				/* Allows escaped symbol \uXXXX */ | ||||
| 				case 'u': | ||||
| 					/* TODO */ | ||||
| 					break; | ||||
| 				/* Unexpected symbol */ | ||||
| 				default: | ||||
| 					parser->pos = start; | ||||
| 					return JSMN_ERROR_INVAL; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 	parser->pos = start; | ||||
| 	return JSMN_ERROR_PART; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Parse JSON string and fill tokens. | ||||
|  */ | ||||
| jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js, jsmntok_t *tokens,  | ||||
| 		unsigned int num_tokens) { | ||||
| 	jsmnerr_t r; | ||||
| 	int i; | ||||
| 	jsmntok_t *token; | ||||
|  | ||||
| 	for (; js[parser->pos] != '\0'; parser->pos++) { | ||||
| 		char c; | ||||
| 		jsmntype_t type; | ||||
|  | ||||
| 		c = js[parser->pos]; | ||||
| 		switch (c) { | ||||
| 			case '{': case '[': | ||||
| 				token = jsmn_alloc_token(parser, tokens, num_tokens); | ||||
| 				if (token == NULL) | ||||
| 					return JSMN_ERROR_NOMEM; | ||||
| 				if (parser->toksuper != -1) { | ||||
| 					tokens[parser->toksuper].size++; | ||||
| #ifdef JSMN_PARENT_LINKS | ||||
| 					token->parent = parser->toksuper; | ||||
| #endif | ||||
| 				} | ||||
| 				token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); | ||||
| 				token->start = parser->pos; | ||||
| 				parser->toksuper = parser->toknext - 1; | ||||
| 				break; | ||||
| 			case '}': case ']': | ||||
| 				type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); | ||||
| #ifdef JSMN_PARENT_LINKS | ||||
| 				if (parser->toknext < 1) { | ||||
| 					return JSMN_ERROR_INVAL; | ||||
| 				} | ||||
| 				token = &tokens[parser->toknext - 1]; | ||||
| 				for (;;) { | ||||
| 					if (token->start != -1 && token->end == -1) { | ||||
| 						if (token->type != type) { | ||||
| 							return JSMN_ERROR_INVAL; | ||||
| 						} | ||||
| 						token->end = parser->pos + 1; | ||||
| 						parser->toksuper = token->parent; | ||||
| 						break; | ||||
| 					} | ||||
| 					if (token->parent == -1) { | ||||
| 						break; | ||||
| 					} | ||||
| 					token = &tokens[token->parent]; | ||||
| 				} | ||||
| #else | ||||
| 				for (i = parser->toknext - 1; i >= 0; i--) { | ||||
| 					token = &tokens[i]; | ||||
| 					if (token->start != -1 && token->end == -1) { | ||||
| 						if (token->type != type) { | ||||
| 							return JSMN_ERROR_INVAL; | ||||
| 						} | ||||
| 						parser->toksuper = -1; | ||||
| 						token->end = parser->pos + 1; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| 				/* Error if unmatched closing bracket */ | ||||
| 				if (i == -1) return JSMN_ERROR_INVAL; | ||||
| 				for (; i >= 0; i--) { | ||||
| 					token = &tokens[i]; | ||||
| 					if (token->start != -1 && token->end == -1) { | ||||
| 						parser->toksuper = i; | ||||
| 						break; | ||||
| 					} | ||||
| 				} | ||||
| #endif | ||||
| 				break; | ||||
| 			case '\"': | ||||
| 				r = jsmn_parse_string(parser, js, tokens, num_tokens); | ||||
| 				if (r < 0) return r; | ||||
| 				if (parser->toksuper != -1) | ||||
| 					tokens[parser->toksuper].size++; | ||||
| 				break; | ||||
| 			case '\t' : case '\r' : case '\n' : case ':' : case ',': case ' ':  | ||||
| 				break; | ||||
| #ifdef JSMN_STRICT | ||||
| 			/* In strict mode primitives are: numbers and booleans */ | ||||
| 			case '-': case '0': case '1' : case '2': case '3' : case '4': | ||||
| 			case '5': case '6': case '7' : case '8': case '9': | ||||
| 			case 't': case 'f': case 'n' : | ||||
| #else | ||||
| 			/* In non-strict mode every unquoted value is a primitive */ | ||||
| 			default: | ||||
| #endif | ||||
| 				r = jsmn_parse_primitive(parser, js, tokens, num_tokens); | ||||
| 				if (r < 0) return r; | ||||
| 				if (parser->toksuper != -1) | ||||
| 					tokens[parser->toksuper].size++; | ||||
| 				break; | ||||
|  | ||||
| #ifdef JSMN_STRICT | ||||
| 			/* Unexpected char in strict mode */ | ||||
| 			default: | ||||
| 				return JSMN_ERROR_INVAL; | ||||
| #endif | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	for (i = parser->toknext - 1; i >= 0; i--) { | ||||
| 		/* Unmatched opened object or array */ | ||||
| 		if (tokens[i].start != -1 && tokens[i].end == -1) { | ||||
| 			return JSMN_ERROR_PART; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return JSMN_SUCCESS; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Creates a new parser based over a given  buffer with an array of tokens  | ||||
|  * available. | ||||
|  */ | ||||
| void jsmn_init(jsmn_parser *parser) { | ||||
| 	parser->pos = 0; | ||||
| 	parser->toknext = 0; | ||||
| 	parser->toksuper = -1; | ||||
| } | ||||
|  | ||||
| @@ -1,67 +0,0 @@ | ||||
| #ifndef __JSMN_H_ | ||||
| #define __JSMN_H_ | ||||
|  | ||||
| /** | ||||
|  * JSON type identifier. Basic types are: | ||||
|  * 	o Object | ||||
|  * 	o Array | ||||
|  * 	o String | ||||
|  * 	o Other primitive: number, boolean (true/false) or null | ||||
|  */ | ||||
| typedef enum { | ||||
| 	JSMN_PRIMITIVE = 0, | ||||
| 	JSMN_OBJECT = 1, | ||||
| 	JSMN_ARRAY = 2, | ||||
| 	JSMN_STRING = 3 | ||||
| } jsmntype_t; | ||||
|  | ||||
| typedef enum { | ||||
| 	/* Not enough tokens were provided */ | ||||
| 	JSMN_ERROR_NOMEM = -1, | ||||
| 	/* Invalid character inside JSON string */ | ||||
| 	JSMN_ERROR_INVAL = -2, | ||||
| 	/* The string is not a full JSON packet, more bytes expected */ | ||||
| 	JSMN_ERROR_PART = -3, | ||||
| 	/* Everything was fine */ | ||||
| 	JSMN_SUCCESS = 0 | ||||
| } jsmnerr_t; | ||||
|  | ||||
| /** | ||||
|  * JSON token description. | ||||
|  * @param		type	type (object, array, string etc.) | ||||
|  * @param		start	start position in JSON data string | ||||
|  * @param		end		end position in JSON data string | ||||
|  */ | ||||
| typedef struct { | ||||
| 	jsmntype_t type; | ||||
| 	int start; | ||||
| 	int end; | ||||
| 	int size; | ||||
| #ifdef JSMN_PARENT_LINKS | ||||
| 	int parent; | ||||
| #endif | ||||
| } jsmntok_t; | ||||
|  | ||||
| /** | ||||
|  * JSON parser. Contains an array of token blocks available. Also stores | ||||
|  * the string being parsed now and current position in that string | ||||
|  */ | ||||
| typedef struct { | ||||
| 	unsigned int pos; /* offset in the JSON string */ | ||||
| 	int toknext; /* next token to allocate */ | ||||
| 	int toksuper; /* superior token node, e.g parent object or array */ | ||||
| } jsmn_parser; | ||||
|  | ||||
| /** | ||||
|  * Create JSON parser over an array of tokens | ||||
|  */ | ||||
| void jsmn_init(jsmn_parser *parser); | ||||
|  | ||||
| /** | ||||
|  * Run JSON parser. It parses a JSON data string into and array of tokens, each describing | ||||
|  * a single JSON object. | ||||
|  */ | ||||
| jsmnerr_t jsmn_parse(jsmn_parser *parser, const char *js,  | ||||
| 		jsmntok_t *tokens, unsigned int num_tokens); | ||||
|  | ||||
| #endif /* __JSMN_H_ */ | ||||
| @@ -1,244 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonParser.h" | ||||
| #include <string> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| namespace ArduinoJsonParserTests | ||||
| { | ||||
| 	TEST_CLASS(GbathreeBug) | ||||
| 	{ | ||||
| 		char json[1024]; | ||||
| 		JsonParser<200> parser; | ||||
| 		JsonHashTable root; | ||||
| 		 | ||||
|  | ||||
| 	public: | ||||
|  | ||||
| 		TEST_METHOD_INITIALIZE(Initialize) | ||||
| 		{ | ||||
| 			// BUG described here: | ||||
| 			// http://forum.arduino.cc/index.php?topic=172578.msg1608219#msg1608219 | ||||
| 			strcpy(json, "{ \"protocol_name\":\"fluorescence\",\"repeats\":1,\"wait\":0,\"averages\":1,\"measurements\":3,\"meas2_light\":15,\"meas1_baseline\":0,\"act_light\":20,\"pulsesize\":25,\"pulsedistance\":10000,\"actintensity1\":50,\"actintensity2\":255,\"measintensity\":255,\"calintensity\":255,\"pulses\":[50,50,50],\"act\":[2,1,2,2],\"red\":[2,2,2,2],\"detectors\":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]],\"alta\":[2,2,2,2],\"altb\":[2,2,2,2],\"measlights\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"measlights2\":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]],\"altc\":[2,2,2,2],\"altd\":[2,2,2,2]}"); | ||||
| 			root = parser.parseHashTable(json); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Root) | ||||
| 		{ | ||||
| 			Assert::IsTrue(root.success()); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(ProtocolName) | ||||
| 		{ | ||||
| 			string protocol_name = root.getString("protocol_name"); | ||||
| 			Assert::AreEqual(string("fluorescence"), protocol_name); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Repeats) | ||||
| 		{ | ||||
| 			Assert::AreEqual(1L, root.getLong("repeats")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Wait) | ||||
| 		{ | ||||
| 			Assert::AreEqual(0L, root.getLong("wait")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Measurements) | ||||
| 		{ | ||||
| 			Assert::AreEqual(3L, root.getLong("measurements")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Meas2_Light) | ||||
| 		{ | ||||
| 			Assert::AreEqual(15L, root.getLong("meas2_light")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Meas1_Baseline) | ||||
| 		{ | ||||
| 			Assert::AreEqual(0L, root.getLong("meas1_baseline")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Act_Light) | ||||
| 		{ | ||||
| 			Assert::AreEqual(20L, root.getLong("act_light")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Pulsesize) | ||||
| 		{ | ||||
| 			Assert::AreEqual(25L, root.getLong("pulsesize")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Pulsedistance) | ||||
| 		{ | ||||
| 			Assert::AreEqual(10000L, root.getLong("pulsedistance")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Actintensity1) | ||||
| 		{ | ||||
| 			Assert::AreEqual(50L, root.getLong("actintensity1")); | ||||
| 		} | ||||
| 				 | ||||
| 		TEST_METHOD(Actintensity2) | ||||
| 		{ | ||||
| 			Assert::AreEqual(255L, root.getLong("actintensity2")); | ||||
| 		} | ||||
| 		 | ||||
| 		TEST_METHOD(Measintensity) | ||||
| 		{ | ||||
| 			Assert::AreEqual(255L, root.getLong("measintensity")); | ||||
| 		} | ||||
| 		 | ||||
| 		TEST_METHOD(Calintensity) | ||||
| 		{ | ||||
| 			Assert::AreEqual(255L, root.getLong("calintensity")); | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Pulses) | ||||
| 		{ | ||||
| 			// "pulses":[50,50,50] | ||||
|  | ||||
| 			JsonArray array = root.getArray("pulses"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
|  | ||||
| 			Assert::AreEqual(3, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 3; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(50L, array.getLong(i)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Act) | ||||
| 		{ | ||||
| 			// "act":[2,1,2,2] | ||||
|  | ||||
| 			JsonArray array = root.getArray("act"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
|  | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
| 			Assert::AreEqual(2L, array.getLong(0)); | ||||
| 			Assert::AreEqual(1L, array.getLong(1)); | ||||
| 			Assert::AreEqual(2L, array.getLong(2)); | ||||
| 			Assert::AreEqual(2L, array.getLong(3));			 | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Detectors) | ||||
| 		{ | ||||
| 			// "detectors":[[34,34,34,34],[34,34,34,34],[34,34,34,34],[34,34,34,34]] | ||||
|  | ||||
| 			JsonArray array = root.getArray("detectors"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 4; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(4, array.getArray(i).getLength()); | ||||
|  | ||||
| 				for (int j = 0; j < 4; j++) | ||||
| 					Assert::AreEqual(34L, array.getArray(i).getLong(j)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Alta) | ||||
| 		{ | ||||
| 			// alta:[2,2,2,2] | ||||
|  | ||||
| 			JsonArray array = root.getArray("alta"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
|  | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 4; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(2L, array.getLong(i)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Altb) | ||||
| 		{ | ||||
| 			// altb:[2,2,2,2] | ||||
|  | ||||
| 			JsonArray array = root.getArray("altb"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
|  | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 4; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(2L, array.getLong(i)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Measlights) | ||||
| 		{ | ||||
| 			// "measlights":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] | ||||
|  | ||||
| 			JsonArray array = root.getArray("measlights"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 4; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(4, array.getArray(i).getLength()); | ||||
|  | ||||
| 				for (int j = 0; j < 4; j++) | ||||
| 					Assert::AreEqual(15L, array.getArray(i).getLong(j)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Measlights2) | ||||
| 		{ | ||||
| 			// "measlights2":[[15,15,15,15],[15,15,15,15],[15,15,15,15],[15,15,15,15]] | ||||
|  | ||||
| 			JsonArray array = root.getArray("measlights2"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 4; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(4, array.getArray(i).getLength()); | ||||
|  | ||||
| 				for (int j = 0; j < 4; j++) | ||||
| 					Assert::AreEqual(15L, array.getArray(i).getLong(j)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Altc) | ||||
| 		{ | ||||
| 			// altc:[2,2,2,2] | ||||
|  | ||||
| 			JsonArray array = root.getArray("altc"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
|  | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 4; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(2L, array.getLong(i)); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		TEST_METHOD(Altd) | ||||
| 		{ | ||||
| 			// altd:[2,2,2,2] | ||||
|  | ||||
| 			JsonArray array = root.getArray("altd"); | ||||
| 			Assert::IsTrue(array.success()); | ||||
|  | ||||
| 			Assert::AreEqual(4, array.getLength()); | ||||
|  | ||||
| 			for (int i = 0; i < 4; i++) | ||||
| 			{ | ||||
| 				Assert::AreEqual(2L, array.getLong(i)); | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| } | ||||
| @@ -1,67 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonParser.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| namespace JsonParserTests | ||||
| { | ||||
|     TEST_CLASS(JsonArrayIteratorTests) | ||||
|     { | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(EmptyJson) | ||||
|         { | ||||
|             char json[] = ""; | ||||
|             JsonParser<1> parser; | ||||
|  | ||||
|             JsonArray a = parser.parse(json); | ||||
|  | ||||
|             int loopCount = 0; | ||||
|  | ||||
|             for (long i : a) | ||||
|             { | ||||
|                 loopCount++; | ||||
|             } | ||||
|  | ||||
|             Assert::AreEqual(0, loopCount); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ThreeIntegers) | ||||
|         { | ||||
|             char json [] = "[1,2,3]"; | ||||
|             long expected [] = {1, 2, 3}; | ||||
|             JsonParser<4> parser; | ||||
|  | ||||
|             JsonArray a = parser.parse(json); | ||||
|  | ||||
|             int index = 0; | ||||
|  | ||||
|             for (long i : a) | ||||
|             { | ||||
|                 Assert::AreEqual(expected[index++], i); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ThreeStrings) | ||||
|         { | ||||
|             char json[] = "[\"1\",\"2\",\"3\"]"; | ||||
|             char* expected[] = {"1", "2", "3"}; | ||||
|             JsonParser<4> parser; | ||||
|  | ||||
|             JsonArray a = parser.parse(json); | ||||
|  | ||||
|             int index = 0; | ||||
|  | ||||
|             for (const char* i : a) | ||||
|             { | ||||
|                 Assert::AreEqual(expected[index++], i); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,189 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonParser.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| namespace ArduinoJsonParserTests | ||||
| { | ||||
|     TEST_CLASS(JsonArrayTests) | ||||
|     { | ||||
|         JsonArray array; | ||||
|         char json[256]; | ||||
|         jsmntok_t tokens[32]; | ||||
|         JsonParserBase parser = JsonParserBase(tokens, 32); | ||||
|  | ||||
|     public: | ||||
|          | ||||
|         TEST_METHOD(TooFewClosingBrackets) | ||||
|         { | ||||
|             whenInputIs("[[]"); | ||||
|             parseMustFail(); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TooManyClosingBrackets) | ||||
|         { | ||||
|             whenInputIs("[]]"); | ||||
|             parseMustFail(); | ||||
|         } | ||||
|          | ||||
|         TEST_METHOD(EmptyArray) | ||||
|         { | ||||
|             whenInputIs("[]"); | ||||
|             parseMustSucceed(); | ||||
|             lengthMustBe(0); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(NotEnoughTokens) | ||||
|         { | ||||
|             setTokenCountTo(2); | ||||
|  | ||||
|             whenInputIs("[1,2]"); | ||||
|  | ||||
|             parseMustFail(); | ||||
|             itemMustNotExist(0); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoIntegers) | ||||
|         { | ||||
|             setTokenCountTo(3); | ||||
|  | ||||
|             whenInputIs("[1,2]"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             lengthMustBe(2); | ||||
|             itemMustBe(0, 1L); | ||||
|             itemMustBe(1, 2L); | ||||
|             itemMustNotExist(2); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoBooleans) | ||||
|         { | ||||
|             setTokenCountTo(3); | ||||
|  | ||||
|             whenInputIs("[true,false]"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             lengthMustBe(2); | ||||
|             itemMustBe(0, true); | ||||
|             itemMustBe(1, false); | ||||
|             itemMustNotExist(2); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoStrings) | ||||
|         { | ||||
|             setTokenCountTo(3); | ||||
|  | ||||
|             whenInputIs("[\"hello\",\"world\"]"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             lengthMustBe(2); | ||||
|             itemMustBe(0, "hello"); | ||||
|             itemMustBe(1, "world"); | ||||
|             itemMustNotExist(2); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoDimensionsArray) | ||||
|         { | ||||
|             setTokenCountTo(7); | ||||
|  | ||||
|             whenInputIs("[[1,2],[3,4]]"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             lengthMustBe(2); | ||||
|             itemMustBe(0, 0, 1L); | ||||
|             itemMustBe(0, 1, 2L); | ||||
|             itemMustBe(1, 0, 3L); | ||||
|             itemMustBe(1, 1, 4L); | ||||
|             itemMustNotExist(2); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ThreeDimensionsArray) | ||||
|         { | ||||
|             setTokenCountTo(15); | ||||
|  | ||||
|             whenInputIs("[[[1,2],[3,4]],[[5,6],[7,8]]]"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             lengthMustBe(2); | ||||
|             itemMustBe(0, 0, 0, 1L); | ||||
|             itemMustBe(0, 0, 1, 2L); | ||||
|             itemMustBe(0, 1, 0, 3L); | ||||
|             itemMustBe(0, 1, 1, 4L); | ||||
|             itemMustBe(1, 0, 0, 5L); | ||||
|             itemMustBe(1, 0, 1, 6L); | ||||
|             itemMustBe(1, 1, 0, 7L); | ||||
|             itemMustBe(1, 1, 1, 8L); | ||||
|             itemMustNotExist(2); | ||||
|         }         | ||||
|          | ||||
|     private: | ||||
|  | ||||
|         void setTokenCountTo(int n) | ||||
|         { | ||||
|             parser = JsonParserBase(tokens, n); | ||||
|         } | ||||
|  | ||||
|         void whenInputIs(const char* input) | ||||
|         { | ||||
|             strcpy(json, input); | ||||
|             array = parser.parseArray(json); | ||||
|         } | ||||
|  | ||||
|         void parseMustFail() | ||||
|         { | ||||
|             Assert::IsFalse(array.success()); | ||||
|             lengthMustBe(0); | ||||
|         } | ||||
|  | ||||
|         void parseMustSucceed() | ||||
|         { | ||||
|             Assert::IsTrue(array.success()); | ||||
|         } | ||||
|  | ||||
|         void lengthMustBe(int expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, array.getLength()); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(int index, long expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, array.getLong(index)); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(int index, bool expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, array.getBool(index)); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(int index, const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, array.getString(index)); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(int index0, int index1, long expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, array.getArray(index0).getLong(index1)); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(int index0, int index1, int index2, long expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, array.getArray(index0).getArray(index1).getLong(index2)); | ||||
|         } | ||||
|  | ||||
|         void itemMustNotExist(int index) | ||||
|         { | ||||
|             Assert::IsFalse(array.getHashTable(index).success()); | ||||
|             Assert::IsFalse(array.getArray(index).success()); | ||||
|             Assert::IsFalse(array.getBool(index)); | ||||
|             Assert::AreEqual(0.0, array.getDouble(index)); | ||||
|             Assert::AreEqual(0L, array.getLong(index)); | ||||
|             Assert::IsNull(array.getString(index)); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,71 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonParser.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| namespace JsonParserTests | ||||
| { | ||||
|     TEST_CLASS(JsonObjectIteratorTests) | ||||
|     { | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(EmptyObject) | ||||
|         { | ||||
|             char json [] = "{}"; | ||||
|             JsonParser<1> parser; | ||||
|  | ||||
|             JsonHashTable a = parser.parse(json); | ||||
|  | ||||
|             int loopCount = 0; | ||||
|  | ||||
|             for (auto i : a) | ||||
|             { | ||||
|                 loopCount++; | ||||
|             } | ||||
|  | ||||
|             Assert::AreEqual(0, loopCount); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EmptyJson) | ||||
|         { | ||||
|             char json[] = ""; | ||||
|             JsonParser<1> parser; | ||||
|  | ||||
|             JsonHashTable a = parser.parse(json); | ||||
|  | ||||
|             int loopCount = 0; | ||||
|  | ||||
|             for (auto i : a) | ||||
|             { | ||||
|                 loopCount++; | ||||
|             } | ||||
|  | ||||
|             Assert::AreEqual(0, loopCount); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(ThreeStrings) | ||||
|         { | ||||
|             char json[] = "{\"key1\":\"value1\",\"key2\":\"value2\",\"key3\":\"value3\"}"; | ||||
|             char* expectedKeys[] = {"key1", "key2", "key3"}; | ||||
|             char* expectedValues[] = {"value1", "value2", "value3"}; | ||||
|             JsonParser<7> parser; | ||||
|  | ||||
|             JsonHashTable a = parser.parse(json); | ||||
|  | ||||
|             int index = 0; | ||||
|  | ||||
|             for (auto i : a) | ||||
|             { | ||||
|                 Assert::AreEqual(expectedKeys[index], i.key()); | ||||
|                 Assert::AreEqual(expectedValues[index], (const char*) i.value()); | ||||
|                 index++; | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,165 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonParser.h" | ||||
| #include <string> | ||||
|  | ||||
| using namespace std; | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| namespace ArduinoJsonParserTests | ||||
| { | ||||
|     TEST_CLASS(JsonHashTableTests) | ||||
|     { | ||||
|         JsonHashTable hashTable; | ||||
|         JsonArray nestedArray; | ||||
|         char json[256]; | ||||
|         jsmntok_t tokens[32]; | ||||
|         JsonParserBase parser = JsonParserBase(tokens, 32); | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(EmptyHashTable) | ||||
|         { | ||||
|             whenInputIs("{}"); | ||||
|             parseMustSucceed(); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(NotEnoughTokens) | ||||
|         { | ||||
|             setTokenCountTo(2); | ||||
|  | ||||
|             whenInputIs("{\"key\":0}"); | ||||
|  | ||||
|             parseMustFail(); | ||||
|             itemMustNotExist("key"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoIntegers) | ||||
|         { | ||||
|             setTokenCountTo(5); | ||||
|  | ||||
|             whenInputIs("{\"key1\":1,\"key2\":2}"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             itemMustBe("key1", 1L); | ||||
|             itemMustBe("key2", 2L); | ||||
|             itemMustNotExist("key3"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoBooleans) | ||||
|         { | ||||
|             setTokenCountTo(5); | ||||
|  | ||||
|             whenInputIs("{\"key1\":true,\"key2\":false}"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             itemMustBe("key1", true); | ||||
|             itemMustBe("key2", false); | ||||
|             itemMustNotExist("key3"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoStrings) | ||||
|         { | ||||
|             setTokenCountTo(5); | ||||
|  | ||||
|             whenInputIs("{\"key1\":\"hello\",\"key2\":\"world\"}"); | ||||
|  | ||||
|             parseMustSucceed(); | ||||
|             itemMustBe("key1", "hello"); | ||||
|             itemMustBe("key2", "world"); | ||||
|             itemMustNotExist("key3"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(TwoNestedArrays) | ||||
|         { | ||||
|             setTokenCountTo(9); | ||||
|  | ||||
|             whenInputIs("{\"key1\":[1,2],\"key2\":[3,4]}"); | ||||
|             parseMustSucceed(); | ||||
|  | ||||
|             itemMustBeAnArray("key1"); | ||||
|             arrayLengthMustBe(2); | ||||
|             arrayItemMustBe(0, 1L); | ||||
|             arrayItemMustBe(1, 2L); | ||||
|             arrayItemMustBe(2, 0L); | ||||
|  | ||||
|             itemMustBeAnArray("key2"); | ||||
|             arrayLengthMustBe(2); | ||||
|             arrayItemMustBe(0, 3L); | ||||
|             arrayItemMustBe(1, 4L); | ||||
|             arrayItemMustBe(2, 0L); | ||||
|  | ||||
|             itemMustNotExist("key3"); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|  | ||||
|         void setTokenCountTo(int n) | ||||
|         { | ||||
|             parser = JsonParserBase(tokens, n); | ||||
|         } | ||||
|  | ||||
|         void whenInputIs(const char* input) | ||||
|         { | ||||
|             strcpy(json, input); | ||||
|             hashTable = parser.parseHashTable(json); | ||||
|         } | ||||
|  | ||||
|         void parseMustFail() | ||||
|         { | ||||
|             Assert::IsFalse(hashTable.success()); | ||||
|         } | ||||
|  | ||||
|         void parseMustSucceed() | ||||
|         { | ||||
|             Assert::IsTrue(hashTable.success()); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(const char* key, long expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, hashTable.getLong(key)); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(const char* key, bool expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, hashTable.getBool(key)); | ||||
|         } | ||||
|  | ||||
|         void itemMustBe(const char* key, const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, hashTable.getString(key)); | ||||
|         } | ||||
|  | ||||
|         void itemMustNotExist(const char* key) | ||||
|         { | ||||
|             Assert::IsFalse(hashTable.containsKey(key)); | ||||
|             Assert::IsFalse(hashTable.getHashTable(key).success()); | ||||
|             Assert::IsFalse(hashTable.getArray(key).success()); | ||||
|             Assert::IsFalse(hashTable.getBool(key)); | ||||
|             Assert::AreEqual(0.0, hashTable.getDouble(key)); | ||||
|             Assert::AreEqual(0L, hashTable.getLong(key)); | ||||
|             Assert::IsNull(hashTable.getString(key)); | ||||
|         } | ||||
|  | ||||
|         void itemMustBeAnArray(const char* key) | ||||
|         { | ||||
|             nestedArray = hashTable.getArray(key); | ||||
|             Assert::IsTrue(nestedArray.success()); | ||||
|         } | ||||
|  | ||||
|         void arrayLengthMustBe(int expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, nestedArray.getLength()); | ||||
|         } | ||||
|  | ||||
|         void arrayItemMustBe(int index, long expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, nestedArray.getLong(index)); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,103 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup Label="ProjectConfigurations"> | ||||
|     <ProjectConfiguration Include="Debug|Win32"> | ||||
|       <Configuration>Debug</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|     <ProjectConfiguration Include="Release|Win32"> | ||||
|       <Configuration>Release</Configuration> | ||||
|       <Platform>Win32</Platform> | ||||
|     </ProjectConfiguration> | ||||
|   </ItemGroup> | ||||
|   <PropertyGroup Label="Globals"> | ||||
|     <ProjectGuid>{4DD596EF-0185-4AB4-A3C2-F20C496F7806}</ProjectGuid> | ||||
|     <Keyword>Win32Proj</Keyword> | ||||
|     <RootNamespace>ArduinoJsonParserTests</RootNamespace> | ||||
|     <ProjectName>JsonParserTests</ProjectName> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>true</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|     <UseOfMfc>false</UseOfMfc> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>false</UseDebugLibraries> | ||||
|     <PlatformToolset>v120</PlatformToolset> | ||||
|     <WholeProgramOptimization>true</WholeProgramOptimization> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|     <UseOfMfc>false</UseOfMfc> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | ||||
|   <ImportGroup Label="ExtensionSettings"> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | ||||
|   </ImportGroup> | ||||
|   <PropertyGroup Label="UserMacros" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <LinkIncremental>true</LinkIncremental> | ||||
|     <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);..</IncludePath> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <LinkIncremental>true</LinkIncremental> | ||||
|     <IncludePath>$(VC_IncludePath);..</IncludePath> | ||||
|   </PropertyGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <ClCompile> | ||||
|       <PrecompiledHeader>NotUsing</PrecompiledHeader> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <Optimization>Disabled</Optimization> | ||||
|       <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <PreprocessorDefinitions>ARDUINO_JSON_NO_DEPRECATION_WARNING;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|       <UseFullPaths>true</UseFullPaths> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <ClCompile> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <PrecompiledHeader>Use</PrecompiledHeader> | ||||
|       <Optimization>MaxSpeed</Optimization> | ||||
|       <FunctionLevelLinking>true</FunctionLevelLinking> | ||||
|       <IntrinsicFunctions>true</IntrinsicFunctions> | ||||
|       <AdditionalIncludeDirectories>$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | ||||
|       <PreprocessorDefinitions>WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|       <UseFullPaths>true</UseFullPaths> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Windows</SubSystem> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||
|       <OptimizeReferences>true</OptimizeReferences> | ||||
|       <AdditionalLibraryDirectories>$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="JsonObjectIteratorTests.cpp" /> | ||||
|     <ClCompile Include="JsonArrayTests.cpp" /> | ||||
|     <ClCompile Include="JsonArrayIteratorTests.cpp" /> | ||||
|     <ClCompile Include="JsonObjectTests.cpp" /> | ||||
|     <ClCompile Include="GbathreeBug.cpp" /> | ||||
|     <ClCompile Include="JsonStringTests.cpp" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ProjectReference Include="..\JsonParser\JsonParser.vcxproj"> | ||||
|       <Project>{c15274de-2695-4dfe-8520-4424223fe6da}</Project> | ||||
|     </ProjectReference> | ||||
|   </ItemGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
|   <ImportGroup Label="ExtensionTargets"> | ||||
|   </ImportGroup> | ||||
| </Project> | ||||
| @@ -1,37 +0,0 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <ItemGroup> | ||||
|     <Filter Include="Source Files"> | ||||
|       <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> | ||||
|       <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Header Files"> | ||||
|       <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> | ||||
|       <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> | ||||
|     </Filter> | ||||
|     <Filter Include="Resource Files"> | ||||
|       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> | ||||
|       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> | ||||
|     </Filter> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="GbathreeBug.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonObjectTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonArrayIteratorTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonObjectIteratorTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonArrayTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="JsonStringTests.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
| @@ -1,107 +0,0 @@ | ||||
| /* | ||||
| * Arduino JSON library | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
|  | ||||
| #include "CppUnitTest.h" | ||||
| #include "JsonParser.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
| using namespace ArduinoJson::Parser; | ||||
|  | ||||
| namespace ArduinoJsonParserTests | ||||
| { | ||||
|     TEST_CLASS(JsonStringTests) | ||||
|     { | ||||
|         const char* actual; | ||||
|         char json[256]; | ||||
|         JsonParser<32> parser; | ||||
|  | ||||
|     public: | ||||
|  | ||||
|         TEST_METHOD(EmptyString) | ||||
|         { | ||||
|             whenInputIs(""); | ||||
|             outputMustBe(0); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(JustOneQuote) | ||||
|         { | ||||
|             whenInputIs("\""); | ||||
|             outputMustBe(0); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(SimpleString) | ||||
|         { | ||||
|             whenInputIs("\"Hi!\""); | ||||
|             outputMustBe("Hi!"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EscapedQuote) | ||||
|         { | ||||
|             whenInputIs("\"12\\\"34\"");  // ie 12\"34 | ||||
|             outputMustBe("12\"34"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EscapedReverseSolidus) | ||||
|         { | ||||
|             whenInputIs("\"12\\\\34\""); // ie 12\\34 | ||||
|             outputMustBe("12\\34"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EscapedSolidus) | ||||
|         { | ||||
|             whenInputIs("\"12\\/34\""); | ||||
|             outputMustBe("12/34"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EscapedBackspace) | ||||
|         { | ||||
|             whenInputIs("\"12\\b34\""); | ||||
|             outputMustBe("12\b34"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EscapedFormfeed) | ||||
|         { | ||||
|             whenInputIs("\"12\\f34\""); | ||||
|             outputMustBe("12\f34"); | ||||
|         } | ||||
|          | ||||
|         TEST_METHOD(EscapedNewline) | ||||
|         { | ||||
|             whenInputIs("\"12\\n34\"");  | ||||
|             outputMustBe("12\n34"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EscapedCarriageReturn) | ||||
|         { | ||||
|             whenInputIs("\"12\\r34\""); | ||||
|             outputMustBe("12\r34"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(EscapedTab) | ||||
|         { | ||||
|             whenInputIs("\"12\\t34\""); | ||||
|             outputMustBe("12\t34"); | ||||
|         } | ||||
|  | ||||
|         TEST_METHOD(AllEscapedCharsTogether) | ||||
|         { | ||||
|             whenInputIs("\"1\\\"2\\\\3\\/4\\b5\\f6\\n7\\r8\\t9\""); | ||||
|             outputMustBe("1\"2\\3/4\b5\f6\n7\r8\t9"); | ||||
|         } | ||||
|  | ||||
|     private:        | ||||
|  | ||||
|         void whenInputIs(const char* input) | ||||
|         { | ||||
|             strcpy(json, input); | ||||
|             actual = parser.parse(json); | ||||
|         } | ||||
|  | ||||
|         void outputMustBe(const char* expected) | ||||
|         { | ||||
|             Assert::AreEqual(expected, actual); | ||||
|         } | ||||
|     }; | ||||
| } | ||||
| @@ -1,25 +0,0 @@ | ||||
| #include "stdafx.h" | ||||
| #include "CppUnitTest.h" | ||||
|  | ||||
| using namespace Microsoft::VisualStudio::CppUnitTestFramework; | ||||
|  | ||||
| namespace ArduinoJsonParserTests | ||||
| { | ||||
| 	TEST_CLASS(TestHashGenerator) | ||||
| 	{ | ||||
| 	public: | ||||
| 		 | ||||
| 		TEST_METHOD(TestMethod1) | ||||
| 		{ | ||||
|             JsonArray<5> arr; | ||||
|             arr.Add(1); | ||||
|             arr.Add("Hi!"); | ||||
|  | ||||
|             JsonHashTable<4> hash; | ||||
|             hash.Add("key1", 1); | ||||
|             hash.Add("key2", "Hello!"); | ||||
|             hash.Add("key3", arr); | ||||
| 		} | ||||
|  | ||||
| 	}; | ||||
| } | ||||
							
								
								
									
										57
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,6 +1,8 @@ | ||||
| Arduino JSON library | ||||
| ==================== | ||||
|  | ||||
| [](https://travis-ci.org/bblanchon/ArduinoJson) | ||||
|  | ||||
| *An elegant and efficient JSON library for embedded systems.* | ||||
|  | ||||
| It's design to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc). | ||||
| @@ -10,31 +12,48 @@ It has been written with Arduino in mind, but it isn't linked to Arduino librari | ||||
| Features | ||||
| -------- | ||||
|  | ||||
| * JSON decoding: [see documentation here](/JsonParser/) | ||||
| * JSON encoding: [see documentation here](/JsonGenerator/) | ||||
| * JSON decoding | ||||
| * JSON encoding (with optional indentation) | ||||
| * Elegant API, very easy to use  | ||||
| * Fixed memory allocation (no malloc) | ||||
| * Small footprint | ||||
| * MIT License | ||||
|  | ||||
| Feature comparison | ||||
| ------------------ | ||||
| Quick start | ||||
| ----------- | ||||
|  | ||||
| | Library      | Memory allocation | Nested objects | Parser size | Encoder size  | | ||||
| | ------------ | ----------------- | -------------- | ----------- | ------------- | | ||||
| | Arduino JSON | static            | yes            | 2760 Bytes  | 862 bytes     | | ||||
| | json-arduino | dynamic           | no             | 3348 (+21%) | not supported | | ||||
| | aJson        | dynamic           | yes            | 5088 (+84%) | 4678 (+540%)  | | ||||
| #### Decoding / Parsing | ||||
|     | ||||
|     char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|  | ||||
| "Parser size" was measured with a program parsing `{"sensor":"outdoor","value":25.6}`. | ||||
| For each library, I wrote a program that extracts a string and a float. I subtracted the size of a program doing the same without any JSON parsing involved. [Source files are here](https://gist.github.com/bblanchon/e8ba914a7109f3642c0f). | ||||
|     StaticJsonBuffer<200> jsonBuffer; | ||||
|  | ||||
| "Encoder size" was measured with a program generating `{"sensor":"outdoor","value":25.6}`. | ||||
| [Source files are here](https://gist.github.com/bblanchon/60224e9dcfeab4ddc7e9). | ||||
|     JsonObject& root = jsonBuffer.parseObject(json); | ||||
|  | ||||
| In each case the target platform was an Arduino Duemilanove and Arduino IDE 1.0.5 was used.  | ||||
|     const char* sensor = root["sensor"]; | ||||
|     long time          = root["time"]; | ||||
|     double latitude    = root["data"][0]; | ||||
|     double longitude   = root["data"][1]; | ||||
|  | ||||
| Links: [json-arduino](https://github.com/not404/json-arduino), [aJson](https://github.com/interactive-matter/aJson)  | ||||
| [See complete guide](/doc/Decoding JSON.md) | ||||
|  | ||||
| #### Encoding / Generating | ||||
|     | ||||
|     StaticJsonBuffer<200> jsonBuffer; | ||||
|  | ||||
|     JsonObject& root = jsonBuffer.createObject(); | ||||
|     root["sensor"] = "gps"; | ||||
|     root["time"] = 1351824120; | ||||
|  | ||||
|     JsonArray& data = root.createNestedArray("data"); | ||||
|     data.add(48.756080, 6);  // 6 is the number of decimals to print | ||||
|     data.add(2.302038, 6);   // if not specified, 2 digits are printed | ||||
|  | ||||
|     root.printTo(Serial); | ||||
|     // This prints: | ||||
|     // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||
|  | ||||
| [See complete guide](/doc/Encoding JSON.md) | ||||
|  | ||||
| Testimonials | ||||
| ------------ | ||||
| @@ -55,10 +74,6 @@ From GitHub user `zacsketches`: | ||||
| > I've been watching you consistently develop this library over the past six months, and I used it today for a publish and subscribe architecture designed to help hobbyists move into more advanced robotics. Your library allowed me to implement remote subscription in order to facilitate multi-processor robots. | ||||
| > ArduinoJson saved me a week's worth of time!! | ||||
|  | ||||
| Related blog posts | ||||
| ----- | ||||
| --- | ||||
|  | ||||
| * [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/) | ||||
| Found this library useful? [Help me back with a donation!](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=donate%40benoitblanchon%2efr&lc=GB&item_name=Benoit%20Blanchon&item_number=Arduino%20JSON¤cy_code=EUR&bn=PP%2dDonationsBF%3abtn_donate_LG%2egif%3aNonHosted) :smile: | ||||
							
								
								
									
										102
									
								
								doc/Avoiding pitfalls.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								doc/Avoiding pitfalls.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| Avoiding common pitfalls in Arduino JSON | ||||
| ======================================== | ||||
|  | ||||
| As `StaticJsonBuffer` is the corner stone of this library, you'll see that every pitfall listed here are related to a wrong understanding of the memory model. | ||||
|  | ||||
| Make sure you read [Arduino JSON memory model](Memory model.md) before going further. | ||||
|  | ||||
| ## 1. Make `StaticJsonBuffer` big enough | ||||
|  | ||||
| By design, the library has no way to tell you why `parseArray()` or `parseObject()` failed. | ||||
|  | ||||
| There are basically two reasons why they may fail: | ||||
|  | ||||
| 1. the JSON string is invalid, | ||||
| 2. the JSON string contains more values that the buffer can store. | ||||
|  | ||||
| So, if you are sure the JSON string is correct and you still can't parse it, you should try to increase the size of the `StaticJsonBuffer`. | ||||
|  | ||||
| ## 2. Make sure everything fits in memory | ||||
|  | ||||
| You may go into unpredictable trouble if you allocate more memory than your processor really has. | ||||
| It's a very common issue in embedded development. | ||||
|  | ||||
| To diagnose this, look at every big objects in you code and sum their size to check that they fit in RAM. | ||||
|  | ||||
| For example, don't do this: | ||||
|  | ||||
|     char json[1024];                // 1 KB | ||||
|     StaticJsonBuffer<512> buffer;   // 514 B | ||||
|  | ||||
| because it may be too big for a processor with only 2 KB: you need free memory to store other variables and the call stack. | ||||
|  | ||||
| That is why an 8-bit processor is not able to parse long and complex JSON strings. | ||||
|  | ||||
| ## 3. Keep the `StaticJsonBuffer` in memory long enough | ||||
|  | ||||
| Remember that `StaticJsonBuffer`'s function return references. | ||||
| References don't contain data, they are just pointer to the actual. | ||||
| So they can only work if the actual data is in memory. | ||||
|  | ||||
| For example, don't do this: | ||||
|  | ||||
|     JsonArray& getArray(char* json) | ||||
|     { | ||||
|         StaticJsonBuffer<200> buffer; | ||||
|         return buffer.parseArray(json);  | ||||
|     } | ||||
|  | ||||
| because the local variable `buffer` will be *removed* from memory when the function `parseArray()` returns, and the `JsonArray&` will point to an invalid location. | ||||
|  | ||||
| ## 4. Don't reuse the same `StaticJsonBuffer` | ||||
|  | ||||
| During is lifetime a `StaticJsonBuffer` growth until it's discarded. If you try to reuse the same instance several time, it will rapidly get full. | ||||
|  | ||||
| For this reason, you should not use a global variable for your `StaticJsonBuffer`. I don't think there is any scenario in which a global `StaticJsonBuffer` would be a valid option. | ||||
|  | ||||
| The best practice is to declare it in a local scope, so that it's discarded as soon as possible. My advice it to declare it in a function which unique role is to handle the JSON serialization. | ||||
|  | ||||
| ## 5. Keep the JSON string in memory long enough | ||||
|  | ||||
| The library never make memory duplication. | ||||
| This has an important implication on string values, it means that the library will return pointer to chunks of the string. | ||||
|  | ||||
| For instance, let's imagine that you parse `["hello","world"]`, like this: | ||||
|  | ||||
|     char[] json = "[\"hello\",\"world\"]"; | ||||
|     StaticJsonBuffer<32> buffer; | ||||
|     JsonArray& array = buffer.parseArray(json); | ||||
|  | ||||
|     const char* first = array[0]; | ||||
|     const char* second = array[1]; | ||||
|  | ||||
| In that case, both `first` and `second` are pointers to the content of the original string `json`. | ||||
| So this will only work if `json` is still in memory. | ||||
|  | ||||
| ## 6. JSON string is altered | ||||
|  | ||||
| If you read carefully the previous section, you may have come to the conclusion that the JSON parser modifies the JSON string. | ||||
|  | ||||
| Indeed, the parser modifies the string for two reasons: | ||||
|  | ||||
| 1. it inserts `\0` to terminate substrings, | ||||
| 2. it translate escaped characters like `\n` or `\t`. | ||||
|  | ||||
| Most of the time this wont be an issue, but there are some corner cases that can be problematic. | ||||
|  | ||||
| Let take the example bellow: | ||||
|  | ||||
|     char[] json = "[\"hello\",\"world\"]"; | ||||
|     StaticJsonBuffer<32> buffer; | ||||
|     JsonArray& array = buffer.parseArray(json); | ||||
|  | ||||
| If you replace it by: | ||||
|  | ||||
|     char* json = "[\"hello\",\"world\"]"; | ||||
|     StaticJsonBuffer<32> buffer; | ||||
|     JsonArray& array = buffer.parseArray(json); | ||||
|  | ||||
| Depending on your platform, you may have an exception because the parser tries to write at a location that is read-only. | ||||
| In the first case `char json[]` declares an array of `char` initialized to the specified string. | ||||
| In the second case `char* json` declares a pointer to a read-only string, in fact it should be a `const char*` instead of a `char*`. | ||||
|  | ||||
							
								
								
									
										15
									
								
								doc/Contributing.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								doc/Contributing.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| Contributing to Arduino JSON | ||||
| ============================ | ||||
|  | ||||
| If you want to contribute to the project, please: | ||||
|  | ||||
| 1. Use GitHub pull request feature | ||||
| 2. Follow the coding conventions | ||||
| 3. Write tests | ||||
|  | ||||
| About the coding conventions: I try to follow the [Google C++ Style Guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html) with few variations to match the Arduino conventions. | ||||
|  | ||||
| I use [ClangFormat](http://clang.llvm.org/docs/ClangFormat.html) to format the code for me. | ||||
| I use [CppLint](http://google-styleguide.googlecode.com/svn/trunk/cpplint/cpplint.py) to detect non-compliant stuff. | ||||
|  | ||||
| You should have a look at the `scripts/` folder as it contains a few helpers scripts. | ||||
							
								
								
									
										148
									
								
								doc/Decoding JSON.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								doc/Decoding JSON.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| Decoding JSON with Arduino JSON | ||||
| =============================== | ||||
|  | ||||
| Before writing any code, don't forget to include the header: | ||||
|  | ||||
|     #include <ArduinoJson.h> | ||||
|  | ||||
| For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md). | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| Here an example that parse the string `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`: | ||||
|  | ||||
|     char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|      | ||||
|     // | ||||
|     // Step 1: Reserve memory space | ||||
|     // | ||||
|     StaticJsonBuffer<200> jsonBuffer; | ||||
|      | ||||
|     // | ||||
|     // Step 2: Deserialize the JSON string | ||||
|     // | ||||
|     JsonObject& root = jsonBuffer.parseObject(json); | ||||
|  | ||||
|     if (!root.success()) | ||||
|     { | ||||
|       Serial.println("parseObject() failed"); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     // | ||||
|     // Step 3: Retrieve the values | ||||
|     // | ||||
|     const char* sensor    = root["sensor"]; | ||||
|     long        time      = root["time"]; | ||||
|     double      latitude  = root["data"][0]; | ||||
|     double      longitude = root["data"][1]; | ||||
|  | ||||
| ## Step 1: Reserve memory space | ||||
|  | ||||
| Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`. | ||||
|  | ||||
| Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`. | ||||
|  | ||||
| ## Step 2: Parse the JSON string | ||||
|  | ||||
| You invoke the JSON parser through the instance of `StaticJsonBuffer`. | ||||
| It exposes two functions for parsing JSON: | ||||
|  | ||||
| 1. `parseArray()` that returns a reference to a `JsonArray` | ||||
| 2. `parseObject()` that returns a reference to a `JsonObject` | ||||
|  | ||||
| Let's see an example. | ||||
| Say we want to parse `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}`, it's an object so we call `parseObject()` as follows: | ||||
|  | ||||
|     char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|  | ||||
|     JsonObject& root = jsonBuffer.parseObject(json); | ||||
|  | ||||
| As you can see `parseObject()` takes a `char*` as a parameter. | ||||
| Be careful, it's not a `const char*`, the memory must be writable. | ||||
| Indeed, the parser will modify the string in two cases: | ||||
|  | ||||
| 1. to insert string endings (character `\0`), | ||||
| 2. to translate escaped characters (like `\n` or `\t`). | ||||
|  | ||||
| Another thing that you must keep in mind is that the string (`char json[]` in the example above) must stay in memory during the whole parsing process. | ||||
| That is because the in memory object tree will store pointer to chunks of the string, so as to avoid any memory duplication.  | ||||
|  | ||||
| Now, to check if the parsing was successful, you can call `JsonObject::success()`: | ||||
|  | ||||
|     if (!root.success()) | ||||
|     { | ||||
|         // Parsing fail | ||||
|     } | ||||
|  | ||||
| The result can be `false` for tree reasons: | ||||
|  | ||||
| 1. the JSON string is invalid, | ||||
| 2. the JSON string doesn't represent an object, | ||||
| 3. the `StaticJsonBuffer` is too small. | ||||
|  | ||||
| We just saw how to parse an object, there is nothing more to say for arrays, the procedure is exactly the same. | ||||
|  | ||||
| ## Step 3: Retrieve the values | ||||
|  | ||||
| Now that the object or array is in memory, you can extract the data very easily. | ||||
|  | ||||
| In this section, we'll see how to do it with a `JsonObject`. | ||||
| Once again, there is nothing more to say about arrays, `JsonArray` works exactly the same as `JsonObject`. | ||||
|  | ||||
| #### Subscript operator | ||||
|  | ||||
| The simplest way is to use the subscript operator of `JsonObject`: | ||||
|      | ||||
|     const char* sensor = root["sensor"]; | ||||
|     long time = root["time"]; | ||||
|  | ||||
| You can chain the subscript operator if you have nested arrays or objects: | ||||
|  | ||||
|     double latitude  = root["data"][0]; | ||||
|     double longitude = root["data"][1]; | ||||
|  | ||||
| But alternatively, you can get a reference to the nested array: | ||||
|  | ||||
|     JsonArray& nestedArray = root["data"]; | ||||
|  | ||||
| #### Casting values | ||||
|  | ||||
| In the previous examples, the values were implicitly casted to the target type. | ||||
| You can also do this explicitly | ||||
|  | ||||
|     const char* sensor = root["sensor"].asString(); | ||||
|     long time = root["time"].as<long>(); | ||||
|     JsonArray& nestedArray = root["data"].asArray(); | ||||
|  | ||||
| If the actual value doesn't match the target type, a default value will be return: | ||||
|  | ||||
| 1. `false` for boolean values | ||||
| 2. `0` for integer values | ||||
| 3. `NULL` for string values | ||||
| 4. `JsonArray::invalid()` for nested arrays | ||||
| 5. `JsonObject::invalid()` for nested object | ||||
|  | ||||
| #### Check values | ||||
|  | ||||
| If you want to know if some value is present, call `containsKey()`: | ||||
|  | ||||
|     if (root.contains("extra")) | ||||
|     { | ||||
|         // root["extra"] is valid | ||||
|     } | ||||
|  | ||||
| If you want to check the type value has a certain type, call `is<T>()`: | ||||
|  | ||||
|     if (root["extra"].is<JsonArray&>()) | ||||
|     { | ||||
|         // root["extra"] is an array | ||||
|     } | ||||
|  | ||||
| You can also iterate through the key-value pairs of the object: | ||||
|  | ||||
|     for (JsonObject::itertor it=root.begin(); it!=root.end(); ++it) | ||||
|     { | ||||
|       Serial.println(it->key); | ||||
|       Serial.println(i->value.asString()); | ||||
|     } | ||||
							
								
								
									
										140
									
								
								doc/Encoding JSON.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								doc/Encoding JSON.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,140 @@ | ||||
| Encoding JSON with Arduino JSON | ||||
| =============================== | ||||
|  | ||||
| Before writing any code, don't forget to include the header: | ||||
|  | ||||
|     #include <ArduinoJson.h> | ||||
|  | ||||
| For instructions on how to install the library, please read [Using the library with Arduino](Using the library with Arduino.md) or [Using the library without Arduino](Using the library without Arduino.md). | ||||
|  | ||||
| ## Example | ||||
|  | ||||
| Here is an example to generate `{"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}` | ||||
|  | ||||
|     // | ||||
|     // Step 1: Reserve memory space | ||||
|     // | ||||
|     StaticJsonBuffer<200> jsonBuffer; | ||||
|  | ||||
|     // | ||||
|     // Step 2: Build object tree in memory | ||||
|     // | ||||
|     JsonObject& root = jsonBuffer.createObject(); | ||||
|     root["sensor"] = "gps"; | ||||
|     root["time"] = 1351824120; | ||||
|  | ||||
|     JsonArray& data = root.createNestedArray("data"); | ||||
|     data.add(48.756080, 6);  // 6 is the number of decimals to print | ||||
|     data.add(2.302038, 6);   // if not specified, 2 digits are printed | ||||
|  | ||||
|     // | ||||
|     // Step 3: Generate the JSON string | ||||
|     // | ||||
|     root.printTo(Serial); | ||||
|  | ||||
| ## Step 1: Reserve memory space | ||||
|  | ||||
| Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer`. | ||||
|  | ||||
| Before continuing please read the page [Arduino JSON memory model](Memory model.md) that explains everything you need to know about `StaticJsonBuffer`. | ||||
|  | ||||
| ## Step 2: Build object tree in memory | ||||
|  | ||||
| Now that you have enough memory hold by the `StaticJsonBuffer`, you can use it to build your in-memory representation of the JSON string. | ||||
|  | ||||
| #### Arrays | ||||
|  | ||||
| You create an array like this: | ||||
|  | ||||
|     JsonArray& array = jsonBuffer.createArray(); | ||||
|  | ||||
| Don't forget the `&` after `JsonArray`, it needs to be a reference to the array. | ||||
|  | ||||
| Then you can add strings, integer, booleans, etc: | ||||
|  | ||||
|     array.add("bazinga!"); | ||||
|     array.add(42); | ||||
|     array.add(true); | ||||
|  | ||||
| There are two syntaxes for floating point values: | ||||
|  | ||||
| 	array.add(3.1415, 4);  // 4 digits: "3.1415" | ||||
|     array.add(3.1415);	   // 2 digits: "3.14" | ||||
|  | ||||
| > ##### About floating point precision | ||||
| > The overload of `add()` with 2 parameters allows you to specify the number of decimals to save in the JSON string. | ||||
| > When you use the overload with one parameter, you use the default number of decimals which is 2. | ||||
| > Note that this behavior is the exact same as Arduino's `Print::print(double,int);` which is implemented by `Serial`, so you may already be familiar with this behavior. | ||||
|  | ||||
| You can add a nested array or object if you have a reference to it. | ||||
| Or simpler, you can create nested array or nested objects from the array: | ||||
|  | ||||
|     JsonArray&  nestedArray  = array.createNestedArray(); | ||||
|     JsonObject& nestedObject = array.createNestedObject(); | ||||
|  | ||||
| #### Objects | ||||
|  | ||||
| You create an object like this: | ||||
|  | ||||
|     JsonObject& object = jsonBuffer.createObject(); | ||||
|  | ||||
| Again, don't forget the `&` after `JsonObject`, it needs to be a reference to the object. | ||||
|  | ||||
| Then you can add strings, integer, booleans, etc: | ||||
|  | ||||
|     object["key1"] = "bazinga!"; | ||||
|     object["key2"] = 42; | ||||
|     object["key3"] = true; | ||||
|  | ||||
| As for the arrays, there are two syntaxes for the floating point values: | ||||
|  | ||||
| 	object["key4"].set(3.1415, 4);  // 4 digits "3.1415" | ||||
|     object["key5"] = 3.1415;	    // default: 2 digits "3.14" | ||||
|  | ||||
| You can add a nested array or object if you have a reference to it. | ||||
| Or simpler, you can create nested array or nested objects from the object: | ||||
|  | ||||
|     JsonArray&  nestedArray  = object.createNestedArray("key6"); | ||||
|     JsonObject& nestedObject = object.createNestedObject("key7"); | ||||
|  | ||||
| > ##### Other JsonObject functions | ||||
| > * `object.add(key, value)` is a synonym for `object[key] = value` | ||||
| > * `object.containsKey(key)` returns `true` is the `key` is present in `object` | ||||
| > * `object.remove(key)` removes the `value` associated with `key` | ||||
|  | ||||
| ## Step 3: Generate the JSON string | ||||
|  | ||||
| There are two ways tho get the resulting JSON string. | ||||
|  | ||||
| Depending on your project, you may need to dump the string in a classic `char[]` or send it to a `Print` implementation like `Serial` or `EthernetClient `. | ||||
|  | ||||
| Both ways are the easy way :-) | ||||
|  | ||||
| #### Use a classic `char[]` | ||||
|  | ||||
| Whether you have a `JsonArray&` or a `JsonObject&`, simply call `printTo()` with the destination buffer, like so: | ||||
|  | ||||
| 	char buffer[256]; | ||||
|     array.printTo(buffer, sizeof(buffer)); | ||||
|  | ||||
| > ##### Want an indented output? | ||||
| > By default the generated JSON is as small as possible. It contains no extra space, nor line break. | ||||
| > But if you want an indented, more readable output, you can. | ||||
| > Simply call `prettyPrintTo` instead of `printTo()`: | ||||
| >  | ||||
| >     array.prettyPrintTo(buffer, sizeof(buffer)); | ||||
|  | ||||
| #### Send to a `Print` implementation | ||||
|  | ||||
| It's very likely that the generated JSON will end up in a stream like `Serial` or `EthernetClient `, so you can save some time and memory by doing this: | ||||
|  | ||||
|     array.printTo(Serial); | ||||
|  | ||||
| And, of course if you need an indented JSON string: | ||||
|  | ||||
|     array.prettyPrintTo(Serial); | ||||
|  | ||||
| > ##### About the Print interface | ||||
| > The library is designed to send the JSON string to an implementation of the `Print` interface that is part of Arduino. | ||||
| > In the example above we used `Serial`, but they are many other implementations that would work as well, including: `HardwareSerial`,  `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`... | ||||
| > When you use this library out of the Arduino environment, it will use it's own implementation of `Print` and everything will be the same. | ||||
							
								
								
									
										58
									
								
								doc/Memory model.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								doc/Memory model.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| Arduino JSON memory model | ||||
| ========================= | ||||
|  | ||||
| ## Fixed memory allocation | ||||
|  | ||||
| ### Introducing `StaticJsonBuffer` | ||||
|  | ||||
| Arduino JSON uses a preallocated memory pool to store the object tree, this is done by the `StaticJsonBuffer` class. | ||||
|  | ||||
| Before using any function of the library you need to create a `StaticJsonBuffer`. Then you can use this instance to create arrays and objects, or parse a JSON string. | ||||
|  | ||||
| `StaticJsonBuffer` has a template parameter that determines its capacity. For example, the following line create a `StaticJsonBuffer` with a capacity of 200 bytes: | ||||
|  | ||||
|     StaticJsonBuffer<200> jsonBuffer; | ||||
|  | ||||
| The bigger the buffer is, the more complex the object tree can be, but also the more memory you need. | ||||
|  | ||||
| ### How to determine the buffer size? | ||||
|  | ||||
| So the big question you should have in mind right now is *How can I determine the size?*. | ||||
|  | ||||
| There are basically two approaches here: | ||||
|  | ||||
| 1. either you can predict the content of the object tree, | ||||
| 2. or, you know how much memory is available. | ||||
|  | ||||
| In the first case, you know some constraints on the object tree. For instance, let's say that your know in advance (and by that I mean "at compilation time") that you want to generate an object with 3 values, one of them being an array with 2 values, like the following: | ||||
|  | ||||
|     {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||
|  | ||||
| To determine the memory usage of this object tree, you use the two macros `JSON_ARRAY_SIZE(n)` and `JSON_OBJECT_SIZE(n)`, both take the number of elements as an argument. | ||||
| For the example above, it would be: | ||||
|  | ||||
|     const int BUFFER_SIZE = JSON_OBJECT_SIZE(3) + JSON_ARRAY_SIZE(2); | ||||
|     StaticJsonBuffer<BUFFER_SIZE> jsonBuffer; | ||||
|  | ||||
| In the second case, let's say you dynamically generate a JSON object tree of a random complexity so you can't put a limit based on that. But on the other hand, you don't want your program to crash because the object tree doesn't fit in memory. | ||||
| The solution here is to determine how much memory is available, or in other words how much memory you can afford for the JSON object tree. | ||||
|  | ||||
| ### Why choosing fixed allocation? | ||||
|  | ||||
| This fixed allocation approach may seem a bit strange, especially if your a desktop application developer used to dynamic allocation, but it make a lot of sense in an embedded context: | ||||
|  | ||||
| 1. the code is smaller | ||||
| 2. it uses less memory | ||||
| 3. it doesn't create memory fragmentation | ||||
| 4. it predictable | ||||
|  | ||||
| Don't forget that the memory is "freed" as soon as the `StaticJsonBuffer` is out of scope, like any other variable. It only hold the memory for a short amount of time. | ||||
|  | ||||
| ## Memory usage | ||||
|  | ||||
| #### Object size for 8-bit AVR | ||||
|  | ||||
| | Type                    | Size       | | ||||
| |-------------------------|------------| | ||||
| | JsonArray of N element  | 4 + 8 * N  | | ||||
| | JsonObject of N element | 4 + 10 * N | | ||||
							
								
								
									
										80
									
								
								doc/Migrating code to new API.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								doc/Migrating code to new API.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| Migrating code written for Arduino JSON v3 to v4 | ||||
| ================================================ | ||||
|  | ||||
| Arduino JSON v4 was a major rewrite of the library, and the API changed significantly. | ||||
|  | ||||
| ## Includes | ||||
|  | ||||
| Arduino JSON v3 had two include files: | ||||
|  | ||||
|     #include <JsonParser.h> | ||||
|     #include <JsonGenerator.h> | ||||
|  | ||||
| Arduino JSON v4 only has one: | ||||
|  | ||||
| 	#include <ArduinoJson.h> | ||||
|  | ||||
| ## Namespaces | ||||
|  | ||||
| Arduino JSON v3 had two namespaces: | ||||
|  | ||||
| 	using namespace ArduinoJson::Parser; | ||||
| 	using namespace ArduinoJson::Generator; | ||||
|  | ||||
| Arduino JSON v4 doesn't require the `using namespace` statement. | ||||
| It has a namespace but the `using namespace` is done in the header file. | ||||
|  | ||||
| ## StaticJsonBuffer | ||||
|  | ||||
| Arduino JSON v3 had different memory allocation models for the parser: | ||||
|  | ||||
| 	JsonParser<16> parser; // 16 being the capacity in "tokens" | ||||
|  | ||||
| and for the generator: | ||||
|  | ||||
| 	JsonArray<4> array; // 4 being the number of element | ||||
| 	JsonObject<4> object; | ||||
|  | ||||
| Arduino JSON v4 only has one memory allocation model: | ||||
|  | ||||
| 	StaticJsonBuffer<128> buffer; // 128 being the capacity in bytes | ||||
|  | ||||
| ## Return values for the parser | ||||
|  | ||||
| Arduino JSON v3 returned value types: | ||||
|  | ||||
| 	JsonArray array = parser.parseArray(json); | ||||
| 	JsonObject object = parser.parseObject(json); | ||||
|  | ||||
| Arduino JSON v4 returns references types: | ||||
|  | ||||
| 	JsonArray& array = buffer.parseArray(json); | ||||
| 	JsonObject& object = buffer.parseObject(json); | ||||
|  | ||||
| Everything else is compatible | ||||
|  | ||||
| ## Creating arrays and objects | ||||
|  | ||||
| Arduino JSON v3 allowed to create `JsonArray` and `JsonObject` directly: | ||||
|  | ||||
| 	JsonArray<4> array; | ||||
| 	JsonObject<4> object; | ||||
|  | ||||
| Arduino JSON v4 requires that you use a `StaticJsonBuffer` for that: | ||||
|  | ||||
| 	JsonArray& array = buffer.createArray(); | ||||
| 	JsonObject& object = buffer.createObject(); | ||||
|  | ||||
| Note: you don't have to specify the capacity anymore. | ||||
|  | ||||
| ## Printable interface | ||||
|  | ||||
| Arduino JSON v3 used to implement the Printable interface, which allowed statements like: | ||||
|  | ||||
|     Serial.print(array); | ||||
|  | ||||
| But Arduino JSON v4 doesn't, instead you need to write this: | ||||
|  | ||||
| 	array.printTo(Serial); | ||||
|  | ||||
| Note: there was a good reason for removing that feature, and it's reducing the size of `JsonArray` and `JsonObject`. | ||||
							
								
								
									
										30
									
								
								doc/Using the library with Arduino.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								doc/Using the library with Arduino.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | ||||
| Using the library with Arduino | ||||
| ============================== | ||||
|  | ||||
| This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment. | ||||
| If you don't use the Arduino IDE, please read [Using the library without Arduino](Using the library without Arduino.md). | ||||
|  | ||||
| ## Install the library | ||||
|  | ||||
| [Download the zip package](https://github.com/bblanchon/ArduinoJson/releases) and extract it to: | ||||
|  | ||||
|     <your Arduino Sketch folder>/libraries/ArduinoJson | ||||
|  | ||||
| Then restart the Arduino IDE. | ||||
|  | ||||
| ## Run the examples sketches | ||||
|  | ||||
| Click `File` / `Example` / `ArduinoJson`. | ||||
|  | ||||
|  | ||||
|  | ||||
| ## Use the library in your sketches | ||||
|  | ||||
| Just add the following line at the top of your program: | ||||
|  | ||||
|     #include <ArduinoJson.h> | ||||
|  | ||||
| Then follow the instructions: | ||||
|  | ||||
| 1. [Parsing JSON](Parsin JSON.md) | ||||
| 2. [Generating JSON](Generating JSON.md) | ||||
							
								
								
									
										37
									
								
								doc/Using the library without Arduino.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								doc/Using the library without Arduino.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| Using the library without Arduino | ||||
| ================================= | ||||
|  | ||||
| This library is primarily design to be used with the Arduino IDE and therefore has a simplified setup procedure for that environment. | ||||
| If you use the Arduino IDE, please read [Using the library with Arduino](Using the library with Arduino.md). | ||||
|  | ||||
| However, it can be used without Arduino IDE with very little effort. | ||||
|  | ||||
| ## Compiling the library | ||||
|  | ||||
| Step 1: Download source code: | ||||
|  | ||||
|     git clone https://github.com/bblanchon/ArduinoJson.git | ||||
|  | ||||
| Step 2: Generate the `Makefile` for your environment | ||||
|  | ||||
|     cd ArduinoJson | ||||
|     cmake . | ||||
|  | ||||
| Step 3: Build | ||||
|  | ||||
| 	make | ||||
|  | ||||
| ## File paths | ||||
|  | ||||
| Assuming you installed the library into `<arduino-json>`, you need to add: | ||||
|  | ||||
| 1. `<arduino-json>/include` to your include path | ||||
| 2. `<arduino-json>/lib` to your library path | ||||
|  | ||||
|  | ||||
| ---------- | ||||
|  | ||||
| You are now ready to follow the instructions: | ||||
|  | ||||
| 1. [Parsing JSON](Parsin JSON.md) | ||||
| 2. [Generating JSON](Generating JSON.md) | ||||
| @@ -3,41 +3,28 @@ | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
|  | ||||
| #include <JsonGenerator.h> | ||||
| #include <ArduinoJson.h> | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
| 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 setup() { | ||||
|   Serial.begin(9600); | ||||
|  | ||||
|   IndentedPrint serial(Serial); | ||||
|   serial.setTabSize(4); | ||||
|  | ||||
|   serial.println("This is at indentation 0"); | ||||
|   serial.indent(); | ||||
|   serial.println("This is at indentation 1"); | ||||
|   serial.println("This is also at indentation 1"); | ||||
|   serial.indent(); | ||||
|   serial.println("This is at indentation 2"); | ||||
|  | ||||
|   serial.unindent(); | ||||
|   serial.unindent(); | ||||
|   serial.println("This is back at indentation 0"); | ||||
| } | ||||
|  | ||||
| void loop() | ||||
| { | ||||
|  | ||||
| void loop() { | ||||
|   // not used in this example | ||||
| } | ||||
| @@ -1,32 +1,42 @@ | ||||
| /* | ||||
|  * Arduino JSON library - Generator example | ||||
|  * Benoit Blanchon 2014 - MIT License | ||||
|  */ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #include <JsonGenerator.h> | ||||
| #include <ArduinoJson.h> | ||||
|  | ||||
| using namespace ArduinoJson::Generator; | ||||
| void setup() { | ||||
|   Serial.begin(9600); | ||||
|  | ||||
| void setup() | ||||
| { | ||||
|     Serial.begin(9600); | ||||
|   StaticJsonBuffer<200> jsonBuffer; | ||||
|  | ||||
|     JsonArray<2> array; | ||||
|     array.add<6>(48.756080); // 6 is the number of decimals to print | ||||
|     array.add<6>(2.302038);  // if not specified, 2 digits are printed | ||||
|   JsonObject& root = jsonBuffer.createObject(); | ||||
|   root["sensor"] = "gps"; | ||||
|   root["time"] = 1351824120; | ||||
|  | ||||
|     JsonObject<3> root;  | ||||
|     root["sensor"] = "gps"; | ||||
|     root["time"] = 1351824120; | ||||
|     root["data"] = array; | ||||
|   JsonArray& data = root.createNestedArray("data"); | ||||
|   data.add(48.756080, 6);  // 6 is the number of decimals to print | ||||
|   data.add(2.302038, 6);   // if not specified, 2 digits are printed | ||||
|  | ||||
|     Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||
|   root.printTo(Serial); | ||||
|   // This prints: | ||||
|   // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||
|  | ||||
|     Serial.println(); | ||||
|     root.prettyPrintTo(Serial); // same string indented | ||||
|   Serial.println(); | ||||
|  | ||||
|   root.prettyPrintTo(Serial); | ||||
|   // This prints: | ||||
|   // { | ||||
|   //   "sensor": "gps", | ||||
|   //   "time": 1351824120, | ||||
|   //   "data": [ | ||||
|   //     48.756080, | ||||
|   //     2.302038 | ||||
|   //   ] | ||||
|   // } | ||||
| } | ||||
|  | ||||
| void loop() | ||||
| { | ||||
|  | ||||
| void loop() { | ||||
|   // not used in this example | ||||
| } | ||||
| @@ -1,40 +1,37 @@ | ||||
| /* | ||||
| * Arduino JSON library - Parser Example | ||||
| * Benoit Blanchon 2014 - MIT License | ||||
| */ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #include <JsonParser.h> | ||||
| #include <ArduinoJson.h> | ||||
|  | ||||
| using namespace ArduinoJson::Parser; | ||||
| void setup() { | ||||
|   Serial.begin(9600); | ||||
|  | ||||
| void setup() | ||||
| { | ||||
|     Serial.begin(9600); | ||||
|   StaticJsonBuffer<200> jsonBuffer; | ||||
|  | ||||
|     char json [] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|   char json[] = | ||||
|       "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}"; | ||||
|  | ||||
|     JsonParser<16> parser; | ||||
|   JsonObject& root = jsonBuffer.parseObject(json); | ||||
|  | ||||
|     JsonObject root = parser.parse(json); | ||||
|   if (!root.success()) { | ||||
|     Serial.println("parseObject() failed"); | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|     if (!root.success()) | ||||
|     { | ||||
|         Serial.println("JsonParser.parse() failed"); | ||||
|         return; | ||||
|     } | ||||
|   const char* sensor = root["sensor"]; | ||||
|   long time = root["time"]; | ||||
|   double latitude = root["data"][0]; | ||||
|   double longitude = root["data"][1]; | ||||
|  | ||||
|     char*  sensor    = root["sensor"]; | ||||
|     long   time      = root["time"]; | ||||
|     double latitude  = root["data"][0]; | ||||
|     double longitude = root["data"][1]; | ||||
|  | ||||
|     Serial.println(sensor); | ||||
|     Serial.println(time); | ||||
|     Serial.println(latitude, 6); | ||||
|     Serial.println(longitude, 6); | ||||
|   Serial.println(sensor); | ||||
|   Serial.println(time); | ||||
|   Serial.println(latitude, 6); | ||||
|   Serial.println(longitude, 6); | ||||
| } | ||||
|  | ||||
| void loop() | ||||
| { | ||||
|  | ||||
| void loop() { | ||||
|   // not used in this example | ||||
| } | ||||
							
								
								
									
										11
									
								
								include/ArduinoJson.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								include/ArduinoJson.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #include "../include/ArduinoJson/JsonArray.hpp" | ||||
| #include "../include/ArduinoJson/JsonObject.hpp" | ||||
| #include "../include/ArduinoJson/StaticJsonBuffer.hpp" | ||||
|  | ||||
| using namespace ArduinoJson; | ||||
							
								
								
									
										31
									
								
								include/ArduinoJson/Arduino/Print.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								include/ArduinoJson/Arduino/Print.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #ifndef ARDUINO | ||||
|  | ||||
| #include <stddef.h> | ||||
| #include <stdint.h> | ||||
|  | ||||
| // This class reproduces Arduino's Print | ||||
| class Print { | ||||
|  public: | ||||
|   virtual ~Print() {} | ||||
|  | ||||
|   virtual size_t write(uint8_t) = 0; | ||||
|  | ||||
|   size_t print(const char[]); | ||||
|   size_t print(double, int = 2); | ||||
|   size_t print(long); | ||||
|   size_t println(); | ||||
| }; | ||||
|  | ||||
| #else | ||||
|  | ||||
| #include <Print.h> | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										54
									
								
								include/ArduinoJson/Internals/IndentedPrint.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								include/ArduinoJson/Internals/IndentedPrint.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../Arduino/Print.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // Decorator on top of Print to allow indented output. | ||||
| // This class is used by JsonPrintable::prettyPrintTo() but can also be used | ||||
| // for your own purpose, like logging. | ||||
| class IndentedPrint : public Print { | ||||
|  public: | ||||
|   explicit IndentedPrint(Print &p) : sink(&p) { | ||||
|     level = 0; | ||||
|     tabSize = 2; | ||||
|     isNewLine = true; | ||||
|   } | ||||
|  | ||||
|   virtual size_t write(uint8_t); | ||||
|  | ||||
|   // Adds one level of indentation | ||||
|   void indent() { | ||||
|     if (level < MAX_LEVEL) level++; | ||||
|   } | ||||
|  | ||||
|   // Removes one level of indentation | ||||
|   void unindent() { | ||||
|     if (level > 0) level--; | ||||
|   } | ||||
|  | ||||
|   // Set the number of space printed for each level of indentation | ||||
|   void setTabSize(uint8_t n) { | ||||
|     if (n < MAX_TAB_SIZE) tabSize = n & MAX_TAB_SIZE; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   Print *sink; | ||||
|   uint8_t level : 4; | ||||
|   uint8_t tabSize : 3; | ||||
|   bool isNewLine : 1; | ||||
|  | ||||
|   size_t writeTabs(); | ||||
|  | ||||
|   static const int MAX_LEVEL = 15;    // because it's only 4 bits | ||||
|   static const int MAX_TAB_SIZE = 7;  // because it's only 3 bits | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										42
									
								
								include/ArduinoJson/Internals/JsonParser.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								include/ArduinoJson/Internals/JsonParser.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../JsonBuffer.hpp" | ||||
| #include "../JsonVariant.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // Parse JSON string to create JsonArrays and JsonObjects | ||||
| // This internal class is not indended to be used directly. | ||||
| // Instead, use JsonBuffer.parseArray() or .parseObject() | ||||
| class JsonParser { | ||||
|  public: | ||||
|   JsonParser(JsonBuffer *buffer, char *json, uint8_t nestingLimit) | ||||
|       : _buffer(buffer), _ptr(json), _nestingLimit(nestingLimit) {} | ||||
|  | ||||
|   JsonArray &parseArray(); | ||||
|   JsonObject &parseObject(); | ||||
|  | ||||
|  private: | ||||
|   bool skip(char charToSkip); | ||||
|   bool skip(const char *wordToSkip); | ||||
|   void skipSpaces(); | ||||
|  | ||||
|   void parseAnythingTo(JsonVariant &destination); | ||||
|   inline void parseBooleanTo(JsonVariant &destination); | ||||
|   inline void parseNullTo(JsonVariant &destination); | ||||
|   inline void parseNumberTo(JsonVariant &destination); | ||||
|   inline const char *parseString(); | ||||
|  | ||||
|   JsonBuffer *_buffer; | ||||
|   char *_ptr; | ||||
|   uint8_t _nestingLimit; | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										54
									
								
								include/ArduinoJson/Internals/JsonPrintable.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								include/ArduinoJson/Internals/JsonPrintable.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "IndentedPrint.hpp" | ||||
| #include "JsonWriter.hpp" | ||||
| #include "Prettyfier.hpp" | ||||
| #include "StringBuilder.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // Implements all the overloads of printTo() and prettyPrintTo() | ||||
| // Caution: this class use a template parameter to avoid virtual methods. | ||||
| // This is a bit curious but allows to reduce the size of JsonVariant, JsonArray | ||||
| // and JsonObject. | ||||
| template <typename T> | ||||
| class JsonPrintable { | ||||
|  public: | ||||
|   size_t printTo(Print &print) const { | ||||
|     JsonWriter writer(print); | ||||
|     downcast().writeTo(writer); | ||||
|     return writer.bytesWritten(); | ||||
|   } | ||||
|  | ||||
|   size_t printTo(char *buffer, size_t bufferSize) const { | ||||
|     StringBuilder sb(buffer, bufferSize); | ||||
|     return printTo(sb); | ||||
|   } | ||||
|  | ||||
|   size_t prettyPrintTo(IndentedPrint &print) const { | ||||
|     Prettyfier p(print); | ||||
|     return printTo(p); | ||||
|   } | ||||
|  | ||||
|   size_t prettyPrintTo(char *buffer, size_t bufferSize) const { | ||||
|     StringBuilder sb(buffer, bufferSize); | ||||
|     return prettyPrintTo(sb); | ||||
|   } | ||||
|  | ||||
|   size_t prettyPrintTo(Print &print) const { | ||||
|     IndentedPrint indentedPrint = IndentedPrint(print); | ||||
|     return prettyPrintTo(indentedPrint); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   const T &downcast() const { return *static_cast<const T *>(this); } | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										28
									
								
								include/ArduinoJson/Internals/JsonVariantContent.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								include/ArduinoJson/Internals/JsonVariantContent.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| // Forward declarations | ||||
| class JsonArray; | ||||
| class JsonObject; | ||||
|  | ||||
| namespace Internals { | ||||
|  | ||||
| // A union that defines the actual content of a JsonVariant. | ||||
| // The enum JsonVariantType determines which member is in use. | ||||
| union JsonVariantContent { | ||||
|   bool asBoolean; | ||||
|   double asDouble;       // asDouble is also used for float | ||||
|   long asLong;           // asLong is also used for char, short and int | ||||
|   const char* asString;  // asString can be null | ||||
|   JsonArray* asArray;    // asArray cannot be null | ||||
|   JsonObject* asObject;  // asObject cannot be null | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										33
									
								
								include/ArduinoJson/Internals/JsonVariantType.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								include/ArduinoJson/Internals/JsonVariantType.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // Enumerated type to know the current type of a JsonVariant. | ||||
| // The value determines which member of JsonVariantContent is used. | ||||
| enum JsonVariantType { | ||||
|   JSON_INVALID,    // a special state for JsonVariant::invalid() | ||||
|   JSON_UNDEFINED,  // the JsonVariant has not been initialized | ||||
|   JSON_ARRAY,      // the JsonVariant stores a pointer to a JsonArray | ||||
|   JSON_OBJECT,     // the JsonVariant stores a pointer to a JsonObject | ||||
|   JSON_BOOLEAN,    // the JsonVariant stores a bool | ||||
|   JSON_STRING,     // the JsonVariant stores a const char* | ||||
|   JSON_LONG,       // the JsonVariant stores a long | ||||
|  | ||||
|   // The following values are reserved for double values | ||||
|   // Multiple values are used for double, depending on the number of decimal | ||||
|   // digits that must be printed in the JSON output. | ||||
|   // This little trick allow to save one extra member in JsonVariant | ||||
|   JSON_DOUBLE_0_DECIMALS | ||||
|   // JSON_DOUBLE_1_DECIMAL | ||||
|   // JSON_DOUBLE_2_DECIMALS | ||||
|   // ... | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										64
									
								
								include/ArduinoJson/Internals/JsonWriter.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								include/ArduinoJson/Internals/JsonWriter.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../Arduino/Print.hpp" | ||||
| #include "QuotedString.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // Writes the JSON tokens to a Print implementation | ||||
| // This class is used by: | ||||
| // - JsonArray::writeTo() | ||||
| // - JsonObject::writeTo() | ||||
| // - JsonVariant::writeTo() | ||||
| // Its derived by PrettyJsonWriter that overrides some members to add | ||||
| // indentation. | ||||
| class JsonWriter { | ||||
|  public: | ||||
|   explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {} | ||||
|  | ||||
|   // Returns the number of bytes sent to the Print implementation. | ||||
|   // This is very handy for implementations of printTo() that must return the | ||||
|   // number of bytes written. | ||||
|   size_t bytesWritten() { return _length; } | ||||
|  | ||||
|   void beginArray() { write('['); } | ||||
|   void endArray() { write(']'); } | ||||
|  | ||||
|   void beginObject() { write('{'); } | ||||
|   void endObject() { write('}'); } | ||||
|  | ||||
|   void writeColon() { write(':'); } | ||||
|   void writeComma() { write(','); } | ||||
|  | ||||
|   void writeString(const char *value) { | ||||
|     _length += QuotedString::printTo(value, _sink); | ||||
|   } | ||||
|  | ||||
|   void writeLong(long value) { _length += _sink.print(value); } | ||||
|  | ||||
|   void writeBoolean(bool value) { | ||||
|     _length += _sink.print(value ? "true" : "false"); | ||||
|   } | ||||
|   void writeDouble(double value, uint8_t decimals) { | ||||
|     _length += _sink.print(value, decimals); | ||||
|   } | ||||
|  | ||||
|  protected: | ||||
|   void write(char c) { _length += _sink.write(c); } | ||||
|   void write(const char *s) { _length += _sink.print(s); } | ||||
|  | ||||
|   Print &_sink; | ||||
|   size_t _length; | ||||
|  | ||||
|  private: | ||||
|   JsonWriter &operator=(const JsonWriter &);  // cannot be assigned | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										74
									
								
								include/ArduinoJson/Internals/List.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								include/ArduinoJson/Internals/List.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../JsonBuffer.hpp" | ||||
| #include "ListConstIterator.hpp" | ||||
| #include "ListIterator.hpp" | ||||
| #include "PlacementNew.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // A singly linked list of T. | ||||
| // The linked list is composed of ListNode<T>. | ||||
| // It is derived by JsonArray and JsonObject | ||||
| template <typename T> | ||||
| class List { | ||||
|  public: | ||||
|   typedef T value_type; | ||||
|   typedef ListNode<T> node_type; | ||||
|   typedef ListIterator<T> iterator; | ||||
|   typedef ListConstIterator<T> const_iterator; | ||||
|  | ||||
|   // Creates an empty List<T> attached to a JsonBuffer. | ||||
|   // The JsonBuffer allows to allocate new nodes. | ||||
|   // When buffer is NULL, the List is not able to grow and success() returns | ||||
|   // false. This is used to identify bad memory allocations and parsing | ||||
|   // failures. | ||||
|   explicit List(JsonBuffer *buffer) : _buffer(buffer), _firstNode(NULL) {} | ||||
|  | ||||
|   // Returns true if the object is valid | ||||
|   // Would return false in the following situation: | ||||
|   // - the memory allocation failed (StaticJsonBuffer was too small) | ||||
|   // - the JSON parsing failed | ||||
|   bool success() const { return _buffer != NULL; } | ||||
|  | ||||
|   // Returns the numbers of elements in the list. | ||||
|   // For a JsonObject, it would return the number of key-value pairs | ||||
|   int size() const; | ||||
|  | ||||
|   iterator begin() { return iterator(_firstNode); } | ||||
|   iterator end() { return iterator(NULL); } | ||||
|  | ||||
|   const_iterator begin() const { return const_iterator(_firstNode); } | ||||
|   const_iterator end() const { return const_iterator(NULL); } | ||||
|  | ||||
|  protected: | ||||
|   node_type *createNode() { | ||||
|     if (!_buffer) return NULL; | ||||
|     void *ptr = _buffer->alloc(sizeof(node_type)); | ||||
|     return ptr ? new (ptr) node_type() : NULL; | ||||
|   } | ||||
|  | ||||
|   void addNode(node_type *nodeToAdd) { | ||||
|     if (_firstNode) { | ||||
|       node_type *lastNode = _firstNode; | ||||
|       while (lastNode->next) lastNode = lastNode->next; | ||||
|       lastNode->next = nodeToAdd; | ||||
|     } else { | ||||
|       _firstNode = nodeToAdd; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   void removeNode(node_type *nodeToRemove); | ||||
|  | ||||
|   JsonBuffer *_buffer; | ||||
|   node_type *_firstNode; | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										40
									
								
								include/ArduinoJson/Internals/ListConstIterator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								include/ArduinoJson/Internals/ListConstIterator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "ListNode.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // A read-only forward itertor for List<T> | ||||
| template <typename T> | ||||
| class ListConstIterator { | ||||
|  public: | ||||
|   explicit ListConstIterator(const ListNode<T> *node = NULL) : _node(node) {} | ||||
|  | ||||
|   const T &operator*() const { return _node->content; } | ||||
|   const T *operator->() { return &_node->content; } | ||||
|  | ||||
|   bool operator==(const ListConstIterator<T> &other) const { | ||||
|     return _node == other._node; | ||||
|   } | ||||
|  | ||||
|   bool operator!=(const ListConstIterator<T> &other) const { | ||||
|     return _node != other._node; | ||||
|   } | ||||
|  | ||||
|   ListConstIterator<T> &operator++() { | ||||
|     if (_node) _node = _node->next; | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   const ListNode<T> *_node; | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										40
									
								
								include/ArduinoJson/Internals/ListIterator.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								include/ArduinoJson/Internals/ListIterator.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "ListNode.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // A read-write forward iterator for List<T> | ||||
| template <typename T> | ||||
| class ListIterator { | ||||
|  public: | ||||
|   explicit ListIterator(ListNode<T> *node = NULL) : _node(node) {} | ||||
|  | ||||
|   T &operator*() const { return _node->content; } | ||||
|   T *operator->() { return &_node->content; } | ||||
|  | ||||
|   bool operator==(const ListIterator<T> &other) const { | ||||
|     return _node == other._node; | ||||
|   } | ||||
|  | ||||
|   bool operator!=(const ListIterator<T> &other) const { | ||||
|     return _node != other._node; | ||||
|   } | ||||
|  | ||||
|   ListIterator<T> &operator++() { | ||||
|     if (_node) _node = _node->next; | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   ListNode<T> *_node; | ||||
| }; | ||||
| } | ||||
| } | ||||
							
								
								
									
										24
									
								
								include/ArduinoJson/Internals/ListNode.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								include/ArduinoJson/Internals/ListNode.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| // Copyright Benoit Blanchon 2014 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <stddef.h>  // for NULL | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| // A node for a singly-linked list. | ||||
| // Used by List<T> and its iterators. | ||||
| template <typename T> | ||||
| struct ListNode { | ||||
|   ListNode() : next(NULL) {} | ||||
|  | ||||
|   ListNode<T>* next; | ||||
|   T content; | ||||
| }; | ||||
| } | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user