mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-07-14 19:16:35 +02:00
Renamed function RawJson()
to serialized()
This commit is contained in:
18
CHANGELOG.md
18
CHANGELOG.md
@ -6,11 +6,29 @@ HEAD
|
|||||||
|
|
||||||
* Disabled lazy number deserialization (issue #772)
|
* Disabled lazy number deserialization (issue #772)
|
||||||
* Improved float serialization when `-fsingle-precision-constant` is used
|
* Improved float serialization when `-fsingle-precision-constant` is used
|
||||||
|
* Renamed function `RawJson()` to `serialized()`
|
||||||
|
* `serializeMsgPack()` now supports values marked with `serialized()`
|
||||||
|
|
||||||
> ### BREAKING CHANGES
|
> ### BREAKING CHANGES
|
||||||
>
|
>
|
||||||
|
> #### Non quoted strings
|
||||||
|
>
|
||||||
> Non quoted strings are now forbidden in values, but they are still allowed in keys.
|
> Non quoted strings are now forbidden in values, but they are still allowed in keys.
|
||||||
> For example, `{key:"value"}` is accepted, but `{key:value}` is not.
|
> For example, `{key:"value"}` is accepted, but `{key:value}` is not.
|
||||||
|
>
|
||||||
|
> #### Preformatted values
|
||||||
|
>
|
||||||
|
> Old code:
|
||||||
|
>
|
||||||
|
> ```c++
|
||||||
|
> object["values"] = RawJson("[1,2,3,4]");
|
||||||
|
> ```
|
||||||
|
>
|
||||||
|
> New code:
|
||||||
|
>
|
||||||
|
> ```c++
|
||||||
|
> object["values"] = serialized("[1,2,3,4]");
|
||||||
|
> ```
|
||||||
|
|
||||||
v6.1.0-beta
|
v6.1.0-beta
|
||||||
-----------
|
-----------
|
||||||
|
@ -37,8 +37,9 @@ void setup() {
|
|||||||
// JsonBuffer.
|
// JsonBuffer.
|
||||||
obj["sensor"] = F("gps");
|
obj["sensor"] = F("gps");
|
||||||
|
|
||||||
// It works with RawJson too:
|
// It works with serialized() too:
|
||||||
obj["sensor"] = RawJson(F("\"gps\""));
|
obj["sensor"] = serialized(F("\"gps\""));
|
||||||
|
obj["sensor"] = serialized(F("\xA3gps"), 3);
|
||||||
|
|
||||||
// You can compare the content of a JsonVariant to a Flash String
|
// You can compare the content of a JsonVariant to a Flash String
|
||||||
if (obj["sensor"] == F("gps")) {
|
if (obj["sensor"] == F("gps")) {
|
||||||
|
@ -41,8 +41,8 @@ void setup() {
|
|||||||
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
||||||
obj["sensor"] = sensor;
|
obj["sensor"] = sensor;
|
||||||
|
|
||||||
// It works with RawJson too:
|
// It works with serialized() too:
|
||||||
obj["sensor"] = RawJson(sensor);
|
obj["sensor"] = serialized(sensor);
|
||||||
|
|
||||||
// You can also concatenate strings
|
// You can also concatenate strings
|
||||||
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
// WARNING: the content of the String will be duplicated in the JsonBuffer.
|
||||||
|
@ -18,9 +18,13 @@ struct JsonObjectData;
|
|||||||
union JsonVariantContent {
|
union JsonVariantContent {
|
||||||
JsonFloat asFloat; // used for double and float
|
JsonFloat asFloat; // used for double and float
|
||||||
JsonUInt asInteger; // used for bool, char, short, int and longs
|
JsonUInt asInteger; // used for bool, char, short, int and longs
|
||||||
const char* asString; // asString can be null
|
|
||||||
JsonArrayData* asArray; // asArray cannot be null
|
JsonArrayData* asArray; // asArray cannot be null
|
||||||
JsonObjectData* asObject; // asObject cannot be null
|
JsonObjectData* asObject; // asObject cannot be null
|
||||||
|
const char* asString; // asString can be null
|
||||||
|
struct {
|
||||||
|
const char* data;
|
||||||
|
size_t size;
|
||||||
|
} asRaw;
|
||||||
};
|
};
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "../JsonVariant.hpp"
|
#include "../JsonVariant.hpp"
|
||||||
#include "../Memory/JsonBuffer.hpp"
|
#include "../Memory/JsonBuffer.hpp"
|
||||||
#include "../Polyfills/type_traits.hpp"
|
#include "../Polyfills/type_traits.hpp"
|
||||||
#include "../Strings/StringTraits.hpp"
|
#include "../Strings/StringTypes.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -21,30 +21,31 @@ struct ValueSaver {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Source>
|
// We duplicate all strings except const char*
|
||||||
|
template <typename TString>
|
||||||
struct ValueSaver<
|
struct ValueSaver<
|
||||||
Source, typename enable_if<StringTraits<Source>::should_duplicate>::type> {
|
TString, typename enable_if<IsString<TString>::value &&
|
||||||
|
!is_same<const char*, TString>::value>::type> {
|
||||||
template <typename Destination>
|
template <typename Destination>
|
||||||
static bool save(JsonBuffer* buffer, Destination& dest, Source source) {
|
static bool save(JsonBuffer* buffer, Destination& dest, TString source) {
|
||||||
if (!StringTraits<Source>::is_null(source)) {
|
const char* dup = makeString(source).save(buffer);
|
||||||
typename StringTraits<Source>::duplicate_t dup =
|
if (!dup) return false;
|
||||||
StringTraits<Source>::duplicate(source, buffer);
|
dest = dup;
|
||||||
if (!dup) return false;
|
|
||||||
dest = dup;
|
|
||||||
} else {
|
|
||||||
dest = reinterpret_cast<const char*>(0);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// const char*, const signed char*, const unsigned char*
|
// We duplicate all SerializedValue<T> except SerializedValue<const char*>
|
||||||
template <typename Char>
|
template <typename TString>
|
||||||
struct ValueSaver<
|
struct ValueSaver<
|
||||||
Char*, typename enable_if<!StringTraits<Char*>::should_duplicate>::type> {
|
const SerializedValue<TString>&,
|
||||||
|
typename enable_if<!is_same<const char*, TString>::value>::type> {
|
||||||
template <typename Destination>
|
template <typename Destination>
|
||||||
static bool save(JsonBuffer*, Destination& dest, Char* source) {
|
static bool save(JsonBuffer* buffer, Destination& dest,
|
||||||
dest = reinterpret_cast<const char*>(source);
|
const SerializedValue<TString>& source) {
|
||||||
|
const char* dup = makeString(source.data(), source.size()).save(buffer);
|
||||||
|
if (!dup) return false;
|
||||||
|
dest = SerializedValue<const char*>(dup, source.size());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -19,19 +19,22 @@ class IndentedPrint {
|
|||||||
isNewLine = true;
|
isNewLine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(char c) {
|
size_t write(uint8_t c) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
if (isNewLine) n += writeTabs();
|
if (isNewLine) n += writeTabs();
|
||||||
n += sink->print(c);
|
n += sink->write(c);
|
||||||
isNewLine = c == '\n';
|
isNewLine = c == '\n';
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(const char *s) {
|
size_t write(const uint8_t *s, size_t n) {
|
||||||
// TODO: optimize
|
// TODO: optimize
|
||||||
size_t n = 0;
|
size_t bytesWritten = 0;
|
||||||
while (*s) n += print(*s++);
|
while (n > 0) {
|
||||||
return n;
|
bytesWritten += write(*s++);
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds one level of indentation
|
// Adds one level of indentation
|
||||||
@ -57,7 +60,7 @@ class IndentedPrint {
|
|||||||
|
|
||||||
size_t writeTabs() {
|
size_t writeTabs() {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
for (int i = 0; i < level * tabSize; i++) n += sink->print(' ');
|
for (int i = 0; i < level * tabSize; i++) n += sink->write(' ');
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,10 +11,10 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
template <typename TPrint>
|
template <typename TWriter>
|
||||||
class JsonSerializer {
|
class JsonSerializer {
|
||||||
public:
|
public:
|
||||||
JsonSerializer(TPrint &destination) : _writer(destination) {}
|
JsonSerializer(TWriter &writer) : _writer(writer) {}
|
||||||
|
|
||||||
void acceptFloat(JsonFloat value) {
|
void acceptFloat(JsonFloat value) {
|
||||||
_writer.writeFloat(value);
|
_writer.writeFloat(value);
|
||||||
@ -58,8 +58,9 @@ class JsonSerializer {
|
|||||||
_writer.writeString(value);
|
_writer.writeString(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void acceptRawJson(const char *value) {
|
void acceptRawJson(const char *data, size_t n) {
|
||||||
_writer.writeRaw(value);
|
// TODO
|
||||||
|
for (size_t i = 0; i < n; i++) _writer.writeRaw(data[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void acceptNegativeInteger(JsonUInt value) {
|
void acceptNegativeInteger(JsonUInt value) {
|
||||||
@ -84,7 +85,7 @@ class JsonSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
JsonWriter<TPrint> _writer;
|
JsonWriter<TWriter> _writer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <string.h> // for strlen
|
||||||
#include "../Data/JsonInteger.hpp"
|
#include "../Data/JsonInteger.hpp"
|
||||||
#include "../Numbers/FloatParts.hpp"
|
#include "../Numbers/FloatParts.hpp"
|
||||||
#include "../Polyfills/attributes.hpp"
|
#include "../Polyfills/attributes.hpp"
|
||||||
@ -13,12 +14,12 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
template <typename Print>
|
template <typename TWriter>
|
||||||
class JsonWriter {
|
class JsonWriter {
|
||||||
public:
|
public:
|
||||||
explicit JsonWriter(Print &sink) : _sink(sink), _length(0) {}
|
explicit JsonWriter(TWriter &writer) : _writer(writer), _length(0) {}
|
||||||
|
|
||||||
// Returns the number of bytes sent to the Print implementation.
|
// Returns the number of bytes sent to the TWriter implementation.
|
||||||
size_t bytesWritten() const {
|
size_t bytesWritten() const {
|
||||||
return _length;
|
return _length;
|
||||||
}
|
}
|
||||||
@ -45,7 +46,10 @@ class JsonWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void writeBoolean(bool value) {
|
void writeBoolean(bool value) {
|
||||||
writeRaw(value ? "true" : "false");
|
if (value)
|
||||||
|
writeRaw("true");
|
||||||
|
else
|
||||||
|
writeRaw("false");
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeString(const char *value) {
|
void writeString(const char *value) {
|
||||||
@ -98,45 +102,53 @@ class JsonWriter {
|
|||||||
template <typename UInt>
|
template <typename UInt>
|
||||||
void writeInteger(UInt value) {
|
void writeInteger(UInt value) {
|
||||||
char buffer[22];
|
char buffer[22];
|
||||||
char *end = buffer + sizeof(buffer) - 1;
|
char *end = buffer + sizeof(buffer);
|
||||||
char *ptr = end;
|
char *begin = end;
|
||||||
|
|
||||||
*ptr = 0;
|
// write the string in reverse order
|
||||||
do {
|
do {
|
||||||
*--ptr = char(value % 10 + '0');
|
*--begin = char(value % 10 + '0');
|
||||||
value = UInt(value / 10);
|
value = UInt(value / 10);
|
||||||
} while (value);
|
} while (value);
|
||||||
|
|
||||||
writeRaw(ptr);
|
// and dump it in the right order
|
||||||
|
writeRaw(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeDecimals(uint32_t value, int8_t width) {
|
void writeDecimals(uint32_t value, int8_t width) {
|
||||||
// buffer should be big enough for all digits, the dot and the null
|
// buffer should be big enough for all digits and the dot
|
||||||
// terminator
|
|
||||||
char buffer[16];
|
char buffer[16];
|
||||||
char *ptr = buffer + sizeof(buffer) - 1;
|
char *end = buffer + sizeof(buffer);
|
||||||
|
char *begin = end;
|
||||||
|
|
||||||
// write the string in reverse order
|
// write the string in reverse order
|
||||||
*ptr = 0;
|
|
||||||
while (width--) {
|
while (width--) {
|
||||||
*--ptr = char(value % 10 + '0');
|
*--begin = char(value % 10 + '0');
|
||||||
value /= 10;
|
value /= 10;
|
||||||
}
|
}
|
||||||
*--ptr = '.';
|
*--begin = '.';
|
||||||
|
|
||||||
// and dump it in the right order
|
// and dump it in the right order
|
||||||
writeRaw(ptr);
|
writeRaw(begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeRaw(const char *s) {
|
void writeRaw(const char *s) {
|
||||||
_length += _sink.print(s);
|
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), strlen(s));
|
||||||
|
}
|
||||||
|
void writeRaw(const char *begin, const char *end) {
|
||||||
|
_length += _writer.write(reinterpret_cast<const uint8_t *>(begin),
|
||||||
|
static_cast<size_t>(end - begin));
|
||||||
|
}
|
||||||
|
template <size_t N>
|
||||||
|
void writeRaw(const char (&s)[N]) {
|
||||||
|
_length += _writer.write(reinterpret_cast<const uint8_t *>(s), N - 1);
|
||||||
}
|
}
|
||||||
void writeRaw(char c) {
|
void writeRaw(char c) {
|
||||||
_length += _sink.print(c);
|
_length += _writer.write(static_cast<uint8_t>(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Print &_sink;
|
TWriter &_writer;
|
||||||
size_t _length;
|
size_t _length;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -10,25 +10,28 @@ namespace ArduinoJson {
|
|||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
// Converts a compact JSON string into an indented one.
|
// Converts a compact JSON string into an indented one.
|
||||||
template <typename Print>
|
template <typename TWriter>
|
||||||
class Prettyfier {
|
class Prettyfier {
|
||||||
public:
|
public:
|
||||||
explicit Prettyfier(IndentedPrint<Print>& p) : _sink(p) {
|
explicit Prettyfier(IndentedPrint<TWriter>& p) : _sink(p) {
|
||||||
_previousChar = 0;
|
_previousChar = 0;
|
||||||
_inString = false;
|
_inString = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(char c) {
|
size_t write(uint8_t c) {
|
||||||
size_t n = _inString ? handleStringChar(c) : handleMarkupChar(c);
|
size_t n = _inString ? handleStringChar(c) : handleMarkupChar(char(c));
|
||||||
_previousChar = c;
|
_previousChar = char(c);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(const char* s) {
|
size_t write(const uint8_t* s, size_t n) {
|
||||||
// TODO: optimize
|
// TODO: optimize
|
||||||
size_t n = 0;
|
size_t bytesWritten = 0;
|
||||||
while (*s) n += print(*s++);
|
while (n > 0) {
|
||||||
return n;
|
bytesWritten += write(*s++);
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
return bytesWritten;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -38,12 +41,12 @@ class Prettyfier {
|
|||||||
return _previousChar == '{' || _previousChar == '[';
|
return _previousChar == '{' || _previousChar == '[';
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t handleStringChar(char c) {
|
size_t handleStringChar(uint8_t c) {
|
||||||
bool isQuote = c == '"' && _previousChar != '\\';
|
bool isQuote = c == '"' && _previousChar != '\\';
|
||||||
|
|
||||||
if (isQuote) _inString = false;
|
if (isQuote) _inString = false;
|
||||||
|
|
||||||
return _sink.print(c);
|
return _sink.write(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t handleMarkupChar(char c) {
|
size_t handleMarkupChar(char c) {
|
||||||
@ -73,26 +76,26 @@ class Prettyfier {
|
|||||||
size_t writeBlockClose(char c) {
|
size_t writeBlockClose(char c) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
n += unindentIfNeeded();
|
n += unindentIfNeeded();
|
||||||
n += _sink.print(c);
|
n += write(c);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeBlockOpen(char c) {
|
size_t writeBlockOpen(char c) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
n += indentIfNeeded();
|
n += indentIfNeeded();
|
||||||
n += _sink.print(c);
|
n += write(c);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeColon() {
|
size_t writeColon() {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
n += _sink.print(": ");
|
n += write(": ");
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeComma() {
|
size_t writeComma() {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
n += _sink.print(",\r\n");
|
n += write(",\r\n");
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,14 +103,14 @@ class Prettyfier {
|
|||||||
_inString = true;
|
_inString = true;
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
n += indentIfNeeded();
|
n += indentIfNeeded();
|
||||||
n += _sink.print('"');
|
n += write('"');
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeNormalChar(char c) {
|
size_t writeNormalChar(char c) {
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
n += indentIfNeeded();
|
n += indentIfNeeded();
|
||||||
n += _sink.print(c);
|
n += write(c);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,19 +118,28 @@ class Prettyfier {
|
|||||||
if (!inEmptyBlock()) return 0;
|
if (!inEmptyBlock()) return 0;
|
||||||
|
|
||||||
_sink.indent();
|
_sink.indent();
|
||||||
return _sink.print("\r\n");
|
return write("\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t unindentIfNeeded() {
|
size_t unindentIfNeeded() {
|
||||||
if (inEmptyBlock()) return 0;
|
if (inEmptyBlock()) return 0;
|
||||||
|
|
||||||
_sink.unindent();
|
_sink.unindent();
|
||||||
return _sink.print("\r\n");
|
return write("\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t write(char c) {
|
||||||
|
return _sink.write(static_cast<uint8_t>(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
size_t write(const char (&s)[N]) {
|
||||||
|
return _sink.write(reinterpret_cast<const uint8_t*>(s), N - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
char _previousChar;
|
char _previousChar;
|
||||||
IndentedPrint<Print>& _sink;
|
IndentedPrint<TWriter>& _sink;
|
||||||
bool _inString;
|
bool _inString;
|
||||||
};
|
};
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
||||||
|
@ -29,7 +29,7 @@ class JsonArray {
|
|||||||
// Adds the specified value at the end of the array.
|
// Adds the specified value at the end of the array.
|
||||||
//
|
//
|
||||||
// bool add(TValue);
|
// bool add(TValue);
|
||||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
// TValue = bool, long, int, short, float, double, serialized, JsonVariant,
|
||||||
// std::string, String, JsonArrayData, JsonObject
|
// std::string, String, JsonArrayData, JsonObject
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool add(const T& value) {
|
bool add(const T& value) {
|
||||||
@ -154,7 +154,7 @@ class JsonArray {
|
|||||||
// Sets the value at specified index.
|
// Sets the value at specified index.
|
||||||
//
|
//
|
||||||
// bool add(size_t index, const TValue&);
|
// bool add(size_t index, const TValue&);
|
||||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
// TValue = bool, long, int, short, float, double, serialized, JsonVariant,
|
||||||
// std::string, String, JsonArrayData, JsonObject
|
// std::string, String, JsonArrayData, JsonObject
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool set(size_t index, const T& value) {
|
bool set(size_t index, const T& value) {
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "JsonVariant.hpp"
|
#include "JsonVariant.hpp"
|
||||||
#include "Memory/JsonBufferAllocated.hpp"
|
#include "Memory/JsonBufferAllocated.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
#include "Strings/StringTraits.hpp"
|
|
||||||
|
|
||||||
// Returns the size (in bytes) of an array with n elements.
|
// Returns the size (in bytes) of an array with n elements.
|
||||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||||
|
@ -27,7 +27,7 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
|||||||
// Replaces the value
|
// Replaces the value
|
||||||
//
|
//
|
||||||
// operator=(const TValue&)
|
// operator=(const TValue&)
|
||||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
// TValue = bool, long, int, short, float, double, serialized, JsonVariant,
|
||||||
// std::string, String, JsonArray, JsonObject
|
// std::string, String, JsonArray, JsonObject
|
||||||
template <typename T>
|
template <typename T>
|
||||||
FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
|
FORCE_INLINE JsonArraySubscript& operator=(const T& src) {
|
||||||
@ -60,7 +60,7 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> {
|
|||||||
// Replaces the value
|
// Replaces the value
|
||||||
//
|
//
|
||||||
// bool set(const TValue&)
|
// bool set(const TValue&)
|
||||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
// TValue = bool, long, int, short, float, double, serialized, JsonVariant,
|
||||||
// std::string, String, JsonArray, JsonObject
|
// std::string, String, JsonArray, JsonObject
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE bool set(const TValue& value) {
|
FORCE_INLINE bool set(const TValue& value) {
|
||||||
|
@ -188,7 +188,7 @@ class JsonObject {
|
|||||||
//
|
//
|
||||||
// bool set(TKey, TValue);
|
// bool set(TKey, TValue);
|
||||||
// TKey = const std::string&, const String&
|
// TKey = const std::string&, const String&
|
||||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
// TValue = bool, long, int, short, float, double, serialized, JsonVariant,
|
||||||
// std::string, String, JsonArray, JsonObject
|
// std::string, String, JsonArray, JsonObject
|
||||||
template <typename TValue, typename TString>
|
template <typename TValue, typename TString>
|
||||||
bool set(const TString& key, const TValue& value) {
|
bool set(const TString& key, const TValue& value) {
|
||||||
@ -205,7 +205,7 @@ class JsonObject {
|
|||||||
//
|
//
|
||||||
// bool set(TKey, const TValue&);
|
// bool set(TKey, const TValue&);
|
||||||
// TKey = char*, const char*, const FlashStringHelper*
|
// TKey = char*, const char*, const FlashStringHelper*
|
||||||
// TValue = bool, long, int, short, float, double, RawJson, JsonVariant,
|
// TValue = bool, long, int, short, float, double, serialized, JsonVariant,
|
||||||
// std::string, String, JsonArray, JsonObject
|
// std::string, String, JsonArray, JsonObject
|
||||||
template <typename TValue, typename TString>
|
template <typename TValue, typename TString>
|
||||||
bool set(TString* key, const TValue& value) {
|
bool set(TString* key, const TValue& value) {
|
||||||
@ -254,7 +254,7 @@ class JsonObject {
|
|||||||
iterator findKey(TStringRef key) {
|
iterator findKey(TStringRef key) {
|
||||||
iterator it;
|
iterator it;
|
||||||
for (it = begin(); it != end(); ++it) {
|
for (it = begin(); it != end(); ++it) {
|
||||||
if (Internals::StringTraits<TStringRef>::equals(key, it->key)) break;
|
if (Internals::makeString(key).equals(it->key)) break;
|
||||||
}
|
}
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
@ -288,7 +288,7 @@ class JsonObject {
|
|||||||
if (!_data) return false;
|
if (!_data) return false;
|
||||||
|
|
||||||
// ignore null key
|
// ignore null key
|
||||||
if (Internals::StringTraits<TStringRef>::is_null(key)) return false;
|
if (Internals::makeString(key).is_null()) return false;
|
||||||
|
|
||||||
// search a matching key
|
// search a matching key
|
||||||
iterator it = findKey<TStringRef>(key);
|
iterator it = findKey<TStringRef>(key);
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include "JsonPair.hpp"
|
#include "JsonPair.hpp"
|
||||||
#include "Memory/JsonBufferAllocated.hpp"
|
#include "Memory/JsonBufferAllocated.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
#include "Strings/StringTraits.hpp"
|
|
||||||
|
|
||||||
// Returns the size (in bytes) of an object with n elements.
|
// Returns the size (in bytes) of an object with n elements.
|
||||||
// Can be very handy to determine the size of a StaticJsonBuffer.
|
// Can be very handy to determine the size of a StaticJsonBuffer.
|
||||||
|
@ -67,7 +67,8 @@ class JsonObjectSubscript
|
|||||||
// Sets the specified value.
|
// Sets the specified value.
|
||||||
//
|
//
|
||||||
// bool set(const TValue&);
|
// bool set(const TValue&);
|
||||||
// TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant,
|
// TValue = bool, char, long, int, short, float, double, serialized,
|
||||||
|
// JsonVariant,
|
||||||
// std::string, String, JsonArray, JsonObject
|
// std::string, String, JsonArray, JsonObject
|
||||||
template <typename TValue>
|
template <typename TValue>
|
||||||
FORCE_INLINE typename enable_if<!is_array<TValue>::value, bool>::type set(
|
FORCE_INLINE typename enable_if<!is_array<TValue>::value, bool>::type set(
|
||||||
@ -94,7 +95,7 @@ class JsonObjectSubscript
|
|||||||
|
|
||||||
template <typename TImpl>
|
template <typename TImpl>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline typename enable_if<StringTraits<TString>::has_equals,
|
inline typename enable_if<IsString<TString>::value,
|
||||||
const JsonObjectSubscript<const TString &> >::type
|
const JsonObjectSubscript<const TString &> >::type
|
||||||
JsonVariantSubscripts<TImpl>::operator[](const TString &key) const {
|
JsonVariantSubscripts<TImpl>::operator[](const TString &key) const {
|
||||||
return impl()->template as<JsonObject>()[key];
|
return impl()->template as<JsonObject>()[key];
|
||||||
@ -102,7 +103,7 @@ inline typename enable_if<StringTraits<TString>::has_equals,
|
|||||||
|
|
||||||
template <typename TImpl>
|
template <typename TImpl>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline typename enable_if<StringTraits<TString>::has_equals,
|
inline typename enable_if<IsString<TString>::value,
|
||||||
JsonObjectSubscript<const TString &> >::type
|
JsonObjectSubscript<const TString &> >::type
|
||||||
JsonVariantSubscripts<TImpl>::operator[](const TString &key) {
|
JsonVariantSubscripts<TImpl>::operator[](const TString &key) {
|
||||||
return impl()->template as<JsonObject>()[key];
|
return impl()->template as<JsonObject>()[key];
|
||||||
@ -110,7 +111,7 @@ inline typename enable_if<StringTraits<TString>::has_equals,
|
|||||||
|
|
||||||
template <typename TImpl>
|
template <typename TImpl>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline typename enable_if<StringTraits<const TString *>::has_equals,
|
inline typename enable_if<IsString<const TString *>::value,
|
||||||
JsonObjectSubscript<const TString *> >::type
|
JsonObjectSubscript<const TString *> >::type
|
||||||
JsonVariantSubscripts<TImpl>::operator[](const TString *key) {
|
JsonVariantSubscripts<TImpl>::operator[](const TString *key) {
|
||||||
return impl()->template as<JsonObject>()[key];
|
return impl()->template as<JsonObject>()[key];
|
||||||
@ -118,7 +119,7 @@ inline typename enable_if<StringTraits<const TString *>::has_equals,
|
|||||||
|
|
||||||
template <typename TImpl>
|
template <typename TImpl>
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
inline typename enable_if<StringTraits<TString *>::has_equals,
|
inline typename enable_if<IsString<TString *>::value,
|
||||||
const JsonObjectSubscript<const TString *> >::type
|
const JsonObjectSubscript<const TString *> >::type
|
||||||
JsonVariantSubscripts<TImpl>::operator[](const TString *key) const {
|
JsonVariantSubscripts<TImpl>::operator[](const TString *key) const {
|
||||||
return impl()->template as<JsonObject>()[key];
|
return impl()->template as<JsonObject>()[key];
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
#include "Data/JsonVariantType.hpp"
|
#include "Data/JsonVariantType.hpp"
|
||||||
#include "JsonVariantBase.hpp"
|
#include "JsonVariantBase.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
#include "RawJson.hpp"
|
#include "Serialization/DynamicStringWriter.hpp"
|
||||||
|
#include "SerializedValue.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
|
|
||||||
@ -99,9 +100,10 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a JsonVariant containing an unparsed string
|
// Create a JsonVariant containing an unparsed string
|
||||||
JsonVariant(Internals::RawJsonString<const char *> value) {
|
JsonVariant(Internals::SerializedValue<const char *> value) {
|
||||||
_type = Internals::JSON_UNPARSED;
|
_type = Internals::JSON_UNPARSED;
|
||||||
_content.asString = value;
|
_content.asRaw.data = value.data();
|
||||||
|
_content.asRaw.size = value.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonVariant(JsonArray array);
|
JsonVariant(JsonArray array);
|
||||||
@ -153,7 +155,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
// std::string as<std::string>() const;
|
// std::string as<std::string>() const;
|
||||||
// String as<String>() const;
|
// String as<String>() const;
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename Internals::enable_if<Internals::StringTraits<T>::has_append, T>::type
|
typename Internals::enable_if<Internals::IsWriteableString<T>::value, T>::type
|
||||||
as() const {
|
as() const {
|
||||||
const char *cstr = variantAsString();
|
const char *cstr = variantAsString();
|
||||||
if (cstr) return T(cstr);
|
if (cstr) return T(cstr);
|
||||||
@ -276,7 +278,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
return visitor.acceptString(_content.asString);
|
return visitor.acceptString(_content.asString);
|
||||||
|
|
||||||
case JSON_UNPARSED:
|
case JSON_UNPARSED:
|
||||||
return visitor.acceptRawJson(_content.asString);
|
return visitor.acceptRawJson(_content.asRaw.data, _content.asRaw.size);
|
||||||
|
|
||||||
case JSON_NEGATIVE_INTEGER:
|
case JSON_NEGATIVE_INTEGER:
|
||||||
return visitor.acceptNegativeInteger(_content.asInteger);
|
return visitor.acceptNegativeInteger(_content.asInteger);
|
||||||
@ -310,9 +312,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> {
|
|||||||
return _type == Internals::JSON_OBJECT;
|
return _type == Internals::JSON_OBJECT;
|
||||||
}
|
}
|
||||||
bool variantIsString() const {
|
bool variantIsString() const {
|
||||||
return _type == Internals::JSON_STRING ||
|
return _type == Internals::JSON_STRING;
|
||||||
(_type == Internals::JSON_UNPARSED && _content.asString &&
|
|
||||||
!strcmp("null", _content.asString));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The current type of the variant
|
// The current type of the variant
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "Data/IsVariant.hpp"
|
#include "Data/IsVariant.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
#include "Strings/StringTraits.hpp"
|
#include "Strings/StringTypes.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
class JsonArray;
|
class JsonArray;
|
||||||
@ -104,16 +104,14 @@ class JsonVariantComparisons {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
typename enable_if<StringTraits<TString>::has_equals, bool>::type equals(
|
typename enable_if<IsString<TString>::value, bool>::type equals(
|
||||||
const TString &comparand) const {
|
const TString &comparand) const {
|
||||||
const char *value = as<const char *>();
|
return makeString(comparand).equals(as<const char *>());
|
||||||
return StringTraits<TString>::equals(comparand, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TComparand>
|
template <typename TComparand>
|
||||||
typename enable_if<!IsVariant<TComparand>::value &&
|
typename enable_if<
|
||||||
!StringTraits<TComparand>::has_equals,
|
!IsVariant<TComparand>::value && !IsString<TComparand>::value, bool>::type
|
||||||
bool>::type
|
|
||||||
equals(const TComparand &comparand) const {
|
equals(const TComparand &comparand) const {
|
||||||
return as<TComparand>() == comparand;
|
return as<TComparand>() == comparand;
|
||||||
}
|
}
|
||||||
@ -132,8 +130,7 @@ class JsonVariantComparisons {
|
|||||||
if (is<JsonObject>() && right.template is<JsonObject>())
|
if (is<JsonObject>() && right.template is<JsonObject>())
|
||||||
return as<JsonObject>() == right.template as<JsonObject>();
|
return as<JsonObject>() == right.template as<JsonObject>();
|
||||||
if (is<char *>() && right.template is<char *>())
|
if (is<char *>() && right.template is<char *>())
|
||||||
return StringTraits<const char *>::equals(as<char *>(),
|
return makeString(as<char *>()).equals(right.template as<char *>());
|
||||||
right.template as<char *>());
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,7 @@ inline T JsonVariant::variantAsInteger() const {
|
|||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case JSON_UNDEFINED:
|
case JSON_UNDEFINED:
|
||||||
|
case JSON_UNPARSED:
|
||||||
return 0;
|
return 0;
|
||||||
case JSON_POSITIVE_INTEGER:
|
case JSON_POSITIVE_INTEGER:
|
||||||
case JSON_BOOLEAN:
|
case JSON_BOOLEAN:
|
||||||
@ -75,7 +76,6 @@ inline T JsonVariant::variantAsInteger() const {
|
|||||||
case JSON_NEGATIVE_INTEGER:
|
case JSON_NEGATIVE_INTEGER:
|
||||||
return T(~_content.asInteger + 1);
|
return T(~_content.asInteger + 1);
|
||||||
case JSON_STRING:
|
case JSON_STRING:
|
||||||
case JSON_UNPARSED:
|
|
||||||
return parseInteger<T>(_content.asString);
|
return parseInteger<T>(_content.asString);
|
||||||
default:
|
default:
|
||||||
return T(_content.asFloat);
|
return T(_content.asFloat);
|
||||||
@ -84,11 +84,7 @@ inline T JsonVariant::variantAsInteger() const {
|
|||||||
|
|
||||||
inline const char *JsonVariant::variantAsString() const {
|
inline const char *JsonVariant::variantAsString() const {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
if (_type == JSON_UNPARSED && _content.asString &&
|
return _type == JSON_STRING ? _content.asString : NULL;
|
||||||
!strcmp("null", _content.asString))
|
|
||||||
return NULL;
|
|
||||||
if (_type == JSON_STRING || _type == JSON_UNPARSED) return _content.asString;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -96,6 +92,7 @@ inline T JsonVariant::variantAsFloat() const {
|
|||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
switch (_type) {
|
switch (_type) {
|
||||||
case JSON_UNDEFINED:
|
case JSON_UNDEFINED:
|
||||||
|
case JSON_UNPARSED:
|
||||||
return 0;
|
return 0;
|
||||||
case JSON_POSITIVE_INTEGER:
|
case JSON_POSITIVE_INTEGER:
|
||||||
case JSON_BOOLEAN:
|
case JSON_BOOLEAN:
|
||||||
@ -103,7 +100,6 @@ inline T JsonVariant::variantAsFloat() const {
|
|||||||
case JSON_NEGATIVE_INTEGER:
|
case JSON_NEGATIVE_INTEGER:
|
||||||
return -static_cast<T>(_content.asInteger);
|
return -static_cast<T>(_content.asInteger);
|
||||||
case JSON_STRING:
|
case JSON_STRING:
|
||||||
case JSON_UNPARSED:
|
|
||||||
return parseFloat<T>(_content.asString);
|
return parseFloat<T>(_content.asString);
|
||||||
default:
|
default:
|
||||||
return static_cast<T>(_content.asFloat);
|
return static_cast<T>(_content.asFloat);
|
||||||
@ -112,27 +108,20 @@ inline T JsonVariant::variantAsFloat() const {
|
|||||||
|
|
||||||
inline bool JsonVariant::variantIsBoolean() const {
|
inline bool JsonVariant::variantIsBoolean() const {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
if (_type == JSON_BOOLEAN) return true;
|
return _type == JSON_BOOLEAN;
|
||||||
|
|
||||||
if (_type != JSON_UNPARSED || _content.asString == NULL) return false;
|
|
||||||
|
|
||||||
return !strcmp(_content.asString, "true") ||
|
|
||||||
!strcmp(_content.asString, "false");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool JsonVariant::variantIsInteger() const {
|
inline bool JsonVariant::variantIsInteger() const {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
|
|
||||||
return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER ||
|
return _type == JSON_POSITIVE_INTEGER || _type == JSON_NEGATIVE_INTEGER;
|
||||||
(_type == JSON_UNPARSED && isInteger(_content.asString));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool JsonVariant::variantIsFloat() const {
|
inline bool JsonVariant::variantIsFloat() const {
|
||||||
using namespace Internals;
|
using namespace Internals;
|
||||||
|
|
||||||
return _type == JSON_FLOAT || _type == JSON_POSITIVE_INTEGER ||
|
return _type == JSON_FLOAT || _type == JSON_POSITIVE_INTEGER ||
|
||||||
_type == JSON_NEGATIVE_INTEGER ||
|
_type == JSON_NEGATIVE_INTEGER;
|
||||||
(_type == JSON_UNPARSED && isFloat(_content.asString));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ArduinoJson
|
} // namespace ArduinoJson
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "Data/JsonVariantAs.hpp"
|
#include "Data/JsonVariantAs.hpp"
|
||||||
#include "Polyfills/attributes.hpp"
|
#include "Polyfills/attributes.hpp"
|
||||||
#include "Polyfills/type_traits.hpp"
|
#include "Polyfills/type_traits.hpp"
|
||||||
#include "Strings/StringTraits.hpp"
|
#include "Strings/StringTypes.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
class JsonArray;
|
class JsonArray;
|
||||||
@ -43,21 +43,21 @@ class JsonVariantSubscripts {
|
|||||||
// TKey = const std::string&, const String&
|
// TKey = const std::string&, const String&
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
typename enable_if<StringTraits<TString>::has_equals,
|
typename enable_if<IsString<TString>::value,
|
||||||
const JsonObjectSubscript<const TString &> >::type
|
const JsonObjectSubscript<const TString &> >::type
|
||||||
operator[](const TString &key) const;
|
operator[](const TString &key) const;
|
||||||
//
|
//
|
||||||
// const JsonObjectSubscript operator[](TKey) const;
|
// const JsonObjectSubscript operator[](TKey) const;
|
||||||
// TKey = const std::string&, const String&
|
// TKey = const std::string&, const String&
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE typename enable_if<StringTraits<TString>::has_equals,
|
FORCE_INLINE typename enable_if<IsString<TString>::value,
|
||||||
JsonObjectSubscript<const TString &> >::type
|
JsonObjectSubscript<const TString &> >::type
|
||||||
operator[](const TString &key);
|
operator[](const TString &key);
|
||||||
//
|
//
|
||||||
// JsonObjectSubscript operator[](TKey);
|
// JsonObjectSubscript operator[](TKey);
|
||||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE typename enable_if<StringTraits<const TString *>::has_equals,
|
FORCE_INLINE typename enable_if<IsString<const TString *>::value,
|
||||||
JsonObjectSubscript<const TString *> >::type
|
JsonObjectSubscript<const TString *> >::type
|
||||||
operator[](const TString *key);
|
operator[](const TString *key);
|
||||||
//
|
//
|
||||||
@ -65,7 +65,7 @@ class JsonVariantSubscripts {
|
|||||||
// TKey = const char*, const char[N], const FlashStringHelper*
|
// TKey = const char*, const char[N], const FlashStringHelper*
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
FORCE_INLINE
|
FORCE_INLINE
|
||||||
typename enable_if<StringTraits<TString *>::has_equals,
|
typename enable_if<IsString<TString *>::value,
|
||||||
const JsonObjectSubscript<const TString *> >::type
|
const JsonObjectSubscript<const TString *> >::type
|
||||||
operator[](const TString *key) const;
|
operator[](const TString *key) const;
|
||||||
|
|
||||||
|
@ -13,10 +13,10 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
template <typename TPrint>
|
template <typename TWriter>
|
||||||
class MsgPackSerializer {
|
class MsgPackSerializer {
|
||||||
public:
|
public:
|
||||||
MsgPackSerializer(TPrint& output) : _output(&output), _bytesWritten(0) {}
|
MsgPackSerializer(TWriter& writer) : _writer(&writer), _bytesWritten(0) {}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
typename enable_if<sizeof(T) == 4>::type acceptFloat(T value32) {
|
typename enable_if<sizeof(T) == 4>::type acceptFloat(T value32) {
|
||||||
@ -91,7 +91,9 @@ class MsgPackSerializer {
|
|||||||
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
writeBytes(reinterpret_cast<const uint8_t*>(value), n);
|
||||||
}
|
}
|
||||||
|
|
||||||
void acceptRawJson(const char* /*value*/) {}
|
void acceptRawJson(const char* data, size_t size) {
|
||||||
|
writeBytes(reinterpret_cast<const uint8_t*>(data), size);
|
||||||
|
}
|
||||||
|
|
||||||
void acceptNegativeInteger(JsonUInt value) {
|
void acceptNegativeInteger(JsonUInt value) {
|
||||||
JsonUInt negated = JsonUInt(~value + 1);
|
JsonUInt negated = JsonUInt(~value + 1);
|
||||||
@ -150,12 +152,11 @@ class MsgPackSerializer {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void writeByte(uint8_t c) {
|
void writeByte(uint8_t c) {
|
||||||
_output->print(char(c));
|
_bytesWritten += _writer->write(c);
|
||||||
_bytesWritten++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeBytes(const uint8_t* c, size_t n) {
|
void writeBytes(const uint8_t* p, size_t n) {
|
||||||
for (; n > 0; --n, ++c) writeByte(*c);
|
_bytesWritten += _writer->write(p, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -164,7 +165,7 @@ class MsgPackSerializer {
|
|||||||
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
TPrint* _output;
|
TWriter* _writer;
|
||||||
size_t _bytesWritten;
|
size_t _bytesWritten;
|
||||||
};
|
};
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
|
||||||
|
|
||||||
namespace Internals {
|
|
||||||
// A special type of data that can be used to insert pregenerated JSON portions.
|
|
||||||
template <typename T>
|
|
||||||
class RawJsonString {
|
|
||||||
public:
|
|
||||||
explicit RawJsonString(T str) : _str(str) {}
|
|
||||||
operator T() const {
|
|
||||||
return _str;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
T _str;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename String>
|
|
||||||
struct StringTraits<RawJsonString<String>, void> {
|
|
||||||
static bool is_null(RawJsonString<String> source) {
|
|
||||||
return StringTraits<String>::is_null(static_cast<String>(source));
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef RawJsonString<const char*> duplicate_t;
|
|
||||||
|
|
||||||
template <typename Buffer>
|
|
||||||
static duplicate_t duplicate(RawJsonString<String> source, Buffer* buffer) {
|
|
||||||
return duplicate_t(StringTraits<String>::duplicate(source, buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bool has_append = false;
|
|
||||||
static const bool has_equals = false;
|
|
||||||
static const bool should_duplicate = StringTraits<String>::should_duplicate;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline Internals::RawJsonString<T> RawJson(T str) {
|
|
||||||
return Internals::RawJsonString<T>(str);
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,14 +7,14 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
class DummyPrint {
|
class DummyWriter {
|
||||||
public:
|
public:
|
||||||
size_t print(char) {
|
size_t write(uint8_t) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(const char* s) {
|
size_t write(const uint8_t*, size_t n) {
|
||||||
return strlen(s);
|
return n;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace Internals
|
} // namespace Internals
|
@ -1,35 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../Strings/StringTraits.hpp"
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
|
||||||
namespace Internals {
|
|
||||||
|
|
||||||
// A Print implementation that allows to write in a String
|
|
||||||
template <typename TString>
|
|
||||||
class DynamicStringBuilder {
|
|
||||||
public:
|
|
||||||
DynamicStringBuilder(TString &str) : _str(str) {}
|
|
||||||
|
|
||||||
size_t print(char c) {
|
|
||||||
StringTraits<TString>::append(_str, c);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t print(const char *s) {
|
|
||||||
size_t initialLen = _str.length();
|
|
||||||
StringTraits<TString>::append(_str, s);
|
|
||||||
return _str.length() - initialLen;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
DynamicStringBuilder &operator=(const DynamicStringBuilder &);
|
|
||||||
|
|
||||||
TString &_str;
|
|
||||||
};
|
|
||||||
} // namespace Internals
|
|
||||||
} // namespace ArduinoJson
|
|
81
src/ArduinoJson/Serialization/DynamicStringWriter.hpp
Normal file
81
src/ArduinoJson/Serialization/DynamicStringWriter.hpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Polyfills/type_traits.hpp"
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
|
#include <WString.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_STD_STRING
|
||||||
|
#include <string>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
template <typename>
|
||||||
|
struct IsWriteableString : false_type {};
|
||||||
|
|
||||||
|
// A Print implementation that allows to write in a String
|
||||||
|
template <typename TString>
|
||||||
|
class DynamicStringWriter {};
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
|
template <>
|
||||||
|
struct IsWriteableString<String> : true_type {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class DynamicStringWriter<String> {
|
||||||
|
public:
|
||||||
|
DynamicStringWriter(String &str) : _str(&str) {}
|
||||||
|
|
||||||
|
size_t write(uint8_t c) {
|
||||||
|
_str->operator+=(static_cast<char>(c));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t write(const uint8_t *s, size_t n) {
|
||||||
|
// CAUTION: Arduino String doesn't have append()
|
||||||
|
// and old version doesn't have size() either
|
||||||
|
_str->reserve(_str->length() + n);
|
||||||
|
while (n > 0) {
|
||||||
|
_str->operator+=(static_cast<char>(*s++));
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
String *_str;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_STD_STRING
|
||||||
|
template <>
|
||||||
|
struct IsWriteableString<std::string> : true_type {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class DynamicStringWriter<std::string> {
|
||||||
|
public:
|
||||||
|
DynamicStringWriter(std::string &str) : _str(&str) {}
|
||||||
|
|
||||||
|
size_t write(uint8_t c) {
|
||||||
|
_str->operator+=(static_cast<char>(c));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t write(const uint8_t *s, size_t n) {
|
||||||
|
_str->append(reinterpret_cast<const char *>(s), n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string *_str;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
@ -8,22 +8,25 @@ namespace ArduinoJson {
|
|||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
// A Print implementation that allows to write in a char[]
|
// A Print implementation that allows to write in a char[]
|
||||||
class StaticStringBuilder {
|
class StaticStringWriter {
|
||||||
public:
|
public:
|
||||||
StaticStringBuilder(char *buf, size_t size) : end(buf + size - 1), p(buf) {
|
StaticStringWriter(char *buf, size_t size) : end(buf + size - 1), p(buf) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(char c) {
|
size_t write(uint8_t c) {
|
||||||
if (p >= end) return 0;
|
if (p >= end) return 0;
|
||||||
*p++ = c;
|
*p++ = static_cast<char>(c);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(const char *s) {
|
size_t write(const uint8_t *s, size_t n) {
|
||||||
char *begin = p;
|
char *begin = p;
|
||||||
while (p < end && *s) *p++ = *s++;
|
while (p < end && n > 0) {
|
||||||
|
*p++ = static_cast<char>(*s++);
|
||||||
|
n--;
|
||||||
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return size_t(p - begin);
|
return size_t(p - begin);
|
||||||
}
|
}
|
@ -13,27 +13,28 @@
|
|||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
class StreamPrintAdapter {
|
class StreamWriter {
|
||||||
public:
|
public:
|
||||||
explicit StreamPrintAdapter(std::ostream& os) : _os(os) {}
|
explicit StreamWriter(std::ostream& os) : _os(os) {}
|
||||||
|
|
||||||
size_t print(char c) {
|
size_t write(uint8_t c) {
|
||||||
_os << c;
|
_os << c;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t print(const char* s) {
|
size_t write(const uint8_t* s, size_t n) {
|
||||||
_os << s;
|
_os.write(reinterpret_cast<const char*>(s),
|
||||||
return strlen(s);
|
static_cast<std::streamsize>(n));
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// cannot be assigned
|
// cannot be assigned
|
||||||
StreamPrintAdapter& operator=(const StreamPrintAdapter&);
|
StreamWriter& operator=(const StreamWriter&);
|
||||||
|
|
||||||
std::ostream& _os;
|
std::ostream& _os;
|
||||||
};
|
};
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
||||||
|
|
||||||
#endif // ARDUINOJSON_ENABLE_STD_STREAM
|
#endif // ARDUINOJSON_ENABLE_STD_STREAM
|
@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "./DummyPrint.hpp"
|
#include "./DummyWriter.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource>
|
template <template <typename> class TSerializer, typename TSource>
|
||||||
size_t measure(const TSource &source) {
|
size_t measure(const TSource &source) {
|
||||||
DummyPrint dp;
|
DummyWriter dp;
|
||||||
TSerializer<DummyPrint> serializer(dp);
|
TSerializer<DummyWriter> serializer(dp);
|
||||||
source.visit(serializer);
|
source.visit(serializer);
|
||||||
return serializer.bytesWritten();
|
return serializer.bytesWritten();
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "./DynamicStringBuilder.hpp"
|
#include "./DynamicStringWriter.hpp"
|
||||||
#include "./StaticStringBuilder.hpp"
|
#include "./StaticStringWriter.hpp"
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
#include "./StreamPrintAdapter.hpp"
|
#include "./StreamWriter.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
@ -16,7 +16,7 @@ namespace Internals {
|
|||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource,
|
template <template <typename> class TSerializer, typename TSource,
|
||||||
typename TPrint>
|
typename TPrint>
|
||||||
typename enable_if<!StringTraits<TPrint>::has_append, size_t>::type serialize(
|
typename enable_if<!IsWriteableString<TPrint>::value, size_t>::type serialize(
|
||||||
const TSource &source, TPrint &destination) {
|
const TSource &source, TPrint &destination) {
|
||||||
TSerializer<TPrint> serializer(destination);
|
TSerializer<TPrint> serializer(destination);
|
||||||
source.visit(serializer);
|
source.visit(serializer);
|
||||||
@ -26,29 +26,29 @@ typename enable_if<!StringTraits<TPrint>::has_append, size_t>::type serialize(
|
|||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
template <template <typename> class TSerializer, typename TSource>
|
template <template <typename> class TSerializer, typename TSource>
|
||||||
size_t serialize(const TSource &source, std::ostream &os) {
|
size_t serialize(const TSource &source, std::ostream &os) {
|
||||||
StreamPrintAdapter adapter(os);
|
StreamWriter writer(os);
|
||||||
return serialize<TSerializer>(source, adapter);
|
return serialize<TSerializer>(source, writer);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource>
|
template <template <typename> class TSerializer, typename TSource>
|
||||||
size_t serialize(const TSource &source, char *buffer, size_t bufferSize) {
|
size_t serialize(const TSource &source, char *buffer, size_t bufferSize) {
|
||||||
StaticStringBuilder sb(buffer, bufferSize);
|
StaticStringWriter writer(buffer, bufferSize);
|
||||||
return serialize<TSerializer>(source, sb);
|
return serialize<TSerializer>(source, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource, size_t N>
|
template <template <typename> class TSerializer, typename TSource, size_t N>
|
||||||
size_t serialize(const TSource &source, char (&buffer)[N]) {
|
size_t serialize(const TSource &source, char (&buffer)[N]) {
|
||||||
StaticStringBuilder sb(buffer, N);
|
StaticStringWriter writer(buffer, N);
|
||||||
return serialize<TSerializer>(source, sb);
|
return serialize<TSerializer>(source, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TSource,
|
template <template <typename> class TSerializer, typename TSource,
|
||||||
typename TString>
|
typename TString>
|
||||||
typename enable_if<StringTraits<TString>::has_append, size_t>::type serialize(
|
typename enable_if<IsWriteableString<TString>::value, size_t>::type serialize(
|
||||||
const TSource &source, TString &str) {
|
const TSource &source, TString &str) {
|
||||||
DynamicStringBuilder<TString> sb(str);
|
DynamicStringWriter<TString> writer(str);
|
||||||
return serialize<TSerializer>(source, sb);
|
return serialize<TSerializer>(source, writer);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internals
|
} // namespace Internals
|
||||||
|
70
src/ArduinoJson/SerializedValue.hpp
Normal file
70
src/ArduinoJson/SerializedValue.hpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Strings/StringTypes.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
|
||||||
|
namespace Internals {
|
||||||
|
// A special type of data that can be used to insert pregenerated JSON portions.
|
||||||
|
template <typename T>
|
||||||
|
class SerializedValue {
|
||||||
|
public:
|
||||||
|
explicit SerializedValue(T str) : _str(str) {}
|
||||||
|
operator T() const {
|
||||||
|
return _str;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* data() const {
|
||||||
|
return _str.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
// CAUTION: the old Arduino String doesn't have size()
|
||||||
|
return _str.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T _str;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
class SerializedValue<TChar*> {
|
||||||
|
public:
|
||||||
|
explicit SerializedValue(TChar* p, size_t n) : _data(p), _size(n) {}
|
||||||
|
operator TChar*() const {
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
TChar* data() const {
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return _size;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
TChar* _data;
|
||||||
|
size_t _size;
|
||||||
|
};
|
||||||
|
} // namespace Internals
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline Internals::SerializedValue<T> serialized(T str) {
|
||||||
|
return Internals::SerializedValue<T>(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
inline Internals::SerializedValue<TChar*> serialized(TChar* p) {
|
||||||
|
return Internals::SerializedValue<TChar*>(p, Internals::makeString(p).size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
inline Internals::SerializedValue<TChar*> serialized(TChar* p, size_t n) {
|
||||||
|
return Internals::SerializedValue<TChar*>(p, n);
|
||||||
|
}
|
||||||
|
} // namespace ArduinoJson
|
60
src/ArduinoJson/Strings/ArduinoString.hpp
Normal file
60
src/ArduinoJson/Strings/ArduinoString.hpp
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <WString.h>
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class ArduinoString {
|
||||||
|
public:
|
||||||
|
ArduinoString(const ::String& str) : _str(&str) {}
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
const char* save(Buffer* buffer) const {
|
||||||
|
if (!_str->c_str()) return NULL; // <- Arduino string can return NULL
|
||||||
|
size_t n = _str->length() + 1;
|
||||||
|
void* dup = buffer->alloc(n);
|
||||||
|
if (dup != NULL) memcpy(dup, _str->c_str(), n);
|
||||||
|
return static_cast<const char*>(dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const {
|
||||||
|
// Arduino's String::c_str() can return NULL
|
||||||
|
return _str->c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equals(const char* expected) const {
|
||||||
|
// Arduino's String::c_str() can return NULL
|
||||||
|
const char* actual = _str->c_str();
|
||||||
|
if (!actual || !expected) return actual == expected;
|
||||||
|
return 0 == strcmp(actual, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* data() const {
|
||||||
|
return _str->c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return _str->length();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const ::String* _str;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct IsString< ::String> : true_type {};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct IsString< ::StringSumHelper> : true_type {};
|
||||||
|
|
||||||
|
inline ArduinoString makeString(const ::String& str) {
|
||||||
|
return ArduinoString(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
@ -1,44 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
|
||||||
namespace Internals {
|
|
||||||
|
|
||||||
template <typename TChar>
|
|
||||||
struct CharPointerTraits {
|
|
||||||
static bool equals(const TChar* str, const char* expected) {
|
|
||||||
const char* actual = reinterpret_cast<const char*>(str);
|
|
||||||
if (!actual || !expected) return actual == expected;
|
|
||||||
return strcmp(actual, expected) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_null(const TChar* str) {
|
|
||||||
return !str;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef const char* duplicate_t;
|
|
||||||
|
|
||||||
template <typename Buffer>
|
|
||||||
static duplicate_t duplicate(const TChar* str, Buffer* buffer) {
|
|
||||||
if (!str) return NULL;
|
|
||||||
size_t size = strlen(reinterpret_cast<const char*>(str)) + 1;
|
|
||||||
void* dup = buffer->alloc(size);
|
|
||||||
if (dup != NULL) memcpy(dup, str, size);
|
|
||||||
return static_cast<duplicate_t>(dup);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bool has_append = false;
|
|
||||||
static const bool has_equals = true;
|
|
||||||
static const bool should_duplicate = !is_const<TChar>::value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// char*, unsigned char*, signed char*
|
|
||||||
// const char*, const unsigned char*, const signed char*
|
|
||||||
template <typename TChar>
|
|
||||||
struct StringTraits<TChar*, typename enable_if<sizeof(TChar) == 1>::type>
|
|
||||||
: CharPointerTraits<TChar> {};
|
|
||||||
} // namespace Internals
|
|
||||||
} // namespace ArduinoJson
|
|
47
src/ArduinoJson/Strings/FixedSizeFlashString.hpp
Normal file
47
src/ArduinoJson/Strings/FixedSizeFlashString.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class FixedSizeFlashString {
|
||||||
|
public:
|
||||||
|
FixedSizeFlashString(const __FlashStringHelper* str, size_t sz)
|
||||||
|
: _str(str), _size(sz) {}
|
||||||
|
|
||||||
|
bool equals(const char* expected) const {
|
||||||
|
const char* actual = reinterpret_cast<const char*>(_str);
|
||||||
|
if (!actual || !expected) return actual == expected;
|
||||||
|
return strcmp_P(actual, expected) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const {
|
||||||
|
return !_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
const char* save(Buffer* buffer) const {
|
||||||
|
if (!_str) return NULL;
|
||||||
|
void* dup = buffer->alloc(_size);
|
||||||
|
if (dup != NULL) memcpy_P(dup, (const char*)_str, _size);
|
||||||
|
return static_cast<const char*>(dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return strlen_P(reinterpret_cast<const char*>(_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const __FlashStringHelper* _str;
|
||||||
|
size_t _size;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline FixedSizeFlashString makeString(const __FlashStringHelper* str,
|
||||||
|
size_t sz) {
|
||||||
|
return FixedSizeFlashString(str, sz);
|
||||||
|
}
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
48
src/ArduinoJson/Strings/FixedSizeRamString.hpp
Normal file
48
src/ArduinoJson/Strings/FixedSizeRamString.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class FixedSizeRamString {
|
||||||
|
public:
|
||||||
|
FixedSizeRamString(const char* str, size_t n) : _str(str), _size(n) {}
|
||||||
|
|
||||||
|
bool equals(const char* expected) const {
|
||||||
|
const char* actual = reinterpret_cast<const char*>(_str);
|
||||||
|
if (!actual || !expected) return actual == expected;
|
||||||
|
return strcmp(actual, expected) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const {
|
||||||
|
return !_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
const char* save(Buffer* buffer) const {
|
||||||
|
if (!_str) return NULL;
|
||||||
|
void* dup = buffer->alloc(_size);
|
||||||
|
if (!dup) return NULL;
|
||||||
|
memcpy(dup, _str, _size);
|
||||||
|
return static_cast<const char*>(dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return strlen(reinterpret_cast<const char*>(_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* _str;
|
||||||
|
size_t _size;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
inline FixedSizeRamString makeString(const TChar* str, size_t size) {
|
||||||
|
return FixedSizeRamString(reinterpret_cast<const char*>(str), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
@ -1,41 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_PROGMEM
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
|
||||||
namespace Internals {
|
|
||||||
template <>
|
|
||||||
struct StringTraits<const __FlashStringHelper*, void> {
|
|
||||||
static bool equals(const __FlashStringHelper* str, const char* expected) {
|
|
||||||
const char* actual = reinterpret_cast<const char*>(str);
|
|
||||||
if (!actual || !expected) return actual == expected;
|
|
||||||
return strcmp_P(expected, actual) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_null(const __FlashStringHelper* str) {
|
|
||||||
return !str;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef const char* duplicate_t;
|
|
||||||
|
|
||||||
template <typename Buffer>
|
|
||||||
static duplicate_t duplicate(const __FlashStringHelper* str, Buffer* buffer) {
|
|
||||||
if (!str) return NULL;
|
|
||||||
size_t size = strlen_P((const char*)str) + 1;
|
|
||||||
void* dup = buffer->alloc(size);
|
|
||||||
if (dup != NULL) memcpy_P(dup, (const char*)str, size);
|
|
||||||
return static_cast<duplicate_t>(dup);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bool has_append = false;
|
|
||||||
static const bool has_equals = true;
|
|
||||||
static const bool should_duplicate = true;
|
|
||||||
};
|
|
||||||
} // namespace Internals
|
|
||||||
} // namespace ArduinoJson
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,73 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STRING || ARDUINOJSON_ENABLE_ARDUINO_STRING
|
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
|
||||||
#include <WString.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STRING
|
|
||||||
#include <string>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
|
||||||
namespace Internals {
|
|
||||||
|
|
||||||
template <typename TString>
|
|
||||||
struct StdStringTraits {
|
|
||||||
typedef const char* duplicate_t;
|
|
||||||
|
|
||||||
template <typename Buffer>
|
|
||||||
static duplicate_t duplicate(const TString& str, Buffer* buffer) {
|
|
||||||
if (!str.c_str()) return NULL; // <- Arduino string can return NULL
|
|
||||||
size_t size = str.length() + 1;
|
|
||||||
void* dup = buffer->alloc(size);
|
|
||||||
if (dup != NULL) memcpy(dup, str.c_str(), size);
|
|
||||||
return static_cast<duplicate_t>(dup);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_null(const TString& str) {
|
|
||||||
// Arduino's String::c_str() can return NULL
|
|
||||||
return !str.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool equals(const TString& str, const char* expected) {
|
|
||||||
// Arduino's String::c_str() can return NULL
|
|
||||||
const char* actual = str.c_str();
|
|
||||||
if (!actual || !expected) return actual == expected;
|
|
||||||
return 0 == strcmp(actual, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void append(TString& str, char c) {
|
|
||||||
str += c;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void append(TString& str, const char* s) {
|
|
||||||
str += s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const bool has_append = true;
|
|
||||||
static const bool has_equals = true;
|
|
||||||
static const bool should_duplicate = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
|
||||||
template <>
|
|
||||||
struct StringTraits<String, void> : StdStringTraits<String> {};
|
|
||||||
template <>
|
|
||||||
struct StringTraits<StringSumHelper, void> : StdStringTraits<StringSumHelper> {
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STRING
|
|
||||||
template <>
|
|
||||||
struct StringTraits<std::string, void> : StdStringTraits<std::string> {};
|
|
||||||
#endif
|
|
||||||
} // namespace Internals
|
|
||||||
} // namespace ArduinoJson
|
|
||||||
|
|
||||||
#endif
|
|
52
src/ArduinoJson/Strings/StlString.hpp
Normal file
52
src/ArduinoJson/Strings/StlString.hpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class StlString {
|
||||||
|
public:
|
||||||
|
StlString(const std::string& str) : _str(&str) {}
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
const char* save(Buffer* buffer) const {
|
||||||
|
size_t n = _str->length() + 1;
|
||||||
|
void* dup = buffer->alloc(n);
|
||||||
|
if (dup != NULL) memcpy(dup, _str->c_str(), n);
|
||||||
|
return static_cast<const char*>(dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool equals(const char* expected) const {
|
||||||
|
return *_str == expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* data() const {
|
||||||
|
return _str->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return _str->size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const std::string* _str;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct IsString<std::string> : true_type {};
|
||||||
|
|
||||||
|
inline StlString makeString(const std::string& str) {
|
||||||
|
return StlString(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
@ -1,30 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include "../Configuration.hpp"
|
|
||||||
#include "../Polyfills/type_traits.hpp"
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
|
||||||
namespace Internals {
|
|
||||||
|
|
||||||
template <typename TString, typename Enable = void>
|
|
||||||
struct StringTraits {
|
|
||||||
static const bool has_append = false;
|
|
||||||
static const bool has_equals = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename TString>
|
|
||||||
struct StringTraits<const TString, void> : StringTraits<TString> {};
|
|
||||||
|
|
||||||
template <typename TString>
|
|
||||||
struct StringTraits<TString&, void> : StringTraits<TString> {};
|
|
||||||
} // namespace Internals
|
|
||||||
} // namespace ArduinoJson
|
|
||||||
|
|
||||||
#include "CharPointer.hpp"
|
|
||||||
#include "FlashString.hpp"
|
|
||||||
#include "StdString.hpp"
|
|
36
src/ArduinoJson/Strings/StringTypes.hpp
Normal file
36
src/ArduinoJson/Strings/StringTypes.hpp
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Polyfills/type_traits.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
template <typename>
|
||||||
|
struct IsString : false_type {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsString<const T> : IsString<T> {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct IsString<T&> : IsString<T> {};
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
||||||
|
|
||||||
|
#include "FixedSizeRamString.hpp"
|
||||||
|
#include "ZeroTerminatedRamString.hpp"
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_STD_STRING
|
||||||
|
#include "StlString.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||||
|
#include "ArduinoString.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||||
|
#include "FixedSizeFlashString.hpp"
|
||||||
|
#include "ZeroTerminatedFlashString.hpp"
|
||||||
|
#endif
|
48
src/ArduinoJson/Strings/ZeroTerminatedFlashString.hpp
Normal file
48
src/ArduinoJson/Strings/ZeroTerminatedFlashString.hpp
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class ZeroTerminatedFlashString {
|
||||||
|
public:
|
||||||
|
ZeroTerminatedFlashString(const __FlashStringHelper* str) : _str(str) {}
|
||||||
|
|
||||||
|
bool equals(const char* expected) const {
|
||||||
|
const char* actual = reinterpret_cast<const char*>(_str);
|
||||||
|
if (!actual || !expected) return actual == expected;
|
||||||
|
return strcmp_P(actual, expected) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const {
|
||||||
|
return !_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
const char* save(Buffer* buffer) const {
|
||||||
|
if (!_str) return NULL;
|
||||||
|
size_t n = size() + 1; // copy the terminator
|
||||||
|
void* dup = buffer->alloc(n);
|
||||||
|
if (dup != NULL) memcpy_P(dup, (const char*)_str, n);
|
||||||
|
return static_cast<const char*>(dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return strlen_P(reinterpret_cast<const char*>(_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const __FlashStringHelper* _str;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline ZeroTerminatedFlashString makeString(const __FlashStringHelper* str) {
|
||||||
|
return ZeroTerminatedFlashString(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct IsString<const __FlashStringHelper*> : true_type {};
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
53
src/ArduinoJson/Strings/ZeroTerminatedRamString.hpp
Normal file
53
src/ArduinoJson/Strings/ZeroTerminatedRamString.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
class ZeroTerminatedRamString {
|
||||||
|
public:
|
||||||
|
ZeroTerminatedRamString(const char* str) : _str(str) {}
|
||||||
|
|
||||||
|
bool equals(const char* expected) const {
|
||||||
|
const char* actual = reinterpret_cast<const char*>(_str);
|
||||||
|
if (!actual || !expected) return actual == expected;
|
||||||
|
return strcmp(actual, expected) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_null() const {
|
||||||
|
return !_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Buffer>
|
||||||
|
const char* save(Buffer* buffer) const {
|
||||||
|
if (!_str) return NULL;
|
||||||
|
size_t n = size() + 1;
|
||||||
|
void* dup = buffer->alloc(n);
|
||||||
|
if (!dup) return NULL;
|
||||||
|
memcpy(dup, _str, n);
|
||||||
|
return static_cast<const char*>(dup);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size() const {
|
||||||
|
return strlen(reinterpret_cast<const char*>(_str));
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char* _str;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
inline ZeroTerminatedRamString makeString(const TChar* str) {
|
||||||
|
return ZeroTerminatedRamString(reinterpret_cast<const char*>(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TChar>
|
||||||
|
struct IsString<TChar*> {
|
||||||
|
static const bool value = sizeof(TChar) == 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
@ -4,16 +4,17 @@
|
|||||||
|
|
||||||
add_executable(JsonArrayTests
|
add_executable(JsonArrayTests
|
||||||
add.cpp
|
add.cpp
|
||||||
basics.cpp
|
|
||||||
copyFrom.cpp
|
copyFrom.cpp
|
||||||
copyTo.cpp
|
copyTo.cpp
|
||||||
invalid.cpp
|
createNested.cpp
|
||||||
|
isNull.cpp
|
||||||
iterator.cpp
|
iterator.cpp
|
||||||
remove.cpp
|
remove.cpp
|
||||||
set.cpp
|
set.cpp
|
||||||
size.cpp
|
size.cpp
|
||||||
std_string.cpp
|
std_string.cpp
|
||||||
subscript.cpp
|
subscript.cpp
|
||||||
|
undefined.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(JsonArrayTests catch)
|
target_link_libraries(JsonArrayTests catch)
|
||||||
|
@ -100,14 +100,26 @@ TEST_CASE("JsonArray::add()") {
|
|||||||
REQUIRE(expectedSize == doc.memoryUsage());
|
REQUIRE(expectedSize == doc.memoryUsage());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("should not duplicate RawJson(const char*)") {
|
SECTION("should not duplicate serialized(const char*)") {
|
||||||
_array.add(RawJson("{}"));
|
_array.add(serialized("{}"));
|
||||||
const size_t expectedSize = JSON_ARRAY_SIZE(1);
|
const size_t expectedSize = JSON_ARRAY_SIZE(1);
|
||||||
REQUIRE(expectedSize == doc.memoryUsage());
|
REQUIRE(expectedSize == doc.memoryUsage());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("should duplicate RawJson(char*)") {
|
SECTION("should duplicate serialized(char*)") {
|
||||||
_array.add(RawJson(const_cast<char*>("{}")));
|
_array.add(serialized(const_cast<char*>("{}")));
|
||||||
|
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 2;
|
||||||
|
REQUIRE(expectedSize == doc.memoryUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("should duplicate serialized(std::string)") {
|
||||||
|
_array.add(serialized(std::string("{}")));
|
||||||
|
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 2;
|
||||||
|
REQUIRE(expectedSize == doc.memoryUsage());
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("should duplicate serialized(std::string)") {
|
||||||
|
_array.add(serialized(std::string("\0XX", 3)));
|
||||||
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3;
|
const size_t expectedSize = JSON_ARRAY_SIZE(1) + 3;
|
||||||
REQUIRE(expectedSize == doc.memoryUsage());
|
REQUIRE(expectedSize == doc.memoryUsage());
|
||||||
}
|
}
|
||||||
|
@ -9,14 +9,6 @@ TEST_CASE("JsonArray basics") {
|
|||||||
DynamicJsonDocument doc;
|
DynamicJsonDocument doc;
|
||||||
JsonArray array = doc.to<JsonArray>();
|
JsonArray array = doc.to<JsonArray>();
|
||||||
|
|
||||||
SECTION("isNull()") {
|
|
||||||
REQUIRE(array.isNull() == false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("InitialSizeIsZero") {
|
|
||||||
REQUIRE(0U == array.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("CreateNestedArray") {
|
SECTION("CreateNestedArray") {
|
||||||
JsonArray arr = array.createNestedArray();
|
JsonArray arr = array.createNestedArray();
|
||||||
REQUIRE(arr == array[0].as<JsonArray>());
|
REQUIRE(arr == array[0].as<JsonArray>());
|
25
test/JsonArray/isNull.cpp
Normal file
25
test/JsonArray/isNull.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("JsonArray::isNull()") {
|
||||||
|
SECTION("returns true for undefined JsonArray") {
|
||||||
|
JsonArray array;
|
||||||
|
REQUIRE(array.isNull() == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("returns false when allocation succeeds") {
|
||||||
|
StaticJsonDocument<JSON_ARRAY_SIZE(0)> doc;
|
||||||
|
JsonArray array = doc.to<JsonArray>();
|
||||||
|
REQUIRE(array.isNull() == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("returns true when allocation fails") {
|
||||||
|
StaticJsonDocument<1> doc;
|
||||||
|
JsonArray array = doc.to<JsonArray>();
|
||||||
|
REQUIRE(array.isNull() == true);
|
||||||
|
}
|
||||||
|
}
|
@ -7,29 +7,33 @@
|
|||||||
|
|
||||||
TEST_CASE("JsonArray::size()") {
|
TEST_CASE("JsonArray::size()") {
|
||||||
DynamicJsonDocument doc;
|
DynamicJsonDocument doc;
|
||||||
JsonArray _array = doc.to<JsonArray>();
|
JsonArray array = doc.to<JsonArray>();
|
||||||
|
|
||||||
|
SECTION("InitialSizeIsZero") {
|
||||||
|
REQUIRE(0U == array.size());
|
||||||
|
}
|
||||||
|
|
||||||
SECTION("increases after add()") {
|
SECTION("increases after add()") {
|
||||||
_array.add("hello");
|
array.add("hello");
|
||||||
REQUIRE(1U == _array.size());
|
REQUIRE(1U == array.size());
|
||||||
|
|
||||||
_array.add("world");
|
array.add("world");
|
||||||
REQUIRE(2U == _array.size());
|
REQUIRE(2U == array.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("remains the same after set()") {
|
SECTION("remains the same after set()") {
|
||||||
_array.add("hello");
|
array.add("hello");
|
||||||
REQUIRE(1U == _array.size());
|
REQUIRE(1U == array.size());
|
||||||
|
|
||||||
_array.set(0, "hello");
|
array.set(0, "hello");
|
||||||
REQUIRE(1U == _array.size());
|
REQUIRE(1U == array.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("remains the same after assigment") {
|
SECTION("remains the same after assigment") {
|
||||||
_array.add("hello");
|
array.add("hello");
|
||||||
REQUIRE(1U == _array.size());
|
REQUIRE(1U == array.size());
|
||||||
|
|
||||||
_array[0] = "hello";
|
array[0] = "hello";
|
||||||
REQUIRE(1U == _array.size());
|
REQUIRE(1U == array.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
# MIT License
|
# MIT License
|
||||||
|
|
||||||
add_executable(JsonObjectTests
|
add_executable(JsonObjectTests
|
||||||
basics.cpp
|
|
||||||
containsKey.cpp
|
containsKey.cpp
|
||||||
get.cpp
|
get.cpp
|
||||||
invalid.cpp
|
invalid.cpp
|
||||||
|
isNull.cpp
|
||||||
iterator.cpp
|
iterator.cpp
|
||||||
remove.cpp
|
remove.cpp
|
||||||
set.cpp
|
set.cpp
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
#include <catch.hpp>
|
|
||||||
|
|
||||||
TEST_CASE("JsonObject basics") {
|
|
||||||
DynamicJsonDocument doc;
|
|
||||||
JsonObject obj = doc.to<JsonObject>();
|
|
||||||
|
|
||||||
SECTION("isNull()") {
|
|
||||||
REQUIRE(obj.isNull() == false);
|
|
||||||
}
|
|
||||||
}
|
|
25
test/JsonObject/isNull.cpp
Normal file
25
test/JsonObject/isNull.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("JsonObject::isNull()") {
|
||||||
|
SECTION("returns true for undefined JsonObject") {
|
||||||
|
JsonObject array;
|
||||||
|
REQUIRE(array.isNull() == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("returns false when allocation succeeds") {
|
||||||
|
StaticJsonDocument<JSON_OBJECT_SIZE(0)> doc;
|
||||||
|
JsonObject array = doc.to<JsonObject>();
|
||||||
|
REQUIRE(array.isNull() == false);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("returns true when allocation fails") {
|
||||||
|
StaticJsonDocument<1> doc;
|
||||||
|
JsonObject array = doc.to<JsonObject>();
|
||||||
|
REQUIRE(array.isNull() == true);
|
||||||
|
}
|
||||||
|
}
|
@ -67,15 +67,15 @@ TEST_CASE("serializeJson(JsonArray)") {
|
|||||||
check(array, "[1,2]");
|
check(array, "[1,2]");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("RawJson(const char*)") {
|
SECTION("serialized(const char*)") {
|
||||||
array.add(RawJson("{\"key\":\"value\"}"));
|
array.add(serialized("{\"key\":\"value\"}"));
|
||||||
|
|
||||||
check(array, "[{\"key\":\"value\"}]");
|
check(array, "[{\"key\":\"value\"}]");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("RawJson(char*)") {
|
SECTION("serialized(char*)") {
|
||||||
char tmp[] = "{\"key\":\"value\"}";
|
char tmp[] = "{\"key\":\"value\"}";
|
||||||
array.add(RawJson(tmp));
|
array.add(serialized(tmp));
|
||||||
|
|
||||||
check(array, "[{\"key\":\"value\"}]");
|
check(array, "[{\"key\":\"value\"}]");
|
||||||
}
|
}
|
||||||
|
@ -68,9 +68,9 @@ TEST_CASE("serializeJson(JsonObject)") {
|
|||||||
check(obj, "{\"a\":1,\"b\":2}");
|
check(obj, "{\"a\":1,\"b\":2}");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("RawJson") {
|
SECTION("serialized(const char*)") {
|
||||||
obj["a"] = RawJson("[1,2]");
|
obj["a"] = serialized("[1,2]");
|
||||||
obj.set("b", RawJson("[4,5]"));
|
obj.set("b", serialized("[4,5]"));
|
||||||
check(obj, "{\"a\":[1,2],\"b\":[4,5]}");
|
check(obj, "{\"a\":[1,2],\"b\":[4,5]}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,21 +95,4 @@ TEST_CASE("JsonVariant::is()") {
|
|||||||
SECTION("string") {
|
SECTION("string") {
|
||||||
checkIsString("42");
|
checkIsString("42");
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("unparsed bool") {
|
|
||||||
checkIsBool(RawJson("true"));
|
|
||||||
checkIsBool(RawJson("false"));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("unparsed int") {
|
|
||||||
checkIsInteger(RawJson("42"));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("unparsed float") {
|
|
||||||
checkIsFloat(RawJson("4.2e-10"));
|
|
||||||
}
|
|
||||||
|
|
||||||
SECTION("unparsed null") {
|
|
||||||
checkIsString(RawJson("null"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,15 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <ArduinoJson/Json/JsonWriter.hpp>
|
#include <ArduinoJson/Json/JsonWriter.hpp>
|
||||||
#include <ArduinoJson/Serialization/DynamicStringBuilder.hpp>
|
#include <ArduinoJson/Serialization/DynamicStringWriter.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
template <typename TFloat>
|
template <typename TFloat>
|
||||||
void check(TFloat input, const std::string& expected) {
|
void check(TFloat input, const std::string& expected) {
|
||||||
std::string output;
|
std::string output;
|
||||||
DynamicStringBuilder<std::string> sb(output);
|
DynamicStringWriter<std::string> sb(output);
|
||||||
JsonWriter<DynamicStringBuilder<std::string> > writer(sb);
|
JsonWriter<DynamicStringWriter<std::string> > writer(sb);
|
||||||
writer.writeFloat(input);
|
writer.writeFloat(input);
|
||||||
REQUIRE(writer.bytesWritten() == output.size());
|
REQUIRE(writer.bytesWritten() == output.size());
|
||||||
CHECK(expected == output);
|
CHECK(expected == output);
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
#include <ArduinoJson/Json/JsonWriter.hpp>
|
#include <ArduinoJson/Json/JsonWriter.hpp>
|
||||||
#include <ArduinoJson/Serialization/StaticStringBuilder.hpp>
|
#include <ArduinoJson/Serialization/StaticStringWriter.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
void check(const char* input, std::string expected) {
|
void check(const char* input, std::string expected) {
|
||||||
char output[1024];
|
char output[1024];
|
||||||
StaticStringBuilder sb(output, sizeof(output));
|
StaticStringWriter sb(output, sizeof(output));
|
||||||
JsonWriter<StaticStringBuilder> writer(sb);
|
JsonWriter<StaticStringWriter> writer(sb);
|
||||||
writer.writeString(input);
|
writer.writeString(input);
|
||||||
REQUIRE(expected == output);
|
REQUIRE(expected == output);
|
||||||
REQUIRE(writer.bytesWritten() == expected.size());
|
REQUIRE(writer.bytesWritten() == expected.size());
|
||||||
|
@ -4,8 +4,7 @@
|
|||||||
|
|
||||||
add_executable(MiscTests
|
add_executable(MiscTests
|
||||||
FloatParts.cpp
|
FloatParts.cpp
|
||||||
StringBuilder.cpp
|
StringWriter.cpp
|
||||||
StringTraits.cpp
|
|
||||||
TypeTraits.cpp
|
TypeTraits.cpp
|
||||||
unsigned_char.cpp
|
unsigned_char.cpp
|
||||||
version.cpp
|
version.cpp
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
// ArduinoJson - arduinojson.org
|
|
||||||
// Copyright Benoit Blanchon 2014-2018
|
|
||||||
// MIT License
|
|
||||||
|
|
||||||
#include <ArduinoJson.h>
|
|
||||||
#include <catch.hpp>
|
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
|
||||||
|
|
||||||
template <typename String>
|
|
||||||
bool should_duplicate() {
|
|
||||||
return StringTraits<String>::should_duplicate;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("StringTraits") {
|
|
||||||
SECTION("should_duplicate") {
|
|
||||||
REQUIRE(false == should_duplicate<const char*>());
|
|
||||||
REQUIRE(true == should_duplicate<char*>());
|
|
||||||
REQUIRE(true == should_duplicate<RawJsonString<char*> >());
|
|
||||||
REQUIRE(false == should_duplicate<RawJsonString<const char*> >());
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,44 +7,49 @@
|
|||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
template <typename StringBuilder, typename String>
|
template <typename StringWriter>
|
||||||
void common_tests(StringBuilder& sb, const String& output) {
|
static size_t print(StringWriter& sb, const char* s) {
|
||||||
|
return sb.write(reinterpret_cast<const uint8_t*>(s), strlen(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StringWriter, typename String>
|
||||||
|
void common_tests(StringWriter& sb, const String& output) {
|
||||||
SECTION("InitialState") {
|
SECTION("InitialState") {
|
||||||
REQUIRE(std::string("") == output);
|
REQUIRE(std::string("") == output);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("EmptyString") {
|
SECTION("EmptyString") {
|
||||||
REQUIRE(0 == sb.print(""));
|
REQUIRE(0 == print(sb, ""));
|
||||||
REQUIRE(std::string("") == output);
|
REQUIRE(std::string("") == output);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("OneString") {
|
SECTION("OneString") {
|
||||||
REQUIRE(4 == sb.print("ABCD"));
|
REQUIRE(4 == print(sb, "ABCD"));
|
||||||
REQUIRE(std::string("ABCD") == output);
|
REQUIRE(std::string("ABCD") == output);
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("TwoStrings") {
|
SECTION("TwoStrings") {
|
||||||
REQUIRE(4 == sb.print("ABCD"));
|
REQUIRE(4 == print(sb, "ABCD"));
|
||||||
REQUIRE(4 == sb.print("EFGH"));
|
REQUIRE(4 == print(sb, "EFGH"));
|
||||||
REQUIRE(std::string("ABCDEFGH") == output);
|
REQUIRE(std::string("ABCDEFGH") == output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("StaticStringBuilder") {
|
TEST_CASE("StaticStringWriter") {
|
||||||
char output[20];
|
char output[20];
|
||||||
StaticStringBuilder sb(output, sizeof(output));
|
StaticStringWriter sb(output, sizeof(output));
|
||||||
|
|
||||||
common_tests(sb, static_cast<const char*>(output));
|
common_tests(sb, static_cast<const char*>(output));
|
||||||
|
|
||||||
SECTION("OverCapacity") {
|
SECTION("OverCapacity") {
|
||||||
REQUIRE(19 == sb.print("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
|
REQUIRE(19 == print(sb, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
|
||||||
REQUIRE(0 == sb.print("ABC"));
|
REQUIRE(0 == print(sb, "ABC"));
|
||||||
REQUIRE(std::string("ABCDEFGHIJKLMNOPQRS") == output);
|
REQUIRE(std::string("ABCDEFGHIJKLMNOPQRS") == output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("DynamicStringBuilder") {
|
TEST_CASE("DynamicStringWriter") {
|
||||||
std::string output;
|
std::string output;
|
||||||
DynamicStringBuilder<std::string> sb(output);
|
DynamicStringWriter<std::string> sb(output);
|
||||||
common_tests(sb, output);
|
common_tests(sb, output);
|
||||||
}
|
}
|
@ -70,4 +70,14 @@ TEST_CASE("serialize MsgPack object") {
|
|||||||
//
|
//
|
||||||
// check(object, expected);
|
// check(object, expected);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
SECTION("serialized(const char*)") {
|
||||||
|
object["hello"] = serialized("\xDB\x00\x01\x00\x00", 5);
|
||||||
|
check(object, "\x81\xA5hello\xDB\x00\x01\x00\x00");
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("serialized(std::string)") {
|
||||||
|
object["hello"] = serialized(std::string("\xDB\x00\x01\x00\x00", 5));
|
||||||
|
check(object, "\x81\xA5hello\xDB\x00\x01\x00\x00");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -126,4 +126,9 @@ TEST_CASE("serialize MsgPack value") {
|
|||||||
std::string shortest(65536, '?');
|
std::string shortest(65536, '?');
|
||||||
check(shortest.c_str(), std::string("\xDB\x00\x01\x00\x00", 5) + shortest);
|
check(shortest.c_str(), std::string("\xDB\x00\x01\x00\x00", 5) + shortest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTION("serialized(const char*)") {
|
||||||
|
check(serialized("\xDA\xFF\xFF"), "\xDA\xFF\xFF");
|
||||||
|
check(serialized("\xDB\x00\x01\x00\x00", 5), "\xDB\x00\x01\x00\x00");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user