Added deserializeMsgPack() (issue #358)

This commit is contained in:
Benoit Blanchon
2018-04-10 17:43:27 +02:00
parent 923d3e8a84
commit cb723840d9
58 changed files with 1311 additions and 89 deletions

View File

@@ -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;
}
}
}
}
}

View File

@@ -1,95 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "../JsonError.hpp"
#include "../JsonVariant.hpp"
#include "../Memory/JsonBuffer.hpp"
#include "../TypeTraits/IsConst.hpp"
#include "StringWriter.hpp"
namespace ArduinoJson {
namespace Internals {
// Parse JSON string to create JsonArrays and JsonObjects
// This internal class is not indended to be used directly.
// Instead, use JsonBuffer.parseArray() or .parseObject()
template <typename TReader, typename TWriter>
class JsonParser {
public:
JsonParser(JsonBuffer *buffer, TReader reader, TWriter writer,
uint8_t nestingLimit)
: _buffer(buffer),
_reader(reader),
_writer(writer),
_nestingLimit(nestingLimit) {}
JsonError parse(JsonArray &destination);
JsonError parse(JsonObject &destination);
JsonError parse(JsonVariant &destination);
private:
JsonParser &operator=(const JsonParser &); // non-copiable
static bool eat(TReader &, char charToSkip);
FORCE_INLINE bool eat(char charToSkip) {
return eat(_reader, charToSkip);
}
const char *parseString();
JsonError parseArray(JsonVariant &variant);
JsonError parseObject(JsonVariant &variant);
JsonError parseValue(JsonVariant &variant);
static inline bool isBetween(char c, char min, char max) {
return min <= c && c <= max;
}
static inline bool canBeInNonQuotedString(char c) {
return isBetween(c, '0', '9') || isBetween(c, '_', 'z') ||
isBetween(c, 'A', 'Z') || c == '+' || c == '-' || c == '.';
}
static inline bool isQuote(char c) {
return c == '\'' || c == '\"';
}
JsonBuffer *_buffer;
TReader _reader;
TWriter _writer;
uint8_t _nestingLimit;
};
template <typename TJsonBuffer, typename TString, typename Enable = void>
struct JsonParserBuilder {
typedef typename StringTraits<TString>::Reader InputReader;
typedef JsonParser<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 JsonParser<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);
}
} // namespace Internals
} // namespace ArduinoJson

View File

@@ -1,166 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
#include "../Data/Encoding.hpp"
#include "Comments.hpp"
#include "JsonParser.hpp"
template <typename TReader, typename TWriter>
inline bool ArduinoJson::Internals::JsonParser<TReader, TWriter>::eat(
TReader &reader, char charToSkip) {
skipSpacesAndComments(reader);
if (reader.current() != charToSkip) return false;
reader.move();
return true;
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonError
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(JsonArray &array) {
if (_nestingLimit == 0) return JsonError::TooDeep;
// Check opening braket
if (!eat('[')) return JsonError::OpeningBracketExpected;
if (eat(']')) return JsonError::Ok;
// Read each value
for (;;) {
// 1 - Parse value
JsonVariant value;
_nestingLimit--;
JsonError error = parse(value);
_nestingLimit++;
if (error != JsonError::Ok) return error;
if (!array.add(value)) return JsonError::NoMemory;
// 2 - More values?
if (eat(']')) return JsonError::Ok;
if (!eat(',')) return JsonError::ClosingBracketExpected;
}
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonError
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
JsonObject &object) {
if (_nestingLimit == 0) return JsonError::TooDeep;
// Check opening brace
if (!eat('{')) return JsonError::OpeningBraceExpected;
if (eat('}')) return JsonError::Ok;
// Read each key value pair
for (;;) {
// 1 - Parse key
const char *key = parseString();
if (!key) return JsonError::NoMemory;
if (!eat(':')) return JsonError::ColonExpected;
// 2 - Parse value
JsonVariant value;
_nestingLimit--;
JsonError error = parse(value);
_nestingLimit++;
if (error != JsonError::Ok) return error;
if (!object.set(key, value)) return JsonError::NoMemory;
// 3 - More keys/values?
if (eat('}')) return JsonError::Ok;
if (!eat(',')) return JsonError::ClosingBraceExpected;
}
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonError
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parse(
JsonVariant &variant) {
skipSpacesAndComments(_reader);
switch (_reader.current()) {
case '[':
return parseArray(variant);
case '{':
return parseObject(variant);
default:
return parseValue(variant);
}
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonError
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseArray(
JsonVariant &variant) {
JsonArray *array = new (_buffer) JsonArray(_buffer);
if (!array) return JsonError::NoMemory;
variant = array;
return parse(*array);
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonError
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseObject(
JsonVariant &variant) {
JsonObject *object = new (_buffer) JsonObject(_buffer);
if (!object) return JsonError::NoMemory;
variant = object;
return parse(*object);
}
template <typename TReader, typename TWriter>
inline ArduinoJson::JsonError
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseValue(
JsonVariant &variant) {
bool hasQuotes = isQuote(_reader.current());
const char *value = parseString();
if (value == NULL) return JsonError::NoMemory;
if (hasQuotes) {
variant = value;
} else {
variant = RawJson(value);
}
return JsonError::Ok;
}
template <typename TReader, typename TWriter>
inline const char *
ArduinoJson::Internals::JsonParser<TReader, TWriter>::parseString() {
typename RemoveReference<TWriter>::type::String str = _writer.startString();
skipSpacesAndComments(_reader);
char c = _reader.current();
if (isQuote(c)) { // quotes
_reader.move();
char stopChar = c;
for (;;) {
c = _reader.current();
if (c == '\0') break;
_reader.move();
if (c == stopChar) break;
if (c == '\\') {
// replace char
c = Encoding::unescapeChar(_reader.current());
if (c == '\0') break;
_reader.move();
}
str.append(c);
}
} else { // no quotes
for (;;) {
if (!canBeInNonQuotedString(c)) break;
_reader.move();
str.append(c);
c = _reader.current();
}
}
return str.c_str();
}

View File

@@ -1,41 +0,0 @@
// ArduinoJson - arduinojson.org
// Copyright Benoit Blanchon 2014-2018
// MIT License
#pragma once
namespace ArduinoJson {
namespace Internals {
template <typename TChar>
class StringWriter {
public:
class String {
public:
String(TChar** ptr) : _writePtr(ptr), _startPtr(*ptr) {}
void append(char c) {
*(*_writePtr)++ = TChar(c);
}
const char* c_str() const {
*(*_writePtr)++ = 0;
return reinterpret_cast<const char*>(_startPtr);
}
private:
TChar** _writePtr;
TChar* _startPtr;
};
StringWriter(TChar* buffer) : _ptr(buffer) {}
String startString() {
return String(&_ptr);
}
private:
TChar* _ptr;
};
}
}