forked from bblanchon/ArduinoJson
Compare commits
55 Commits
Author | SHA1 | Date | |
---|---|---|---|
58c051f564 | |||
763aa7fe37 | |||
cd88fb0882 | |||
ec843659d8 | |||
2997a405a0 | |||
57f28c2017 | |||
b3b70b78cf | |||
48018bd6e6 | |||
61952a9bcd | |||
602cc104f9 | |||
d71a39211d | |||
f77a8b02e3 | |||
aa2cd0db00 | |||
f127ef6019 | |||
3ae7327687 | |||
23e61cc0f7 | |||
b5002265cf | |||
e48ea94789 | |||
6539c6982c | |||
d877d77b63 | |||
1df6cde026 | |||
fafae8181b | |||
151fc52c1c | |||
ea79340dc7 | |||
9e88514700 | |||
752378a8cb | |||
8465cc0c83 | |||
2ddf8f1619 | |||
f7aa0f89e3 | |||
3d322fdb28 | |||
981adf1989 | |||
dbc3bee3a0 | |||
3f2b7b706a | |||
c243417585 | |||
514a6c0879 | |||
76f9ecce75 | |||
410ca55e88 | |||
66c05041e8 | |||
aafabd8e8d | |||
eb1a774778 | |||
75c89e7b35 | |||
e31a2136fc | |||
380722402f | |||
030c8542e7 | |||
1f25d4434e | |||
f29904e217 | |||
7246db7691 | |||
4bdbc6c1fc | |||
8e6fdb20eb | |||
016d0d699e | |||
6771603a05 | |||
d067cf0e84 | |||
13593d73a3 | |||
bc86ae800a | |||
df52dceaa1 |
13
BuildArduinoPackage.sh
Normal file
13
BuildArduinoPackage.sh
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
ZIP="C:\Program Files\7-Zip\7z.exe"
|
||||||
|
|
||||||
|
TAG=$(git describe)
|
||||||
|
OUTPUT="ArduinoJson-$TAG.zip"
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
INPUT=$(find ArduinoJson -regex ".*\.\(cpp\|h\|md\|txt\|ino\)$" -not -regex ".*Tests/.*")
|
||||||
|
|
||||||
|
rm -f $OUTPUT
|
||||||
|
"$ZIP" a $OUTPUT $INPUT
|
17
CHANGELOG.md
17
CHANGELOG.md
@ -1,6 +1,23 @@
|
|||||||
Arduino JSON: change log
|
Arduino JSON: change log
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
v3.3
|
||||||
|
----
|
||||||
|
|
||||||
|
* Added indented output for the JSON generator, see example bellow.
|
||||||
|
* Added `IndentedPrint`, a decorator for `Print` to allow indented output
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
JsonOject<2> json;
|
||||||
|
json["key"] = "value";
|
||||||
|
json.prettyPrintTo(Serial);
|
||||||
|
|
||||||
|
v3.2
|
||||||
|
----
|
||||||
|
|
||||||
|
* Fixed a bug when adding nested object in `JsonArray` (bug introduced in v3.1).
|
||||||
|
|
||||||
v3.1
|
v3.1
|
||||||
----
|
----
|
||||||
|
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
// This file is here to help the Arduino IDE find the .cpp files
|
// This file is here to help the Arduino IDE find the .cpp files
|
||||||
|
|
||||||
#include "JsonGenerator/EscapedString.cpp"
|
#include "JsonGenerator/EscapedString.cpp"
|
||||||
|
#include "JsonGenerator/IndentedPrint.cpp"
|
||||||
#include "JsonGenerator/JsonArrayBase.cpp"
|
#include "JsonGenerator/JsonArrayBase.cpp"
|
||||||
#include "JsonGenerator/JsonObjectBase.cpp"
|
#include "JsonGenerator/JsonObjectBase.cpp"
|
||||||
#include "JsonGenerator/JsonValue.cpp"
|
#include "JsonGenerator/JsonValue.cpp"
|
||||||
|
#include "JsonGenerator/JsonPrettyPrint.cpp"
|
||||||
|
#include "JsonGenerator/JsonPrintable.cpp"
|
||||||
#include "JsonGenerator/StringBuilder.cpp"
|
#include "JsonGenerator/StringBuilder.cpp"
|
45
JsonGenerator/IndentedPrint.cpp
Normal file
45
JsonGenerator/IndentedPrint.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include "IndentedPrint.h"
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
|
||||||
|
void IndentedPrint::indent()
|
||||||
|
{
|
||||||
|
if (level < MAX_LEVEL)
|
||||||
|
level++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IndentedPrint::unindent()
|
||||||
|
{
|
||||||
|
if (level > 0)
|
||||||
|
level--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IndentedPrint::setTabSize(uint8_t n)
|
||||||
|
{
|
||||||
|
if (n < MAX_TAB_SIZE)
|
||||||
|
tabSize = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IndentedPrint::write(uint8_t c)
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
if (isNewLine)
|
||||||
|
n += writeTabs();
|
||||||
|
|
||||||
|
n += sink.write(c);
|
||||||
|
|
||||||
|
isNewLine = c == '\n';
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t IndentedPrint::writeTabs()
|
||||||
|
{
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < level*tabSize; i++)
|
||||||
|
n += sink.write(' ');
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
53
JsonGenerator/IndentedPrint.h
Normal file
53
JsonGenerator/IndentedPrint.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Print.h"
|
||||||
|
|
||||||
|
namespace ArduinoJson
|
||||||
|
{
|
||||||
|
namespace Generator
|
||||||
|
{
|
||||||
|
// Decorator on top of Print to allow indented output.
|
||||||
|
// This class is used by JsonPrintable::prettyPrintTo() but can also be used
|
||||||
|
// for your own purpose, like logging.
|
||||||
|
class IndentedPrint : public Print
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
IndentedPrint(Print& p)
|
||||||
|
: sink(p)
|
||||||
|
{
|
||||||
|
level = 0;
|
||||||
|
tabSize = 2;
|
||||||
|
isNewLine = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t write(uint8_t);
|
||||||
|
|
||||||
|
// Adds one level of indentation
|
||||||
|
void indent();
|
||||||
|
|
||||||
|
// Removes one level of indentation
|
||||||
|
void unindent();
|
||||||
|
|
||||||
|
// Set the number of space printed for each level of indentation
|
||||||
|
void setTabSize(uint8_t n);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Print& sink;
|
||||||
|
uint8_t level : 4;
|
||||||
|
uint8_t tabSize : 3;
|
||||||
|
bool isNewLine : 1;
|
||||||
|
|
||||||
|
size_t writeTabs();
|
||||||
|
|
||||||
|
static const int MAX_LEVEL = 15; // because it's only 4 bits
|
||||||
|
static const int MAX_TAB_SIZE = 7; // because it's only 3 bits
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "JsonPrintable.h"
|
#include "JsonPrintable.h"
|
||||||
|
#include "JsonValue.h"
|
||||||
|
|
||||||
namespace ArduinoJson
|
namespace ArduinoJson
|
||||||
{
|
{
|
||||||
@ -20,12 +21,34 @@ namespace ArduinoJson
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
void add(const Printable& value)
|
||||||
void add(T value)
|
|
||||||
{
|
{
|
||||||
if (count >= capacity) return;
|
addIfPossible<const Printable&>(value);
|
||||||
|
}
|
||||||
|
|
||||||
items[count++] = 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>
|
template<int DIGITS>
|
||||||
@ -44,6 +67,13 @@ namespace ArduinoJson
|
|||||||
private:
|
private:
|
||||||
JsonValue* items;
|
JsonValue* items;
|
||||||
int capacity, count;
|
int capacity, count;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void addIfPossible(T value)
|
||||||
|
{
|
||||||
|
if (count < capacity)
|
||||||
|
items[count++] = value;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -12,6 +12,8 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="EscapedString.h" />
|
<ClInclude Include="EscapedString.h" />
|
||||||
|
<ClInclude Include="IndentedPrint.h" />
|
||||||
|
<ClInclude Include="JsonPrettyPrint.h" />
|
||||||
<ClInclude Include="JsonArray.h" />
|
<ClInclude Include="JsonArray.h" />
|
||||||
<ClInclude Include="JsonArrayBase.h" />
|
<ClInclude Include="JsonArrayBase.h" />
|
||||||
<ClInclude Include="JsonObject.h" />
|
<ClInclude Include="JsonObject.h" />
|
||||||
@ -24,8 +26,11 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="EscapedString.cpp" />
|
<ClCompile Include="EscapedString.cpp" />
|
||||||
|
<ClCompile Include="IndentedPrint.cpp" />
|
||||||
|
<ClCompile Include="JsonPrettyPrint.cpp" />
|
||||||
<ClCompile Include="JsonArrayBase.cpp" />
|
<ClCompile Include="JsonArrayBase.cpp" />
|
||||||
<ClCompile Include="JsonObjectBase.cpp" />
|
<ClCompile Include="JsonObjectBase.cpp" />
|
||||||
|
<ClCompile Include="JsonPrintable.cpp" />
|
||||||
<ClCompile Include="JsonValue.cpp" />
|
<ClCompile Include="JsonValue.cpp" />
|
||||||
<ClCompile Include="Print.cpp" />
|
<ClCompile Include="Print.cpp" />
|
||||||
<ClCompile Include="StringBuilder.cpp" />
|
<ClCompile Include="StringBuilder.cpp" />
|
||||||
|
@ -45,6 +45,12 @@
|
|||||||
<ClInclude Include="JsonObject.h">
|
<ClInclude Include="JsonObject.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="IndentedPrint.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="JsonPrettyPrint.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="EscapedString.cpp">
|
<ClCompile Include="EscapedString.cpp">
|
||||||
@ -65,5 +71,14 @@
|
|||||||
<ClCompile Include="JsonObjectBase.cpp">
|
<ClCompile Include="JsonObjectBase.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -6,6 +6,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "JsonPrintable.h"
|
#include "JsonPrintable.h"
|
||||||
|
#include "JsonValue.h"
|
||||||
#include "EscapedString.h"
|
#include "EscapedString.h"
|
||||||
|
|
||||||
namespace ArduinoJson
|
namespace ArduinoJson
|
||||||
|
97
JsonGenerator/JsonPrettyPrint.cpp
Normal file
97
JsonGenerator/JsonPrettyPrint.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "JsonPrettyPrint.h"
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
|
||||||
|
size_t JsonPrettyPrint::write(uint8_t c)
|
||||||
|
{
|
||||||
|
size_t n = inString ? handleStringChar(c) : handleMarkupChar(c);
|
||||||
|
previousChar = c;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleStringChar(uint8_t c)
|
||||||
|
{
|
||||||
|
bool isQuote = c == '"' && previousChar != '\\';
|
||||||
|
|
||||||
|
if (isQuote) inString = false;
|
||||||
|
|
||||||
|
return sink.write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleMarkupChar(uint8_t c)
|
||||||
|
{
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '{':
|
||||||
|
case '[':
|
||||||
|
return handleBlockOpen(c);
|
||||||
|
|
||||||
|
case '}':
|
||||||
|
case ']':
|
||||||
|
return handleBlockClose(c);
|
||||||
|
|
||||||
|
case ':':
|
||||||
|
return handleColumn();
|
||||||
|
|
||||||
|
case ',':
|
||||||
|
return handleComma();
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
return handleQuoteOpen();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return handleNormalChar(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleBlockOpen(uint8_t c)
|
||||||
|
{
|
||||||
|
return indentIfNeeded() + sink.write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleBlockClose(uint8_t c)
|
||||||
|
{
|
||||||
|
return unindentIfNeeded() + sink.write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleColumn()
|
||||||
|
{
|
||||||
|
return sink.write(':') + sink.write(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleComma()
|
||||||
|
{
|
||||||
|
return sink.write(',') + sink.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleQuoteOpen()
|
||||||
|
{
|
||||||
|
inString = true;
|
||||||
|
return indentIfNeeded() + sink.write('"');
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t JsonPrettyPrint::handleNormalChar(uint8_t c)
|
||||||
|
{
|
||||||
|
return indentIfNeeded() + sink.write(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t JsonPrettyPrint::indentIfNeeded()
|
||||||
|
{
|
||||||
|
if (!inEmptyBlock()) return 0;
|
||||||
|
|
||||||
|
sink.indent();
|
||||||
|
return sink.println();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t JsonPrettyPrint::unindentIfNeeded()
|
||||||
|
{
|
||||||
|
if (inEmptyBlock()) return 0;
|
||||||
|
|
||||||
|
sink.unindent();
|
||||||
|
return sink.println();
|
||||||
|
}
|
52
JsonGenerator/JsonPrettyPrint.h
Normal file
52
JsonGenerator/JsonPrettyPrint.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Print.h"
|
||||||
|
#include "IndentedPrint.h"
|
||||||
|
|
||||||
|
namespace ArduinoJson
|
||||||
|
{
|
||||||
|
namespace Generator
|
||||||
|
{
|
||||||
|
// Converts a compact JSON string into an indented one.
|
||||||
|
class JsonPrettyPrint : public Print
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
JsonPrettyPrint(IndentedPrint& p)
|
||||||
|
: sink(p)
|
||||||
|
{
|
||||||
|
previousChar = 0;
|
||||||
|
inString = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual size_t write(uint8_t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint8_t previousChar;
|
||||||
|
IndentedPrint& sink;
|
||||||
|
bool inString;
|
||||||
|
|
||||||
|
bool inEmptyBlock()
|
||||||
|
{
|
||||||
|
return previousChar == '{' || previousChar == '[';
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t handleStringChar(uint8_t);
|
||||||
|
size_t handleMarkupChar(uint8_t);
|
||||||
|
|
||||||
|
size_t handleBlockClose(uint8_t);
|
||||||
|
size_t handleBlockOpen(uint8_t);
|
||||||
|
size_t handleColumn();
|
||||||
|
size_t handleComma();
|
||||||
|
size_t handleQuoteOpen();
|
||||||
|
size_t handleNormalChar(uint8_t);
|
||||||
|
size_t indentIfNeeded();
|
||||||
|
size_t unindentIfNeeded();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
35
JsonGenerator/JsonPrintable.cpp
Normal file
35
JsonGenerator/JsonPrintable.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "JsonPrintable.h"
|
||||||
|
#include "JsonPrettyPrint.h"
|
||||||
|
#include "StringBuilder.h"
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
|
size_t JsonPrintable::printTo(char* buffer, size_t bufferSize) const
|
||||||
|
{
|
||||||
|
StringBuilder sb(buffer, bufferSize);
|
||||||
|
return printTo(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t JsonPrintable::prettyPrintTo(char* buffer, size_t bufferSize) const
|
||||||
|
{
|
||||||
|
StringBuilder sb(buffer, bufferSize);
|
||||||
|
return prettyPrintTo(sb);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t JsonPrintable::prettyPrintTo(IndentedPrint& p) const
|
||||||
|
{
|
||||||
|
JsonPrettyPrint prettyPrint(p);
|
||||||
|
return printTo(prettyPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t JsonPrintable::prettyPrintTo(Print& p) const
|
||||||
|
{
|
||||||
|
IndentedPrint indentedPrint(p);
|
||||||
|
return prettyPrintTo(indentedPrint);
|
||||||
|
}
|
@ -5,27 +5,36 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "JsonValue.h"
|
|
||||||
#include "Print.h"
|
#include "Print.h"
|
||||||
#include "Printable.h"
|
#include "Printable.h"
|
||||||
|
#include "IndentedPrint.h"
|
||||||
|
|
||||||
namespace ArduinoJson
|
namespace ArduinoJson
|
||||||
{
|
{
|
||||||
namespace Generator
|
namespace Generator
|
||||||
{
|
{
|
||||||
|
// Contains methods to generate a JSON string.
|
||||||
|
// Implemented by both JsonObject and JsonArray
|
||||||
class JsonPrintable : public Printable
|
class JsonPrintable : public Printable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
size_t printTo(char* buffer, size_t bufferSize)
|
// Generates the compact JSON string and sends it to a Print stream
|
||||||
{
|
|
||||||
using namespace Internals;
|
|
||||||
|
|
||||||
StringBuilder sb(buffer, bufferSize);
|
|
||||||
return printTo(sb);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual size_t printTo(Print& p) const = 0;
|
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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -35,7 +35,7 @@ namespace ArduinoJson
|
|||||||
content.asLong = value;
|
content.asLong = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator=(Printable& value)
|
void operator=(const Printable& value)
|
||||||
{
|
{
|
||||||
printToImpl = &printPrintableTo;
|
printToImpl = &printPrintableTo;
|
||||||
content.asPrintable = &value;
|
content.asPrintable = &value;
|
||||||
@ -89,7 +89,7 @@ namespace ArduinoJson
|
|||||||
return content.asLong;
|
return content.asLong;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator Printable&()
|
operator const Printable&()
|
||||||
{
|
{
|
||||||
return *content.asPrintable;
|
return *content.asPrintable;
|
||||||
}
|
}
|
||||||
@ -109,11 +109,11 @@ namespace ArduinoJson
|
|||||||
private:
|
private:
|
||||||
union Content
|
union Content
|
||||||
{
|
{
|
||||||
bool asBool;
|
bool asBool;
|
||||||
double asDouble;
|
double asDouble;
|
||||||
long asLong;
|
long asLong;
|
||||||
Printable* asPrintable;
|
const Printable* asPrintable;
|
||||||
const char* asString;
|
const char* asString;
|
||||||
};
|
};
|
||||||
|
|
||||||
Content content;
|
Content content;
|
||||||
|
@ -32,4 +32,9 @@ size_t Print::print(long value)
|
|||||||
return print(tmp);
|
return print(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t Print::println()
|
||||||
|
{
|
||||||
|
return write('\r') + write('\n');
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -19,6 +19,7 @@ public:
|
|||||||
size_t print(const char[]);
|
size_t print(const char[]);
|
||||||
size_t print(double, int = 2);
|
size_t print(double, int = 2);
|
||||||
size_t print(long);
|
size_t print(long);
|
||||||
|
size_t println();
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -15,6 +15,7 @@ Features
|
|||||||
* Fixed memory allocation (no malloc)
|
* Fixed memory allocation (no malloc)
|
||||||
* Small footprint
|
* Small footprint
|
||||||
* Supports nested objects
|
* Supports nested objects
|
||||||
|
* Supports indented output
|
||||||
* Implements Arduino's `Printable interface
|
* Implements Arduino's `Printable interface
|
||||||
* MIT License
|
* MIT License
|
||||||
|
|
||||||
@ -101,6 +102,33 @@ or
|
|||||||
JsonObject<8> nestedObject;
|
JsonObject<8> nestedObject;
|
||||||
array.add(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
|
#### JSON Object
|
||||||
|
|
||||||
You create a JSON object (ie hash-table/dictionary) with the following line:
|
You create a JSON object (ie hash-table/dictionary) with the following line:
|
||||||
@ -150,6 +178,13 @@ Whether you have a `JsonArray` or a `JsonObject`, simply call `printTo()` with t
|
|||||||
char buffer[256];
|
char buffer[256];
|
||||||
array.printTo(buffer, sizeof(buffer));
|
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
|
#### 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:
|
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:
|
||||||
@ -163,7 +198,7 @@ or
|
|||||||
> ##### About the Printable interface
|
> ##### About the Printable interface
|
||||||
> `JsonArray` and `JsonObject` implement Arduino's `Printable` interface.
|
> `JsonArray` and `JsonObject` implement Arduino's `Printable` interface.
|
||||||
> This is why you can call `Serial.print()` like in the example above.
|
> This is why you can call `Serial.print()` like in the example above.
|
||||||
> You can do the same with any other implementation of `Print`: `HardwareSerial`, `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`...
|
> You can do the same with any other implementation of `Print`: `HardwareSerial`, `SoftwareSerial`, `LiquidCrystal`, `EthernetClient`, `WiFiClient`, `Wire`...
|
||||||
|
|
||||||
|
|
||||||
Memory usage
|
Memory usage
|
||||||
|
73
JsonGeneratorTests/Issue10.cpp
Normal file
73
JsonGeneratorTests/Issue10.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "CppUnitTest.h"
|
||||||
|
#include "JsonArray.h"
|
||||||
|
#include "JsonObject.h"
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
|
namespace JsonGeneratorTests
|
||||||
|
{
|
||||||
|
TEST_CLASS(Issue10)
|
||||||
|
{
|
||||||
|
struct Person {
|
||||||
|
int id;
|
||||||
|
char name[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
Person persons[2];
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TEST_METHOD_INITIALIZE(Initialize)
|
||||||
|
{
|
||||||
|
Person boss;
|
||||||
|
boss.id = 1;
|
||||||
|
strcpy(boss.name, "Jeff");
|
||||||
|
Person employee;
|
||||||
|
employee.id = 2;
|
||||||
|
strcpy(employee.name, "John");
|
||||||
|
persons[0] = boss;
|
||||||
|
persons[1] = employee;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(WrongWayToAddObjectInAnArray)
|
||||||
|
{
|
||||||
|
JsonArray<2> json;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
JsonObject<2> object;
|
||||||
|
|
||||||
|
object["id"] = persons[i].id;
|
||||||
|
object["name"] = persons[i].name;
|
||||||
|
|
||||||
|
json.add(object); // <- Adding a reference to a temporary variable
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[256];
|
||||||
|
json.printTo(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
// the same values are repeated, that's normal
|
||||||
|
Assert::AreEqual("[{\"id\":2,\"name\":\"John\"},{\"id\":2,\"name\":\"John\"}]", buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(RightWayToAddObjectInAnArray)
|
||||||
|
{
|
||||||
|
JsonArray<2> json;
|
||||||
|
JsonObject<2> object[2];
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
object[i]["id"] = persons[i].id;
|
||||||
|
object[i]["name"] = persons[i].name;
|
||||||
|
|
||||||
|
json.add(object[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[256];
|
||||||
|
json.printTo(buffer, sizeof(buffer));
|
||||||
|
|
||||||
|
Assert::AreEqual("[{\"id\":1,\"name\":\"Jeff\"},{\"id\":2,\"name\":\"John\"}]", buffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -14,7 +14,7 @@ namespace JsonGeneratorTests
|
|||||||
{
|
{
|
||||||
TEST_CLASS(JsonArrayTests)
|
TEST_CLASS(JsonArrayTests)
|
||||||
{
|
{
|
||||||
JsonArray<2> arr;
|
JsonArray<2> array;
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -26,111 +26,117 @@ namespace JsonGeneratorTests
|
|||||||
|
|
||||||
TEST_METHOD(Null)
|
TEST_METHOD(Null)
|
||||||
{
|
{
|
||||||
add((char*)0);
|
array.add((char*) 0);
|
||||||
|
|
||||||
outputMustBe("[null]");
|
outputMustBe("[null]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneString)
|
TEST_METHOD(OneString)
|
||||||
{
|
{
|
||||||
add("hello");
|
array.add("hello");
|
||||||
|
|
||||||
outputMustBe("[\"hello\"]");
|
outputMustBe("[\"hello\"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(TwoStrings)
|
TEST_METHOD(TwoStrings)
|
||||||
{
|
{
|
||||||
add("hello");
|
array.add("hello");
|
||||||
add("world");
|
array.add("world");
|
||||||
|
|
||||||
outputMustBe("[\"hello\",\"world\"]");
|
outputMustBe("[\"hello\",\"world\"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneStringOverCapacity)
|
TEST_METHOD(OneStringOverCapacity)
|
||||||
{
|
{
|
||||||
add("hello");
|
array.add("hello");
|
||||||
add("world");
|
array.add("world");
|
||||||
add("lost");
|
array.add("lost");
|
||||||
|
|
||||||
outputMustBe("[\"hello\",\"world\"]");
|
outputMustBe("[\"hello\",\"world\"]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneDoubleDefaultDigits)
|
TEST_METHOD(OneDoubleDefaultDigits)
|
||||||
{
|
{
|
||||||
add(3.14159265358979323846);
|
array.add(3.14159265358979323846);
|
||||||
outputMustBe("[3.14]");
|
outputMustBe("[3.14]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneDoubleFourDigits)
|
TEST_METHOD(OneDoubleFourDigits)
|
||||||
{
|
{
|
||||||
add<4>(3.14159265358979323846);
|
array.add<4>(3.14159265358979323846);
|
||||||
outputMustBe("[3.1416]");
|
outputMustBe("[3.1416]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneInteger)
|
TEST_METHOD(OneInteger)
|
||||||
{
|
{
|
||||||
add(1);
|
array.add(1);
|
||||||
|
|
||||||
outputMustBe("[1]");
|
outputMustBe("[1]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(TwoIntegers)
|
TEST_METHOD(TwoIntegers)
|
||||||
{
|
{
|
||||||
add(1);
|
array.add(1);
|
||||||
add(2);
|
array.add(2);
|
||||||
|
|
||||||
outputMustBe("[1,2]");
|
outputMustBe("[1,2]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneIntegerOverCapacity)
|
TEST_METHOD(OneIntegerOverCapacity)
|
||||||
{
|
{
|
||||||
add(1);
|
array.add(1);
|
||||||
add(2);
|
array.add(2);
|
||||||
add(3);
|
array.add(3);
|
||||||
|
|
||||||
outputMustBe("[1,2]");
|
outputMustBe("[1,2]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneTrue)
|
TEST_METHOD(OneTrue)
|
||||||
{
|
{
|
||||||
add(true);
|
array.add(true);
|
||||||
|
|
||||||
outputMustBe("[true]");
|
outputMustBe("[true]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneFalse)
|
TEST_METHOD(OneFalse)
|
||||||
{
|
{
|
||||||
add(false);
|
array.add(false);
|
||||||
|
|
||||||
outputMustBe("[false]");
|
outputMustBe("[false]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(TwoBooleans)
|
TEST_METHOD(TwoBooleans)
|
||||||
{
|
{
|
||||||
add(false);
|
array.add(false);
|
||||||
add(true);
|
array.add(true);
|
||||||
|
|
||||||
outputMustBe("[false,true]");
|
outputMustBe("[false,true]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneBooleanOverCapacity)
|
TEST_METHOD(OneBooleanOverCapacity)
|
||||||
{
|
{
|
||||||
add(false);
|
array.add(false);
|
||||||
add(true);
|
array.add(true);
|
||||||
add(false);
|
array.add(false);
|
||||||
|
|
||||||
outputMustBe("[false,true]");
|
outputMustBe("[false,true]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneEmptyNestedArray)
|
TEST_METHOD(OneEmptyNestedArray)
|
||||||
{
|
{
|
||||||
addNested(JsonArray<1>());
|
JsonArray<1> nestedArray;
|
||||||
|
|
||||||
|
array.add(nestedArray);
|
||||||
|
|
||||||
outputMustBe("[[]]");
|
outputMustBe("[[]]");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_METHOD(OneEmptyNestedHash)
|
TEST_METHOD(OneEmptyNestedHash)
|
||||||
{
|
{
|
||||||
addNested(JsonHashTable<1>());
|
JsonObject<1> nestedObject;
|
||||||
|
|
||||||
|
array.add(nestedObject);
|
||||||
|
|
||||||
outputMustBe("[{}]");
|
outputMustBe("[{}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,33 +145,16 @@ namespace JsonGeneratorTests
|
|||||||
JsonArray<1> nestedArray;
|
JsonArray<1> nestedArray;
|
||||||
nestedArray.add(1);
|
nestedArray.add(1);
|
||||||
|
|
||||||
addNested(nestedArray);
|
array.add(nestedArray);
|
||||||
|
|
||||||
outputMustBe("[[1]]");
|
outputMustBe("[[1]]");
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void addNested(Printable& value)
|
|
||||||
{
|
|
||||||
arr.add<Printable&>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void add(T value)
|
|
||||||
{
|
|
||||||
arr.add(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<int DIGITS>
|
|
||||||
void add(double value)
|
|
||||||
{
|
|
||||||
arr.add<DIGITS>(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void outputMustBe(const char* expected)
|
void outputMustBe(const char* expected)
|
||||||
{
|
{
|
||||||
size_t n = arr.printTo(buffer, sizeof(buffer));
|
size_t n = array.printTo(buffer, sizeof(buffer));
|
||||||
Assert::AreEqual(expected, buffer);
|
Assert::AreEqual(expected, buffer);
|
||||||
Assert::AreEqual(strlen(expected), n);
|
Assert::AreEqual(strlen(expected), n);
|
||||||
}
|
}
|
||||||
|
@ -85,6 +85,10 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="EscapedStringTests.cpp" />
|
<ClCompile Include="EscapedStringTests.cpp" />
|
||||||
|
<ClCompile Include="PrettyPrint_Array_Tests.cpp" />
|
||||||
|
<ClCompile Include="PrettyPrint_Object_Tests.cpp" />
|
||||||
|
<ClCompile Include="PrettyPrint_String_Tests.cpp" />
|
||||||
|
<ClCompile Include="Issue10.cpp" />
|
||||||
<ClCompile Include="JsonArrayTests.cpp" />
|
<ClCompile Include="JsonArrayTests.cpp" />
|
||||||
<ClCompile Include="JsonObject_Indexer_Tests.cpp" />
|
<ClCompile Include="JsonObject_Indexer_Tests.cpp" />
|
||||||
<ClCompile Include="JsonObject_PrintTo_Tests.cpp" />
|
<ClCompile Include="JsonObject_PrintTo_Tests.cpp" />
|
||||||
|
@ -36,5 +36,17 @@
|
|||||||
<ClCompile Include="JsonValue_Cast_Tests.cpp">
|
<ClCompile Include="JsonValue_Cast_Tests.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -71,7 +71,7 @@ namespace JsonGeneratorTests
|
|||||||
void setValueAndCheckCast(JsonArray<N>& expected)
|
void setValueAndCheckCast(JsonArray<N>& expected)
|
||||||
{
|
{
|
||||||
value = expected;
|
value = expected;
|
||||||
Printable& actual = value;
|
const Printable& actual = value;
|
||||||
Assert::AreEqual((void*) &expected, (void*) &actual);
|
Assert::AreEqual((void*) &expected, (void*) &actual);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
91
JsonGeneratorTests/PrettyPrint_Array_Tests.cpp
Normal file
91
JsonGeneratorTests/PrettyPrint_Array_Tests.cpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CppUnitTest.h"
|
||||||
|
#include "JsonPrettyPrint.h"
|
||||||
|
#include "StringBuilder.h"
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Internals;
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
|
namespace JsonGeneratorTests
|
||||||
|
{
|
||||||
|
TEST_CLASS(PrettyPrint_Array_Tests)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
size_t returnValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TEST_METHOD(EmptyArray)
|
||||||
|
{
|
||||||
|
whenInputIs("[]");
|
||||||
|
outputMustBe("[]");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(OneElement)
|
||||||
|
{
|
||||||
|
whenInputIs("[1]");
|
||||||
|
outputMustBe(
|
||||||
|
"[\r\n"
|
||||||
|
" 1\r\n"
|
||||||
|
"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(TwoElements)
|
||||||
|
{
|
||||||
|
whenInputIs("[1,2]");
|
||||||
|
outputMustBe(
|
||||||
|
"[\r\n"
|
||||||
|
" 1,\r\n"
|
||||||
|
" 2\r\n"
|
||||||
|
"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(EmptyNestedArrays)
|
||||||
|
{
|
||||||
|
whenInputIs("[[],[]]");
|
||||||
|
outputMustBe(
|
||||||
|
"[\r\n"
|
||||||
|
" [],\r\n"
|
||||||
|
" []\r\n"
|
||||||
|
"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(NestedArrays)
|
||||||
|
{
|
||||||
|
whenInputIs("[[1,2],[3,4]]");
|
||||||
|
outputMustBe(
|
||||||
|
"[\r\n"
|
||||||
|
" [\r\n"
|
||||||
|
" 1,\r\n"
|
||||||
|
" 2\r\n"
|
||||||
|
" ],\r\n"
|
||||||
|
" [\r\n"
|
||||||
|
" 3,\r\n"
|
||||||
|
" 4\r\n"
|
||||||
|
" ]\r\n"
|
||||||
|
"]");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void whenInputIs(const char input[])
|
||||||
|
{
|
||||||
|
StringBuilder sb(buffer, sizeof(buffer));
|
||||||
|
IndentedPrint indentedPrint(sb);
|
||||||
|
JsonPrettyPrint decorator(indentedPrint);
|
||||||
|
|
||||||
|
returnValue = decorator.print(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputMustBe(const char* expected)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(expected, buffer);
|
||||||
|
Assert::AreEqual(strlen(expected), returnValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
89
JsonGeneratorTests/PrettyPrint_Object_Tests.cpp
Normal file
89
JsonGeneratorTests/PrettyPrint_Object_Tests.cpp
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CppUnitTest.h"
|
||||||
|
#include "JsonPrettyPrint.h"
|
||||||
|
#include "StringBuilder.h"
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Internals;
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
|
namespace JsonGeneratorTests
|
||||||
|
{
|
||||||
|
TEST_CLASS(PrettyPrint_Object_Tests)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
size_t returnValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TEST_METHOD(EmptyObject)
|
||||||
|
{
|
||||||
|
whenInputIs("{}");
|
||||||
|
outputMustBe("{}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(OneMember)
|
||||||
|
{
|
||||||
|
whenInputIs("{\"key\":\"value\"}");
|
||||||
|
outputMustBe(
|
||||||
|
"{\r\n"
|
||||||
|
" \"key\": \"value\"\r\n"
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(TwoMembers)
|
||||||
|
{
|
||||||
|
whenInputIs("{\"key1\":\"value1\",\"key2\":\"value2\"}");
|
||||||
|
outputMustBe(
|
||||||
|
"{\r\n"
|
||||||
|
" \"key1\": \"value1\",\r\n"
|
||||||
|
" \"key2\": \"value2\"\r\n"
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(EmptyNestedObjects)
|
||||||
|
{
|
||||||
|
whenInputIs("{\"key1\":{},\"key2\":{}}");
|
||||||
|
outputMustBe(
|
||||||
|
"{\r\n"
|
||||||
|
" \"key1\": {},\r\n"
|
||||||
|
" \"key2\": {}\r\n"
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(NestedObjects)
|
||||||
|
{
|
||||||
|
whenInputIs("{\"key1\":{\"a\":1},\"key2\":{\"b\":2}}");
|
||||||
|
outputMustBe(
|
||||||
|
"{\r\n"
|
||||||
|
" \"key1\": {\r\n"
|
||||||
|
" \"a\": 1\r\n"
|
||||||
|
" },\r\n"
|
||||||
|
" \"key2\": {\r\n"
|
||||||
|
" \"b\": 2\r\n"
|
||||||
|
" }\r\n"
|
||||||
|
"}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void whenInputIs(const char input[])
|
||||||
|
{
|
||||||
|
StringBuilder sb(buffer, sizeof(buffer));
|
||||||
|
IndentedPrint indentedPrint(sb);
|
||||||
|
JsonPrettyPrint decorator(indentedPrint);
|
||||||
|
|
||||||
|
returnValue = decorator.print(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputMustBe(const char* expected)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(expected, buffer);
|
||||||
|
Assert::AreEqual(strlen(expected), returnValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
76
JsonGeneratorTests/PrettyPrint_String_Tests.cpp
Normal file
76
JsonGeneratorTests/PrettyPrint_String_Tests.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "CppUnitTest.h"
|
||||||
|
#include "JsonPrettyPrint.h"
|
||||||
|
#include "StringBuilder.h"
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Internals;
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
|
||||||
|
|
||||||
|
namespace JsonGeneratorTests
|
||||||
|
{
|
||||||
|
TEST_CLASS(PrettyPrint_String_Tests)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
size_t returnValue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TEST_METHOD(EmptyString)
|
||||||
|
{
|
||||||
|
whenInputIs("");
|
||||||
|
outputMustBe("");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(TrickyCharacters)
|
||||||
|
{
|
||||||
|
whenInputIs ("\":\\\"',\"");
|
||||||
|
outputMustBe("\":\\\"',\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(OpeningCurlyBrace)
|
||||||
|
{
|
||||||
|
whenInputIs ("\"{\"");
|
||||||
|
outputMustBe("\"{\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(OpeningSquareBrace)
|
||||||
|
{
|
||||||
|
whenInputIs("\"[\"");
|
||||||
|
outputMustBe("\"[\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(ClosingCurlyBrace)
|
||||||
|
{
|
||||||
|
whenInputIs("\"}\"");
|
||||||
|
outputMustBe("\"}\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_METHOD(ClosingSquareBrace)
|
||||||
|
{
|
||||||
|
whenInputIs("\"]\"");
|
||||||
|
outputMustBe("\"]\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void whenInputIs(const char input[])
|
||||||
|
{
|
||||||
|
StringBuilder sb(buffer, sizeof(buffer));
|
||||||
|
IndentedPrint indentedPrint(sb);
|
||||||
|
JsonPrettyPrint decorator(indentedPrint);
|
||||||
|
|
||||||
|
returnValue = decorator.print(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
void outputMustBe(const char* expected)
|
||||||
|
{
|
||||||
|
Assert::AreEqual(expected, buffer);
|
||||||
|
Assert::AreEqual(strlen(expected), returnValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
43
examples/IndentedPrintExample/IndentedPrintExample.ino
Normal file
43
examples/IndentedPrintExample/IndentedPrintExample.ino
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Arduino JSON library - IndentedPrint example
|
||||||
|
* Benoit Blanchon 2014 - MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <JsonGenerator.h>
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Generator;
|
||||||
|
|
||||||
|
void setup()
|
||||||
|
{
|
||||||
|
Serial.begin(9600);
|
||||||
|
|
||||||
|
JsonObject<1> json;
|
||||||
|
json["key"] = "value";
|
||||||
|
|
||||||
|
IndentedPrint serial(Serial);
|
||||||
|
serial.setTabSize(4);
|
||||||
|
|
||||||
|
serial.println("This is at indentation 0");
|
||||||
|
serial.indent();
|
||||||
|
serial.println("This is at indentation 1");
|
||||||
|
serial.println("This is also at indentation 1");
|
||||||
|
serial.indent();
|
||||||
|
serial.println("This is at indentation 2");
|
||||||
|
|
||||||
|
serial.println("You can print JSON here, as usual:");
|
||||||
|
serial.println(json);
|
||||||
|
serial.println();
|
||||||
|
|
||||||
|
serial.println("But you can also prettyPrint JSON here:");
|
||||||
|
json.prettyPrintTo(serial);
|
||||||
|
serial.println();
|
||||||
|
|
||||||
|
serial.unindent();
|
||||||
|
serial.unindent();
|
||||||
|
serial.println("This is back at indentation 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -21,6 +21,9 @@ void setup()
|
|||||||
root["data"] = array;
|
root["data"] = array;
|
||||||
|
|
||||||
Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
Serial.print(root); // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]}
|
||||||
|
|
||||||
|
Serial.println();
|
||||||
|
root.prettyPrintTo(Serial); // same string indented
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop()
|
void loop()
|
||||||
|
Reference in New Issue
Block a user