forked from bblanchon/ArduinoJson
Added support for non zero-terminated strings (fixes #704)
This commit is contained in:
@ -5,12 +5,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "ArduinoJson/DynamicJsonDocument.hpp"
|
||||
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
||||
#include "ArduinoJson/StaticJsonDocument.hpp"
|
||||
#include "ArduinoJson/deserializeJson.hpp"
|
||||
#include "ArduinoJson/deserializeMsgPack.hpp"
|
||||
|
||||
#include "ArduinoJson/Json/Deserialization/JsonDeserializer.hpp"
|
||||
#include "ArduinoJson/Json/Serialization/JsonSerializer.hpp"
|
||||
#include "ArduinoJson/JsonArrayImpl.hpp"
|
||||
#include "ArduinoJson/JsonObjectImpl.hpp"
|
||||
|
@ -1,61 +0,0 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
template <typename TInput>
|
||||
void skipSpacesAndComments(TInput& input) {
|
||||
for (;;) {
|
||||
switch (input.current()) {
|
||||
// spaces
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
input.move();
|
||||
continue;
|
||||
|
||||
// comments
|
||||
case '/':
|
||||
switch (input.next()) {
|
||||
// C-style block comment
|
||||
case '*':
|
||||
input.move(); // skip '/'
|
||||
// no need to skip '*'
|
||||
for (;;) {
|
||||
input.move();
|
||||
if (input.current() == '\0') return;
|
||||
if (input.current() == '*' && input.next() == '/') {
|
||||
input.move(); // skip '*'
|
||||
input.move(); // skip '/'
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// C++-style line comment
|
||||
case '/':
|
||||
// not need to skip "//"
|
||||
for (;;) {
|
||||
input.move();
|
||||
if (input.current() == '\0') return;
|
||||
if (input.current() == '\n') break;
|
||||
}
|
||||
break;
|
||||
|
||||
// not a comment, just a '/'
|
||||
default:
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,10 +7,9 @@
|
||||
#include "../../JsonError.hpp"
|
||||
#include "../../JsonVariant.hpp"
|
||||
#include "../../Memory/JsonBuffer.hpp"
|
||||
#include "../../Strings/StringWriter.hpp"
|
||||
#include "../../Reading/Reader.hpp"
|
||||
#include "../../TypeTraits/IsConst.hpp"
|
||||
#include "../Encoding.hpp"
|
||||
#include "./Comments.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
@ -23,11 +22,13 @@ class JsonDeserializer {
|
||||
: _buffer(buffer),
|
||||
_reader(reader),
|
||||
_writer(writer),
|
||||
_nestingLimit(nestingLimit) {}
|
||||
_nestingLimit(nestingLimit),
|
||||
_loaded(false) {}
|
||||
JsonError parse(JsonVariant &variant) {
|
||||
skipSpacesAndComments(_reader);
|
||||
JsonError err = skipSpacesAndComments();
|
||||
if (err) return err;
|
||||
|
||||
switch (_reader.current()) {
|
||||
switch (current()) {
|
||||
case '[':
|
||||
return parseArray(variant);
|
||||
|
||||
@ -42,15 +43,25 @@ class JsonDeserializer {
|
||||
private:
|
||||
JsonDeserializer &operator=(const JsonDeserializer &); // non-copiable
|
||||
|
||||
static bool eat(TReader &reader, char charToSkip) {
|
||||
skipSpacesAndComments(reader);
|
||||
if (reader.current() != charToSkip) return false;
|
||||
reader.move();
|
||||
return true;
|
||||
char current() {
|
||||
if (!_loaded) {
|
||||
if (_reader.ended())
|
||||
_current = 0;
|
||||
else
|
||||
_current = _reader.read();
|
||||
_loaded = true;
|
||||
}
|
||||
return _current;
|
||||
}
|
||||
|
||||
void move() {
|
||||
_loaded = false;
|
||||
}
|
||||
|
||||
FORCE_INLINE bool eat(char charToSkip) {
|
||||
return eat(_reader, charToSkip);
|
||||
if (current() != charToSkip) return false;
|
||||
move();
|
||||
return true;
|
||||
}
|
||||
|
||||
JsonError parseArray(JsonVariant &variant) {
|
||||
@ -62,6 +73,12 @@ class JsonDeserializer {
|
||||
|
||||
// Check opening braket
|
||||
if (!eat('[')) return JsonError::InvalidInput;
|
||||
|
||||
// Skip spaces
|
||||
JsonError err = skipSpacesAndComments();
|
||||
if (err) return err;
|
||||
|
||||
// Empty array?
|
||||
if (eat(']')) return JsonError::Ok;
|
||||
|
||||
// Read each value
|
||||
@ -69,12 +86,16 @@ class JsonDeserializer {
|
||||
// 1 - Parse value
|
||||
JsonVariant value;
|
||||
_nestingLimit--;
|
||||
JsonError error = parse(value);
|
||||
err = parse(value);
|
||||
_nestingLimit++;
|
||||
if (error != JsonError::Ok) return error;
|
||||
if (err) return err;
|
||||
if (!array->add(value)) return JsonError::NoMemory;
|
||||
|
||||
// 2 - More values?
|
||||
// 2 - Skip spaces
|
||||
err = skipSpacesAndComments();
|
||||
if (err) return err;
|
||||
|
||||
// 3 - More values?
|
||||
if (eat(']')) return JsonError::Ok;
|
||||
if (!eat(',')) return JsonError::InvalidInput;
|
||||
}
|
||||
@ -89,31 +110,52 @@ class JsonDeserializer {
|
||||
|
||||
// Check opening brace
|
||||
if (!eat('{')) return JsonError::InvalidInput;
|
||||
|
||||
// Skip spaces
|
||||
JsonError err = skipSpacesAndComments();
|
||||
if (err) return err;
|
||||
|
||||
// Empty object?
|
||||
if (eat('}')) return JsonError::Ok;
|
||||
|
||||
// Read each key value pair
|
||||
for (;;) {
|
||||
// 1 - Parse key
|
||||
// Parse key
|
||||
const char *key;
|
||||
JsonError error = parseString(&key);
|
||||
if (error) return error;
|
||||
err = parseString(&key);
|
||||
if (err) return err;
|
||||
|
||||
// Skip spaces
|
||||
err = skipSpacesAndComments();
|
||||
if (err) return err;
|
||||
|
||||
// Colon
|
||||
if (!eat(':')) return JsonError::InvalidInput;
|
||||
|
||||
// 2 - Parse value
|
||||
// Parse value
|
||||
JsonVariant value;
|
||||
_nestingLimit--;
|
||||
error = parse(value);
|
||||
err = parse(value);
|
||||
_nestingLimit++;
|
||||
if (error != JsonError::Ok) return error;
|
||||
if (err) return err;
|
||||
if (!object->set(key, value)) return JsonError::NoMemory;
|
||||
|
||||
// 3 - More keys/values?
|
||||
// Skip spaces
|
||||
err = skipSpacesAndComments();
|
||||
if (err) return err;
|
||||
|
||||
// More keys/values?
|
||||
if (eat('}')) return JsonError::Ok;
|
||||
if (!eat(',')) return JsonError::InvalidInput;
|
||||
|
||||
// Skip spaces
|
||||
err = skipSpacesAndComments();
|
||||
if (err) return err;
|
||||
}
|
||||
}
|
||||
|
||||
JsonError parseValue(JsonVariant &variant) {
|
||||
bool hasQuotes = isQuote(_reader.current());
|
||||
bool hasQuotes = isQuote(current());
|
||||
const char *value;
|
||||
JsonError error = parseString(&value);
|
||||
if (error) return error;
|
||||
@ -128,33 +170,35 @@ class JsonDeserializer {
|
||||
JsonError parseString(const char **result) {
|
||||
typename RemoveReference<TWriter>::type::String str = _writer.startString();
|
||||
|
||||
skipSpacesAndComments(_reader);
|
||||
char c = _reader.current();
|
||||
char c = current();
|
||||
if (c == '\0') return JsonError::IncompleteInput;
|
||||
|
||||
if (isQuote(c)) { // quotes
|
||||
_reader.move();
|
||||
move();
|
||||
char stopChar = c;
|
||||
for (;;) {
|
||||
c = _reader.current();
|
||||
if (c == '\0') break;
|
||||
_reader.move();
|
||||
|
||||
c = current();
|
||||
move();
|
||||
if (c == stopChar) break;
|
||||
|
||||
if (c == '\0') return JsonError::IncompleteInput;
|
||||
|
||||
if (c == '\\') {
|
||||
c = current();
|
||||
if (c == 0) return JsonError::IncompleteInput;
|
||||
// replace char
|
||||
c = Encoding::unescapeChar(_reader.current());
|
||||
c = Encoding::unescapeChar(c);
|
||||
if (c == '\0') return JsonError::InvalidInput;
|
||||
_reader.move();
|
||||
move();
|
||||
}
|
||||
|
||||
str.append(c);
|
||||
}
|
||||
} else if (canBeInNonQuotedString(c)) { // no quotes
|
||||
do {
|
||||
_reader.move();
|
||||
move();
|
||||
str.append(c);
|
||||
c = _reader.current();
|
||||
c = current();
|
||||
} while (canBeInNonQuotedString(c));
|
||||
} else {
|
||||
return JsonError::InvalidInput;
|
||||
@ -178,41 +222,80 @@ class JsonDeserializer {
|
||||
return c == '\'' || c == '\"';
|
||||
}
|
||||
|
||||
JsonError skipSpacesAndComments() {
|
||||
for (;;) {
|
||||
switch (current()) {
|
||||
// end of string
|
||||
case '\0':
|
||||
return JsonError::IncompleteInput;
|
||||
|
||||
// spaces
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
move();
|
||||
continue;
|
||||
|
||||
// comments
|
||||
case '/':
|
||||
move(); // skip '/'
|
||||
switch (current()) {
|
||||
// block comment
|
||||
case '*': {
|
||||
move(); // skip '*'
|
||||
bool wasStar = false;
|
||||
for (;;) {
|
||||
char c = current();
|
||||
if (c == '\0') return JsonError::IncompleteInput;
|
||||
if (c == '/' && wasStar) {
|
||||
move();
|
||||
break;
|
||||
}
|
||||
wasStar = c == '*';
|
||||
move();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// trailing comment
|
||||
case '/':
|
||||
// no need to skip "//"
|
||||
for (;;) {
|
||||
move();
|
||||
char c = current();
|
||||
if (c == '\0') return JsonError::IncompleteInput;
|
||||
if (c == '\n') break;
|
||||
}
|
||||
break;
|
||||
|
||||
// not a comment, just a '/'
|
||||
default:
|
||||
return JsonError::InvalidInput;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return JsonError::Ok;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JsonBuffer *_buffer;
|
||||
TReader _reader;
|
||||
TWriter _writer;
|
||||
uint8_t _nestingLimit;
|
||||
char _current;
|
||||
bool _loaded;
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TString, typename Enable = void>
|
||||
struct JsonParserBuilder {
|
||||
typedef typename StringTraits<TString>::Reader InputReader;
|
||||
typedef JsonDeserializer<InputReader, TJsonBuffer &> TParser;
|
||||
|
||||
static TParser makeParser(TJsonBuffer *buffer, TString &json,
|
||||
uint8_t nestingLimit) {
|
||||
return TParser(buffer, InputReader(json), *buffer, nestingLimit);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TChar>
|
||||
struct JsonParserBuilder<TJsonBuffer, TChar *,
|
||||
typename EnableIf<!IsConst<TChar>::value>::type> {
|
||||
typedef typename StringTraits<TChar *>::Reader TReader;
|
||||
typedef StringWriter<TChar> TWriter;
|
||||
typedef JsonDeserializer<TReader, TWriter> TParser;
|
||||
|
||||
static TParser makeParser(TJsonBuffer *buffer, TChar *json,
|
||||
uint8_t nestingLimit) {
|
||||
return TParser(buffer, TReader(json), TWriter(json), nestingLimit);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TString>
|
||||
inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser(
|
||||
TJsonBuffer *buffer, TString &json, uint8_t nestingLimit) {
|
||||
return JsonParserBuilder<TJsonBuffer, TString>::makeParser(buffer, json,
|
||||
nestingLimit);
|
||||
template <typename TJsonBuffer, typename TReader, typename TWriter>
|
||||
JsonDeserializer<TReader, TWriter> makeJsonDeserializer(TJsonBuffer *buffer,
|
||||
TReader reader,
|
||||
TWriter writer,
|
||||
uint8_t nestingLimit) {
|
||||
return JsonDeserializer<TReader, TWriter>(buffer, reader, writer,
|
||||
nestingLimit);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
||||
|
@ -4,11 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
class JsonError {
|
||||
public:
|
||||
enum Code { Ok, TooDeep, NoMemory, InvalidInput };
|
||||
enum Code { Ok, TooDeep, NoMemory, InvalidInput, IncompleteInput };
|
||||
|
||||
JsonError(Code code) : _code(code) {}
|
||||
|
||||
@ -42,6 +46,8 @@ class JsonError {
|
||||
return "NoMemory";
|
||||
case InvalidInput:
|
||||
return "InvalidInput";
|
||||
case IncompleteInput:
|
||||
return "IncompleteInput";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
|
@ -6,8 +6,9 @@
|
||||
|
||||
#include "../JsonVariant.hpp"
|
||||
#include "../Memory/JsonBuffer.hpp"
|
||||
#include "../Strings/StringWriter.hpp"
|
||||
#include "../Reading/Reader.hpp"
|
||||
#include "../TypeTraits/IsConst.hpp"
|
||||
#include "../Writing/Writer.hpp"
|
||||
#include "./MsgPackError.hpp"
|
||||
#include "./endianess.hpp"
|
||||
#include "./ieee754.hpp"
|
||||
@ -29,27 +30,28 @@ class MsgPackDeserializer {
|
||||
_nestingLimit(nestingLimit) {}
|
||||
|
||||
MsgPackError parse(JsonVariant &variant) {
|
||||
uint8_t c = readOne();
|
||||
uint8_t code;
|
||||
if (!readByte(code)) return MsgPackError::IncompleteInput;
|
||||
|
||||
if ((c & 0x80) == 0) {
|
||||
variant = c;
|
||||
if ((code & 0x80) == 0) {
|
||||
variant = code;
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
if ((c & 0xe0) == 0xe0) {
|
||||
variant = static_cast<int8_t>(c);
|
||||
if ((code & 0xe0) == 0xe0) {
|
||||
variant = static_cast<int8_t>(code);
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
if ((c & 0xe0) == 0xa0) {
|
||||
return readString(variant, c & 0x1f);
|
||||
if ((code & 0xe0) == 0xa0) {
|
||||
return readString(variant, code & 0x1f);
|
||||
}
|
||||
|
||||
if ((c & 0xf0) == 0x90) return readArray(variant, c & 0x0F);
|
||||
if ((code & 0xf0) == 0x90) return readArray(variant, code & 0x0F);
|
||||
|
||||
if ((c & 0xf0) == 0x80) return readObject(variant, c & 0x0F);
|
||||
if ((code & 0xf0) == 0x80) return readObject(variant, code & 0x0F);
|
||||
|
||||
switch (c) {
|
||||
switch (code) {
|
||||
case 0xc0:
|
||||
variant = static_cast<char *>(0);
|
||||
return MsgPackError::Ok;
|
||||
@ -63,81 +65,65 @@ class MsgPackDeserializer {
|
||||
return MsgPackError::Ok;
|
||||
|
||||
case 0xcc:
|
||||
variant = readInteger<uint8_t>();
|
||||
return MsgPackError::Ok;
|
||||
return readInteger<uint8_t>(variant);
|
||||
|
||||
case 0xcd:
|
||||
variant = readInteger<uint16_t>();
|
||||
return MsgPackError::Ok;
|
||||
return readInteger<uint16_t>(variant);
|
||||
|
||||
case 0xce:
|
||||
variant = readInteger<uint32_t>();
|
||||
return MsgPackError::Ok;
|
||||
return readInteger<uint32_t>(variant);
|
||||
|
||||
case 0xcf:
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
variant = readInteger<uint64_t>();
|
||||
return readInteger<uint64_t>(variant);
|
||||
#else
|
||||
readInteger<uint32_t>();
|
||||
variant = readInteger<uint32_t>();
|
||||
return readInteger<uint32_t>(variant);
|
||||
#endif
|
||||
return MsgPackError::Ok;
|
||||
|
||||
case 0xd0:
|
||||
variant = readInteger<int8_t>();
|
||||
return MsgPackError::Ok;
|
||||
return readInteger<int8_t>(variant);
|
||||
|
||||
case 0xd1:
|
||||
variant = readInteger<int16_t>();
|
||||
return MsgPackError::Ok;
|
||||
return readInteger<int16_t>(variant);
|
||||
|
||||
case 0xd2:
|
||||
variant = readInteger<int32_t>();
|
||||
return MsgPackError::Ok;
|
||||
return readInteger<int32_t>(variant);
|
||||
|
||||
case 0xd3:
|
||||
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||
variant = readInteger<int64_t>();
|
||||
return readInteger<int64_t>(variant);
|
||||
#else
|
||||
readInteger<int32_t>();
|
||||
variant = readInteger<int32_t>();
|
||||
if (!skip(4)) return MsgPackError::IncompleteInput;
|
||||
return readInteger<int32_t>(variant);
|
||||
#endif
|
||||
return MsgPackError::Ok;
|
||||
|
||||
case 0xca:
|
||||
variant = readFloat<float>();
|
||||
return MsgPackError::Ok;
|
||||
return readFloat<float>(variant);
|
||||
|
||||
case 0xcb:
|
||||
variant = readDouble<double>();
|
||||
return MsgPackError::Ok;
|
||||
return readDouble<double>(variant);
|
||||
|
||||
case 0xd9: {
|
||||
uint8_t n = readInteger<uint8_t>();
|
||||
return readString(variant, n);
|
||||
}
|
||||
case 0xd9:
|
||||
return readString<uint8_t>(variant);
|
||||
|
||||
case 0xda: {
|
||||
uint16_t n = readInteger<uint16_t>();
|
||||
return readString(variant, n);
|
||||
}
|
||||
case 0xda:
|
||||
return readString<uint16_t>(variant);
|
||||
|
||||
case 0xdb: {
|
||||
uint32_t n = readInteger<uint32_t>();
|
||||
return readString(variant, n);
|
||||
}
|
||||
case 0xdb:
|
||||
return readString<uint32_t>(variant);
|
||||
|
||||
case 0xdc:
|
||||
return readArray(variant, readInteger<uint16_t>());
|
||||
return readArray<uint16_t>(variant);
|
||||
|
||||
case 0xdd:
|
||||
return readArray(variant, readInteger<uint32_t>());
|
||||
return readArray<uint32_t>(variant);
|
||||
|
||||
case 0xde:
|
||||
return readObject(variant, readInteger<uint16_t>());
|
||||
return readObject<uint16_t>(variant);
|
||||
|
||||
case 0xdf:
|
||||
return readObject(variant, readInteger<uint32_t>());
|
||||
return readObject<uint32_t>(variant);
|
||||
|
||||
default:
|
||||
return MsgPackError::NotSupported;
|
||||
@ -148,65 +134,115 @@ class MsgPackDeserializer {
|
||||
// Prevent VS warning "assignment operator could not be generated"
|
||||
MsgPackDeserializer &operator=(const MsgPackDeserializer &);
|
||||
|
||||
uint8_t readOne() {
|
||||
char c = _reader.current();
|
||||
_reader.move();
|
||||
return static_cast<uint8_t>(c);
|
||||
bool skip(uint8_t n) {
|
||||
while (n--) {
|
||||
if (_reader.ended()) return false;
|
||||
_reader.read();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void read(uint8_t *p, size_t n) {
|
||||
for (size_t i = 0; i < n; i++) p[i] = readOne();
|
||||
bool readByte(uint8_t &value) {
|
||||
if (_reader.ended()) return false;
|
||||
value = static_cast<uint8_t>(_reader.read());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readBytes(uint8_t *p, size_t n) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (!readByte(p[i])) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void read(T &value) {
|
||||
read(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
||||
bool readBytes(T &value) {
|
||||
return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T readInteger() {
|
||||
T value;
|
||||
read(value);
|
||||
readBytes(value);
|
||||
fixEndianess(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename EnableIf<sizeof(T) == 4, T>::type readFloat() {
|
||||
bool readInteger(T &value) {
|
||||
if (!readBytes(value)) return false;
|
||||
fixEndianess(value);
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
MsgPackError readInteger(JsonVariant &variant) {
|
||||
T value;
|
||||
read(value);
|
||||
fixEndianess(value);
|
||||
return value;
|
||||
if (!readInteger(value)) return MsgPackError::IncompleteInput;
|
||||
variant = value;
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename EnableIf<sizeof(T) == 8, T>::type readDouble() {
|
||||
typename EnableIf<sizeof(T) == 4, MsgPackError>::type readFloat(
|
||||
JsonVariant &variant) {
|
||||
T value;
|
||||
read(value);
|
||||
if (!readBytes(value)) return MsgPackError::IncompleteInput;
|
||||
fixEndianess(value);
|
||||
return value;
|
||||
variant = value;
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename EnableIf<sizeof(T) == 4, T>::type readDouble() {
|
||||
typename EnableIf<sizeof(T) == 8, MsgPackError>::type readDouble(
|
||||
JsonVariant &variant) {
|
||||
T value;
|
||||
if (!readBytes(value)) return MsgPackError::IncompleteInput;
|
||||
fixEndianess(value);
|
||||
variant = value;
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename EnableIf<sizeof(T) == 4, MsgPackError>::type readDouble(
|
||||
JsonVariant &variant) {
|
||||
uint8_t i[8]; // input is 8 bytes
|
||||
T value; // output is 4 bytes
|
||||
uint8_t *o = reinterpret_cast<uint8_t *>(&value);
|
||||
read(i, 8);
|
||||
if (!readBytes(i, 8)) return MsgPackError::IncompleteInput;
|
||||
doubleToFloat(i, o);
|
||||
fixEndianess(value);
|
||||
return value;
|
||||
variant = value;
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
MsgPackError readString(JsonVariant &variant) {
|
||||
T size;
|
||||
if (!readInteger(size)) return MsgPackError::IncompleteInput;
|
||||
return readString(variant, size);
|
||||
}
|
||||
|
||||
MsgPackError readString(JsonVariant &variant, size_t n) {
|
||||
typename RemoveReference<TWriter>::type::String str = _writer.startString();
|
||||
for (; n; --n) str.append(static_cast<char>(readOne()));
|
||||
for (; n; --n) {
|
||||
uint8_t c;
|
||||
if (!readBytes(c)) return MsgPackError::IncompleteInput;
|
||||
str.append(static_cast<char>(c));
|
||||
}
|
||||
const char *s = str.c_str();
|
||||
if (s == NULL) return MsgPackError::NoMemory;
|
||||
variant = s;
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
MsgPackError readArray(JsonVariant &variant) {
|
||||
TSize size;
|
||||
if (!readInteger(size)) return MsgPackError::IncompleteInput;
|
||||
return readArray(variant, size);
|
||||
}
|
||||
|
||||
MsgPackError readArray(JsonVariant &variant, size_t n) {
|
||||
JsonArray *array = new (_buffer) JsonArray(_buffer);
|
||||
if (!array) return MsgPackError::NoMemory;
|
||||
@ -227,6 +263,13 @@ class MsgPackDeserializer {
|
||||
return MsgPackError::Ok;
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
MsgPackError readObject(JsonVariant &variant) {
|
||||
TSize size;
|
||||
if (!readInteger(size)) return MsgPackError::IncompleteInput;
|
||||
return readObject(variant, size);
|
||||
}
|
||||
|
||||
MsgPackError readObject(JsonVariant &variant, size_t n) {
|
||||
JsonObject *object = new (_buffer) JsonObject(_buffer);
|
||||
if (!object) return MsgPackError::NoMemory;
|
||||
@ -258,37 +301,11 @@ class MsgPackDeserializer {
|
||||
uint8_t _nestingLimit;
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TString, typename Enable = void>
|
||||
struct MsgPackDeserializerBuilder {
|
||||
typedef typename StringTraits<TString>::Reader InputReader;
|
||||
typedef MsgPackDeserializer<InputReader, TJsonBuffer &> TParser;
|
||||
|
||||
static TParser makeMsgPackDeserializer(TJsonBuffer *buffer, TString &json,
|
||||
uint8_t nestingLimit) {
|
||||
return TParser(buffer, InputReader(json), *buffer, nestingLimit);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TChar>
|
||||
struct MsgPackDeserializerBuilder<
|
||||
TJsonBuffer, TChar *, typename EnableIf<!IsConst<TChar>::value>::type> {
|
||||
typedef typename StringTraits<TChar *>::Reader TReader;
|
||||
typedef StringWriter<TChar> TWriter;
|
||||
typedef MsgPackDeserializer<TReader, TWriter> TParser;
|
||||
|
||||
static TParser makeMsgPackDeserializer(TJsonBuffer *buffer, TChar *json,
|
||||
uint8_t nestingLimit) {
|
||||
return TParser(buffer, TReader(json), TWriter(json), nestingLimit);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TString>
|
||||
inline typename MsgPackDeserializerBuilder<TJsonBuffer, TString>::TParser
|
||||
makeMsgPackDeserializer(TJsonBuffer *buffer, TString &json,
|
||||
uint8_t nestingLimit) {
|
||||
return MsgPackDeserializerBuilder<
|
||||
TJsonBuffer, TString>::makeMsgPackDeserializer(buffer, json,
|
||||
nestingLimit);
|
||||
template <typename TJsonBuffer, typename TReader, typename TWriter>
|
||||
MsgPackDeserializer<TReader, TWriter> makeMsgPackDeserializer(
|
||||
TJsonBuffer *buffer, TReader reader, TWriter writer, uint8_t nestingLimit) {
|
||||
return MsgPackDeserializer<TReader, TWriter>(buffer, reader, writer,
|
||||
nestingLimit);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
||||
|
@ -4,11 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
namespace ArduinoJson {
|
||||
|
||||
class MsgPackError {
|
||||
public:
|
||||
enum Code { Ok, NotSupported, NoMemory, TooDeep };
|
||||
enum Code { Ok, NotSupported, NoMemory, TooDeep, IncompleteInput };
|
||||
|
||||
MsgPackError() {}
|
||||
|
||||
@ -44,6 +48,8 @@ class MsgPackError {
|
||||
return "NoMemory";
|
||||
case TooDeep:
|
||||
return "TooDeep";
|
||||
case IncompleteInput:
|
||||
return "IncompleteInput";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
|
41
src/ArduinoJson/Reading/ArduinoStreamReader.hpp
Normal file
41
src/ArduinoJson/Reading/ArduinoStreamReader.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
struct ArduinoStreamReader {
|
||||
Stream& _stream;
|
||||
char _current;
|
||||
bool _ended;
|
||||
|
||||
public:
|
||||
explicit ArduinoStreamReader(Stream& stream)
|
||||
: _stream(stream), _current(0), _ended(false) {}
|
||||
|
||||
char read() {
|
||||
// don't use _stream.read() as it ignores the timeout
|
||||
char c = 0;
|
||||
_ended = _stream.readBytes(&c, 1) == 0;
|
||||
return c;
|
||||
}
|
||||
|
||||
bool ended() const {
|
||||
return _ended;
|
||||
}
|
||||
};
|
||||
|
||||
inline ArduinoStreamReader makeReader(Stream& input) {
|
||||
return ArduinoStreamReader(input);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
||||
|
||||
#endif
|
64
src/ArduinoJson/Reading/CharPointerReader.hpp
Normal file
64
src/ArduinoJson/Reading/CharPointerReader.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename TChar>
|
||||
class UnsafeCharPointerReader {
|
||||
const TChar* _ptr;
|
||||
|
||||
public:
|
||||
explicit UnsafeCharPointerReader(const TChar* ptr)
|
||||
: _ptr(ptr ? ptr : reinterpret_cast<const TChar*>("")) {}
|
||||
|
||||
char read() {
|
||||
return static_cast<char>(*_ptr++);
|
||||
}
|
||||
|
||||
bool ended() const {
|
||||
// we cannot know
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TChar>
|
||||
class SafeCharPointerReader {
|
||||
const TChar* _ptr;
|
||||
const TChar* _end;
|
||||
|
||||
public:
|
||||
explicit SafeCharPointerReader(const TChar* ptr, size_t len)
|
||||
: _ptr(ptr ? ptr : reinterpret_cast<const TChar*>("")),
|
||||
_end(_ptr + len) {}
|
||||
|
||||
char read() {
|
||||
return static_cast<char>(*_ptr++);
|
||||
}
|
||||
|
||||
bool ended() const {
|
||||
return _ptr == _end;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TChar>
|
||||
inline UnsafeCharPointerReader<TChar> makeReader(TChar* input) {
|
||||
return UnsafeCharPointerReader<TChar>(input);
|
||||
}
|
||||
|
||||
template <typename TChar>
|
||||
inline SafeCharPointerReader<TChar> makeReader(TChar* input, size_t n) {
|
||||
return SafeCharPointerReader<TChar>(input, n);
|
||||
}
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STRING
|
||||
inline SafeCharPointerReader<char> makeReader(const String& input) {
|
||||
return SafeCharPointerReader<char>(input.c_str(), input.length());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
56
src/ArduinoJson/Reading/FlashStringReader.hpp
Normal file
56
src/ArduinoJson/Reading/FlashStringReader.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_PROGMEM
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
class UnsafeFlashStringReader {
|
||||
const char* _ptr;
|
||||
|
||||
public:
|
||||
explicit UnsafeFlashStringReader(const __FlashStringHelper* ptr)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
||||
|
||||
char read() {
|
||||
return pgm_read_byte_near(_ptr++);
|
||||
}
|
||||
|
||||
bool ended() const {
|
||||
// this reader cannot detect the end
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class SafeFlashStringReader {
|
||||
const char* _ptr;
|
||||
const char* _end;
|
||||
|
||||
public:
|
||||
explicit SafeFlashStringReader(const __FlashStringHelper* ptr, size_t size)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {}
|
||||
|
||||
char read() {
|
||||
return pgm_read_byte_near(_ptr++);
|
||||
}
|
||||
|
||||
bool ended() const {
|
||||
return _ptr == _end;
|
||||
}
|
||||
};
|
||||
|
||||
inline UnsafeFlashStringReader makeReader(const __FlashStringHelper* input) {
|
||||
return UnsafeFlashStringReader(input);
|
||||
}
|
||||
|
||||
inline SafeFlashStringReader makeReader(const __FlashStringHelper* input,
|
||||
size_t size) {
|
||||
return SafeFlashStringReader(input, size);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
||||
|
||||
#endif
|
34
src/ArduinoJson/Reading/IteratorReader.hpp
Normal file
34
src/ArduinoJson/Reading/IteratorReader.hpp
Normal file
@ -0,0 +1,34 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename TIterator>
|
||||
class IteratorReader {
|
||||
TIterator _ptr, _end;
|
||||
|
||||
public:
|
||||
explicit IteratorReader(TIterator begin, TIterator end)
|
||||
: _ptr(begin), _end(end) {}
|
||||
|
||||
bool ended() const {
|
||||
return _ptr == _end;
|
||||
}
|
||||
|
||||
char read() {
|
||||
return char(*_ptr++);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TInput>
|
||||
inline IteratorReader<typename TInput::const_iterator> makeReader(
|
||||
const TInput& input) {
|
||||
return IteratorReader<typename TInput::const_iterator>(input.begin(),
|
||||
input.end());
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
11
src/ArduinoJson/Reading/Reader.hpp
Normal file
11
src/ArduinoJson/Reading/Reader.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "./ArduinoStreamReader.hpp"
|
||||
#include "./CharPointerReader.hpp"
|
||||
#include "./FlashStringReader.hpp"
|
||||
#include "./IteratorReader.hpp"
|
||||
#include "./StdStreamReader.hpp"
|
40
src/ArduinoJson/Reading/StdStreamReader.hpp
Normal file
40
src/ArduinoJson/Reading/StdStreamReader.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
class StdStreamReader {
|
||||
std::istream& _stream;
|
||||
char _current;
|
||||
|
||||
public:
|
||||
explicit StdStreamReader(std::istream& stream)
|
||||
: _stream(stream), _current(0) {}
|
||||
|
||||
bool ended() const {
|
||||
return _stream.eof();
|
||||
}
|
||||
|
||||
char read() {
|
||||
return static_cast<char>(_stream.get());
|
||||
}
|
||||
|
||||
private:
|
||||
StdStreamReader& operator=(const StdStreamReader&); // Visual Studio C4512
|
||||
};
|
||||
|
||||
inline StdStreamReader makeReader(std::istream& input) {
|
||||
return StdStreamReader(input);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
||||
|
||||
#endif
|
@ -1,61 +0,0 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_ARDUINO_STREAM
|
||||
|
||||
#include <Stream.h>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
struct ArduinoStreamTraits {
|
||||
class Reader {
|
||||
Stream& _stream;
|
||||
char _current, _next;
|
||||
|
||||
public:
|
||||
Reader(Stream& stream) : _stream(stream), _current(0), _next(0) {}
|
||||
|
||||
void move() {
|
||||
_current = _next;
|
||||
_next = 0;
|
||||
}
|
||||
|
||||
char current() {
|
||||
if (!_current) _current = read();
|
||||
return _current;
|
||||
}
|
||||
|
||||
char next() {
|
||||
// assumes that current() has been called
|
||||
if (!_next) _next = read();
|
||||
return _next;
|
||||
}
|
||||
|
||||
private:
|
||||
char read() {
|
||||
// don't use _stream.read() as it ignores the timeout
|
||||
char c = 0;
|
||||
_stream.readBytes(&c, 1);
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
static const bool has_append = false;
|
||||
static const bool has_equals = false;
|
||||
};
|
||||
|
||||
template <typename TStream>
|
||||
struct StringTraits<
|
||||
TStream,
|
||||
// match any type that is derived from Stream:
|
||||
typename EnableIf<
|
||||
IsBaseOf<Stream, typename RemoveReference<TStream>::type>::value>::type>
|
||||
: ArduinoStreamTraits {};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -9,26 +9,6 @@ namespace Internals {
|
||||
|
||||
template <typename TChar>
|
||||
struct CharPointerTraits {
|
||||
class Reader {
|
||||
const TChar* _ptr;
|
||||
|
||||
public:
|
||||
Reader(const TChar* ptr)
|
||||
: _ptr(ptr ? ptr : reinterpret_cast<const TChar*>("")) {}
|
||||
|
||||
void move() {
|
||||
++_ptr;
|
||||
}
|
||||
|
||||
char current() const {
|
||||
return char(_ptr[0]);
|
||||
}
|
||||
|
||||
char next() const {
|
||||
return char(_ptr[1]);
|
||||
}
|
||||
};
|
||||
|
||||
static bool equals(const TChar* str, const char* expected) {
|
||||
return strcmp(reinterpret_cast<const char*>(str), expected) == 0;
|
||||
}
|
||||
|
@ -10,26 +10,6 @@ namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
template <>
|
||||
struct StringTraits<const __FlashStringHelper*, void> {
|
||||
class Reader {
|
||||
const char* _ptr;
|
||||
|
||||
public:
|
||||
Reader(const __FlashStringHelper* ptr)
|
||||
: _ptr(reinterpret_cast<const char*>(ptr)) {}
|
||||
|
||||
void move() {
|
||||
_ptr++;
|
||||
}
|
||||
|
||||
char current() const {
|
||||
return pgm_read_byte_near(_ptr);
|
||||
}
|
||||
|
||||
char next() const {
|
||||
return pgm_read_byte_near(_ptr + 1);
|
||||
}
|
||||
};
|
||||
|
||||
static bool equals(const __FlashStringHelper* str, const char* expected) {
|
||||
return strcmp_P(expected, (const char*)str) == 0;
|
||||
}
|
||||
|
@ -1,60 +0,0 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||
|
||||
#include <istream>
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
struct StdStreamTraits {
|
||||
class Reader {
|
||||
std::istream& _stream;
|
||||
char _current, _next;
|
||||
|
||||
public:
|
||||
Reader(std::istream& stream) : _stream(stream), _current(0), _next(0) {}
|
||||
|
||||
void move() {
|
||||
_current = _next;
|
||||
_next = 0;
|
||||
}
|
||||
|
||||
char current() {
|
||||
if (!_current) _current = read();
|
||||
return _current;
|
||||
}
|
||||
|
||||
char next() {
|
||||
// assumes that current() has been called
|
||||
if (!_next) _next = read();
|
||||
return _next;
|
||||
}
|
||||
|
||||
private:
|
||||
Reader& operator=(const Reader&); // Visual Studio C4512
|
||||
|
||||
char read() {
|
||||
return _stream.eof() ? '\0' : static_cast<char>(_stream.get());
|
||||
}
|
||||
};
|
||||
|
||||
static const bool has_append = false;
|
||||
static const bool has_equals = false;
|
||||
};
|
||||
|
||||
template <typename TStream>
|
||||
struct StringTraits<
|
||||
TStream,
|
||||
// match any type that is derived from std::istream:
|
||||
typename EnableIf<IsBaseOf<
|
||||
std::istream, typename RemoveReference<TStream>::type>::value>::type>
|
||||
: StdStreamTraits {};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -35,10 +35,6 @@ struct StdStringTraits {
|
||||
return !str.c_str();
|
||||
}
|
||||
|
||||
struct Reader : CharPointerTraits<char>::Reader {
|
||||
Reader(const TString& str) : CharPointerTraits<char>::Reader(str.c_str()) {}
|
||||
};
|
||||
|
||||
static bool equals(const TString& str, const char* expected) {
|
||||
return 0 == strcmp(str.c_str(), expected);
|
||||
}
|
||||
|
@ -29,8 +29,6 @@ struct StringTraits<TString&, void> : StringTraits<TString> {};
|
||||
}
|
||||
}
|
||||
|
||||
#include "ArduinoStream.hpp"
|
||||
#include "CharPointer.hpp"
|
||||
#include "FlashString.hpp"
|
||||
#include "StdStream.hpp"
|
||||
#include "StdString.hpp"
|
||||
|
27
src/ArduinoJson/Writing/JsonBufferWriter.hpp
Normal file
27
src/ArduinoJson/Writing/JsonBufferWriter.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "./StringWriter.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename TJsonBuffer>
|
||||
class JsonBufferWriter {
|
||||
public:
|
||||
JsonBufferWriter(TJsonBuffer& jb) : _jb(&jb) {}
|
||||
|
||||
typedef typename TJsonBuffer::String String;
|
||||
|
||||
String startString() {
|
||||
return _jb->startString();
|
||||
}
|
||||
|
||||
private:
|
||||
TJsonBuffer* _jb;
|
||||
};
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
44
src/ArduinoJson/Writing/Writer.hpp
Normal file
44
src/ArduinoJson/Writing/Writer.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
// ArduinoJson - arduinojson.org
|
||||
// Copyright Benoit Blanchon 2014-2018
|
||||
// MIT License
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "./JsonBufferWriter.hpp"
|
||||
#include "./StringWriter.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
namespace Internals {
|
||||
|
||||
template <typename TJsonBuffer, typename TInput, typename Enable = void>
|
||||
struct Writer {
|
||||
typedef JsonBufferWriter<TJsonBuffer> type;
|
||||
|
||||
static type create(TJsonBuffer& jb, TInput&) {
|
||||
return type(jb);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TChar>
|
||||
struct Writer<TJsonBuffer, TChar*,
|
||||
typename EnableIf<!IsConst<TChar>::value>::type> {
|
||||
typedef StringWriter<TChar> type;
|
||||
|
||||
static type create(TJsonBuffer&, TChar* input) {
|
||||
return type(input);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename TJsonBuffer, typename TInput>
|
||||
typename Writer<TJsonBuffer, TInput>::type makeWriter(TJsonBuffer& jb,
|
||||
TInput& input) {
|
||||
return Writer<TJsonBuffer, TInput>::create(jb, input);
|
||||
}
|
||||
|
||||
template <typename TJsonBuffer, typename TChar>
|
||||
typename Writer<TJsonBuffer, TChar*>::type makeWriter(TJsonBuffer& jb,
|
||||
TChar* input) {
|
||||
return Writer<TJsonBuffer, TChar*>::create(jb, input);
|
||||
}
|
||||
} // namespace Internals
|
||||
} // namespace ArduinoJson
|
@ -5,34 +5,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "Json/Deserialization/JsonDeserializer.hpp"
|
||||
#include "Reading/Reader.hpp"
|
||||
#include "Writing/Writer.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
// JsonError deserializeJson(TDocument& doc, TString json);
|
||||
// JsonError deserializeJson(TDocument& doc, TString input);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TString = const std::string&, const String&
|
||||
template <typename TDocument, typename TString>
|
||||
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
|
||||
JsonError>::type
|
||||
deserializeJson(TDocument &doc, const TString &json) {
|
||||
return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit)
|
||||
deserializeJson(TDocument &doc, const TString &input) {
|
||||
using namespace Internals;
|
||||
return makeJsonDeserializer(&doc.buffer(), makeReader(input),
|
||||
makeWriter(doc.buffer(), input), doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
//
|
||||
// JsonError deserializeJson(TDocument& doc, TString json);
|
||||
// JsonError deserializeJson(TDocument& doc, TChar* input);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TString = const char*, const char[N], const FlashStringHelper*
|
||||
template <typename TDocument, typename TString>
|
||||
JsonError deserializeJson(TDocument &doc, TString *json) {
|
||||
return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit)
|
||||
// TChar* = char*, const char*, const FlashStringHelper*
|
||||
template <typename TDocument, typename TChar>
|
||||
JsonError deserializeJson(TDocument &doc, TChar *input) {
|
||||
using namespace Internals;
|
||||
return makeJsonDeserializer(&doc.buffer(), makeReader(input),
|
||||
makeWriter(doc.buffer(), input), doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
//
|
||||
// JsonError deserializeJson(TDocument& doc, TString json);
|
||||
// JsonError deserializeJson(TDocument& doc, TChar* input, size_t inputSize);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TString = std::istream&, Stream&
|
||||
template <typename TDocument, typename TString>
|
||||
JsonError deserializeJson(TDocument &doc, TString &json) {
|
||||
return Internals::makeParser(&doc.buffer(), json, doc.nestingLimit)
|
||||
// TChar* = char*, const char*, const FlashStringHelper*
|
||||
template <typename TDocument, typename TChar>
|
||||
JsonError deserializeJson(TDocument &doc, TChar *input, size_t inputSize) {
|
||||
using namespace Internals;
|
||||
return makeJsonDeserializer(&doc.buffer(), makeReader(input, inputSize),
|
||||
makeWriter(doc.buffer(), input), doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
//
|
||||
// JsonError deserializeJson(TDocument& doc, TStream input);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TStream = std::istream&, Stream&
|
||||
template <typename TDocument, typename TStream>
|
||||
JsonError deserializeJson(TDocument &doc, TStream &input) {
|
||||
using namespace Internals;
|
||||
return makeJsonDeserializer(&doc.buffer(), makeReader(input),
|
||||
makeWriter(doc.buffer(), input), doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
} // namespace ArduinoJson
|
||||
|
@ -5,37 +5,59 @@
|
||||
#pragma once
|
||||
|
||||
#include "MsgPack/MsgPackDeserializer.hpp"
|
||||
#include "Reading/Reader.hpp"
|
||||
#include "Writing/Writer.hpp"
|
||||
|
||||
namespace ArduinoJson {
|
||||
// MsgPackError deserializeMsgPack(TDocument& doc, TString json);
|
||||
// TDocument = DynamicJsonArray | StaticJsonArray
|
||||
// MsgPackError deserializeMsgPack(TDocument& doc, TString input);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TString = const std::string&, const String&
|
||||
template <typename TDocument, typename TString>
|
||||
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
|
||||
MsgPackError>::type
|
||||
deserializeMsgPack(TDocument &doc, const TString &json) {
|
||||
return Internals::makeMsgPackDeserializer(&doc.buffer(), json,
|
||||
doc.nestingLimit)
|
||||
deserializeMsgPack(TDocument &doc, const TString &input) {
|
||||
using namespace Internals;
|
||||
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input),
|
||||
makeWriter(doc.buffer(), input),
|
||||
doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
//
|
||||
// MsgPackError deserializeMsgPack(TDocument& doc, TString json);
|
||||
// TDocument = DynamicJsonArray | StaticJsonArray
|
||||
// TString = const char*, const char[N], const FlashStringHelper*
|
||||
template <typename TDocument, typename TString>
|
||||
MsgPackError deserializeMsgPack(TDocument &doc, TString *json) {
|
||||
return Internals::makeMsgPackDeserializer(&doc.buffer(), json,
|
||||
doc.nestingLimit)
|
||||
// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TChar* = char*, const char*, const FlashStringHelper*
|
||||
template <typename TDocument, typename TChar>
|
||||
MsgPackError deserializeMsgPack(TDocument &doc, TChar *input) {
|
||||
using namespace Internals;
|
||||
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input),
|
||||
makeWriter(doc.buffer(), input),
|
||||
doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
//
|
||||
// MsgPackError deserializeMsgPack(TDocument& doc, TString json);
|
||||
// TDocument = DynamicJsonArray | StaticJsonArray
|
||||
// TString = std::istream&, Stream&
|
||||
template <typename TDocument, typename TString>
|
||||
MsgPackError deserializeMsgPack(TDocument &doc, TString &json) {
|
||||
return Internals::makeMsgPackDeserializer(&doc.buffer(), json,
|
||||
doc.nestingLimit)
|
||||
// MsgPackError deserializeMsgPack(TDocument& doc, TChar* input, size_t
|
||||
// inputSize);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TChar* = char*, const char*, const FlashStringHelper*
|
||||
template <typename TDocument, typename TChar>
|
||||
MsgPackError deserializeMsgPack(TDocument &doc, TChar *input,
|
||||
size_t inputSize) {
|
||||
using namespace Internals;
|
||||
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input, inputSize),
|
||||
makeWriter(doc.buffer(), input),
|
||||
doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
//
|
||||
// MsgPackError deserializeMsgPack(TDocument& doc, TStream input);
|
||||
// TDocument = DynamicJsonDocument, StaticJsonDocument
|
||||
// TStream = std::istream&, Stream&
|
||||
template <typename TDocument, typename TStream>
|
||||
MsgPackError deserializeMsgPack(TDocument &doc, TStream &input) {
|
||||
using namespace Internals;
|
||||
return makeMsgPackDeserializer(&doc.buffer(), makeReader(input),
|
||||
makeWriter(doc.buffer(), input),
|
||||
doc.nestingLimit)
|
||||
.parse(doc.template to<JsonVariant>());
|
||||
}
|
||||
} // namespace ArduinoJson
|
||||
|
Reference in New Issue
Block a user