forked from bblanchon/ArduinoJson
Added deserializeMsgPack()
(issue #358)
This commit is contained in:
@ -2,12 +2,6 @@ sudo: false
|
|||||||
language: cpp
|
language: cpp
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- compiler: gcc
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
sources: ['ubuntu-toolchain-r-test']
|
|
||||||
packages: ['g++-4.4']
|
|
||||||
env: SCRIPT=cmake GCC=4.4
|
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
@ -12,6 +12,7 @@ HEAD
|
|||||||
* Added `deserializeJson()`
|
* Added `deserializeJson()`
|
||||||
* Added `serializeJson()` and `serializeJsonPretty()`
|
* Added `serializeJson()` and `serializeJsonPretty()`
|
||||||
* Added `measureJson()` and `measureJsonPretty()`
|
* Added `measureJson()` and `measureJsonPretty()`
|
||||||
|
* Added `deserializeMsgPack()` (issue #358)
|
||||||
* Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()`
|
* Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()`
|
||||||
* Removed `JsonBuffer::createArray()` and `createObject()`
|
* Removed `JsonBuffer::createArray()` and `createObject()`
|
||||||
* Removed `printTo()` and `prettyPrintTo()`
|
* Removed `printTo()` and `prettyPrintTo()`
|
||||||
|
@ -7,13 +7,15 @@
|
|||||||
#include "ArduinoJson/DynamicJsonArray.hpp"
|
#include "ArduinoJson/DynamicJsonArray.hpp"
|
||||||
#include "ArduinoJson/DynamicJsonObject.hpp"
|
#include "ArduinoJson/DynamicJsonObject.hpp"
|
||||||
#include "ArduinoJson/DynamicJsonVariant.hpp"
|
#include "ArduinoJson/DynamicJsonVariant.hpp"
|
||||||
|
#include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp"
|
||||||
#include "ArduinoJson/StaticJsonArray.hpp"
|
#include "ArduinoJson/StaticJsonArray.hpp"
|
||||||
#include "ArduinoJson/StaticJsonObject.hpp"
|
#include "ArduinoJson/StaticJsonObject.hpp"
|
||||||
#include "ArduinoJson/StaticJsonVariant.hpp"
|
#include "ArduinoJson/StaticJsonVariant.hpp"
|
||||||
#include "ArduinoJson/deserializeJson.hpp"
|
#include "ArduinoJson/deserializeJson.hpp"
|
||||||
|
#include "ArduinoJson/deserializeMsgPack.hpp"
|
||||||
|
|
||||||
#include "ArduinoJson/Deserialization/JsonParserImpl.hpp"
|
#include "ArduinoJson/Json/Deserialization/JsonParserImpl.hpp"
|
||||||
|
#include "ArduinoJson/Json/Serialization/JsonSerializerImpl.hpp"
|
||||||
#include "ArduinoJson/JsonArrayImpl.hpp"
|
#include "ArduinoJson/JsonArrayImpl.hpp"
|
||||||
#include "ArduinoJson/JsonObjectImpl.hpp"
|
#include "ArduinoJson/JsonObjectImpl.hpp"
|
||||||
#include "ArduinoJson/JsonVariantImpl.hpp"
|
#include "ArduinoJson/JsonVariantImpl.hpp"
|
||||||
#include "ArduinoJson/Serialization/JsonSerializerImpl.hpp"
|
|
||||||
|
@ -144,3 +144,13 @@
|
|||||||
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
|
#if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64
|
||||||
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
|
#error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef ARDUINOJSON_LITTLE_ENDIAN
|
||||||
|
#if defined(_MSC_VER) || \
|
||||||
|
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
|
||||||
|
(defined(__LITTLE_ENDIAN__))
|
||||||
|
#define ARDUINOJSON_LITTLE_ENDIAN 1
|
||||||
|
#else
|
||||||
|
#define ARDUINOJSON_LITTLE_ENDIAN 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "../JsonVariant.hpp"
|
#include "../JsonVariant.hpp"
|
||||||
#include "../Memory/JsonBuffer.hpp"
|
#include "../Memory/JsonBuffer.hpp"
|
||||||
#include "../StringTraits/StringTraits.hpp"
|
#include "../Strings/StringTraits.hpp"
|
||||||
#include "../TypeTraits/EnableIf.hpp"
|
#include "../TypeTraits/EnableIf.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../JsonError.hpp"
|
#include "../../JsonError.hpp"
|
||||||
#include "../JsonVariant.hpp"
|
#include "../../JsonVariant.hpp"
|
||||||
#include "../Memory/JsonBuffer.hpp"
|
#include "../../Memory/JsonBuffer.hpp"
|
||||||
#include "../TypeTraits/IsConst.hpp"
|
#include "../../Strings/StringWriter.hpp"
|
||||||
#include "StringWriter.hpp"
|
#include "../../TypeTraits/IsConst.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Data/Encoding.hpp"
|
#include "../Encoding.hpp"
|
||||||
#include "Comments.hpp"
|
#include "Comments.hpp"
|
||||||
#include "JsonParser.hpp"
|
#include "JsonParser.hpp"
|
||||||
|
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../Configuration.hpp"
|
#include "../../Configuration.hpp"
|
||||||
#include "../Polyfills/math.hpp"
|
#include "../../Polyfills/math.hpp"
|
||||||
#include "../TypeTraits/FloatTraits.hpp"
|
#include "../../TypeTraits/FloatTraits.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -85,5 +85,5 @@ struct FloatParts {
|
|||||||
return powersOf10;
|
return powersOf10;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
@ -4,15 +4,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "DummyPrint.hpp"
|
#include "../../Print/DummyPrint.hpp"
|
||||||
#include "DynamicStringBuilder.hpp"
|
#include "../../Print/DynamicStringBuilder.hpp"
|
||||||
#include "IndentedPrint.hpp"
|
#include "../../Print/StaticStringBuilder.hpp"
|
||||||
#include "JsonWriter.hpp"
|
#include "./IndentedPrint.hpp"
|
||||||
#include "Prettyfier.hpp"
|
#include "./JsonWriter.hpp"
|
||||||
#include "StaticStringBuilder.hpp"
|
#include "./Prettyfier.hpp"
|
||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
#include "StreamPrintAdapter.hpp"
|
#include "../../Print/StreamPrintAdapter.hpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
@ -4,11 +4,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../JsonArray.hpp"
|
#include "../../JsonArray.hpp"
|
||||||
#include "../JsonArraySubscript.hpp"
|
#include "../../JsonArraySubscript.hpp"
|
||||||
#include "../JsonObject.hpp"
|
#include "../../JsonObject.hpp"
|
||||||
#include "../JsonObjectSubscript.hpp"
|
#include "../../JsonObjectSubscript.hpp"
|
||||||
#include "../JsonVariant.hpp"
|
#include "../../JsonVariant.hpp"
|
||||||
#include "JsonSerializer.hpp"
|
#include "JsonSerializer.hpp"
|
||||||
|
|
||||||
template <typename Writer>
|
template <typename Writer>
|
@ -5,10 +5,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "../Data/Encoding.hpp"
|
#include "../../Data/JsonInteger.hpp"
|
||||||
#include "../Data/JsonInteger.hpp"
|
#include "../../Polyfills/attributes.hpp"
|
||||||
#include "../Polyfills/attributes.hpp"
|
#include "../Encoding.hpp"
|
||||||
#include "../Serialization/FloatParts.hpp"
|
#include "./FloatParts.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
@ -9,7 +9,7 @@
|
|||||||
#include "Data/ValueSaver.hpp"
|
#include "Data/ValueSaver.hpp"
|
||||||
#include "JsonVariant.hpp"
|
#include "JsonVariant.hpp"
|
||||||
#include "Memory/JsonBufferAllocated.hpp"
|
#include "Memory/JsonBufferAllocated.hpp"
|
||||||
#include "StringTraits/StringTraits.hpp"
|
#include "Strings/StringTraits.hpp"
|
||||||
#include "TypeTraits/EnableIf.hpp"
|
#include "TypeTraits/EnableIf.hpp"
|
||||||
#include "TypeTraits/IsArray.hpp"
|
#include "TypeTraits/IsArray.hpp"
|
||||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||||
|
@ -42,15 +42,7 @@ class JsonError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char* c_str() const {
|
const char* c_str() const {
|
||||||
return to_string(_code);
|
switch (_code) {
|
||||||
}
|
|
||||||
|
|
||||||
friend const char* to_string(const JsonError err) {
|
|
||||||
return to_string(err._code);
|
|
||||||
}
|
|
||||||
|
|
||||||
friend const char* to_string(JsonError::Code code) {
|
|
||||||
switch (code) {
|
|
||||||
case Ok:
|
case Ok:
|
||||||
return "Ok";
|
return "Ok";
|
||||||
case OpeningBraceExpected:
|
case OpeningBraceExpected:
|
||||||
@ -78,12 +70,7 @@ class JsonError {
|
|||||||
|
|
||||||
#if ARDUINOJSON_ENABLE_STD_STREAM
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
inline std::ostream& operator<<(std::ostream& s, const JsonError& e) {
|
inline std::ostream& operator<<(std::ostream& s, const JsonError& e) {
|
||||||
s << to_string(e);
|
s << e.c_str();
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& s, JsonError::Code e) {
|
|
||||||
s << to_string(e);
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "Data/ValueSaver.hpp"
|
#include "Data/ValueSaver.hpp"
|
||||||
#include "JsonPair.hpp"
|
#include "JsonPair.hpp"
|
||||||
#include "Memory/JsonBufferAllocated.hpp"
|
#include "Memory/JsonBufferAllocated.hpp"
|
||||||
#include "StringTraits/StringTraits.hpp"
|
#include "Strings/StringTraits.hpp"
|
||||||
#include "TypeTraits/EnableIf.hpp"
|
#include "TypeTraits/EnableIf.hpp"
|
||||||
#include "TypeTraits/IsArray.hpp"
|
#include "TypeTraits/IsArray.hpp"
|
||||||
#include "TypeTraits/IsFloatingPoint.hpp"
|
#include "TypeTraits/IsFloatingPoint.hpp"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "StringTraits/StringTraits.hpp"
|
#include "Strings/StringTraits.hpp"
|
||||||
#include "TypeTraits/EnableIf.hpp"
|
#include "TypeTraits/EnableIf.hpp"
|
||||||
#include "TypeTraits/IsVariant.hpp"
|
#include "TypeTraits/IsVariant.hpp"
|
||||||
|
|
||||||
@ -134,5 +134,5 @@ class JsonVariantComparisons {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
||||||
|
@ -8,10 +8,10 @@
|
|||||||
#include "JsonArray.hpp"
|
#include "JsonArray.hpp"
|
||||||
#include "JsonObject.hpp"
|
#include "JsonObject.hpp"
|
||||||
#include "JsonVariant.hpp"
|
#include "JsonVariant.hpp"
|
||||||
#include "Polyfills/isFloat.hpp"
|
#include "Text/isFloat.hpp"
|
||||||
#include "Polyfills/isInteger.hpp"
|
#include "Text/isInteger.hpp"
|
||||||
#include "Polyfills/parseFloat.hpp"
|
#include "Text/parseFloat.hpp"
|
||||||
#include "Polyfills/parseInteger.hpp"
|
#include "Text/parseInteger.hpp"
|
||||||
|
|
||||||
#include <string.h> // for strcmp
|
#include <string.h> // for strcmp
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "Data/JsonVariantAs.hpp"
|
#include "Data/JsonVariantAs.hpp"
|
||||||
#include "Polyfills/attributes.hpp"
|
#include "Polyfills/attributes.hpp"
|
||||||
#include "StringTraits/StringTraits.hpp"
|
#include "Strings/StringTraits.hpp"
|
||||||
#include "TypeTraits/EnableIf.hpp"
|
#include "TypeTraits/EnableIf.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
@ -82,5 +82,5 @@ class JsonVariantSubscripts {
|
|||||||
return static_cast<const TImpl *>(this);
|
return static_cast<const TImpl *>(this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
||||||
|
328
src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp
Normal file
328
src/ArduinoJson/MsgPack/MsgPackDeserializer.hpp
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../JsonVariant.hpp"
|
||||||
|
#include "../Memory/JsonBuffer.hpp"
|
||||||
|
#include "../Strings/StringWriter.hpp"
|
||||||
|
#include "../TypeTraits/IsConst.hpp"
|
||||||
|
#include "./MsgPackError.hpp"
|
||||||
|
#include "./endianess.hpp"
|
||||||
|
#include "./ieee754.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 MsgPackDeserializer {
|
||||||
|
public:
|
||||||
|
MsgPackDeserializer(JsonBuffer *buffer, TReader reader, TWriter writer,
|
||||||
|
uint8_t nestingLimit)
|
||||||
|
: _buffer(buffer),
|
||||||
|
_reader(reader),
|
||||||
|
_writer(writer),
|
||||||
|
_nestingLimit(nestingLimit) {}
|
||||||
|
|
||||||
|
MsgPackError parse(JsonArray &array) {
|
||||||
|
uint8_t c = readOne();
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if ((c & 0xF0) == 0x90) {
|
||||||
|
n = c & 0x0F;
|
||||||
|
} else if (c == 0xdc) {
|
||||||
|
n = readInteger<uint16_t>();
|
||||||
|
} else if (c == 0xdd) {
|
||||||
|
n = readInteger<uint32_t>();
|
||||||
|
} else {
|
||||||
|
return MsgPackError::NotAnArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
return readArray(array, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgPackError parse(JsonObject &object) {
|
||||||
|
uint8_t c = readOne();
|
||||||
|
size_t n;
|
||||||
|
|
||||||
|
if ((c & 0xf0) == 0x80) {
|
||||||
|
n = c & 0x0f;
|
||||||
|
} else if (c == 0xde) {
|
||||||
|
n = readInteger<uint16_t>();
|
||||||
|
} else if (c == 0xdf) {
|
||||||
|
n = readInteger<uint32_t>();
|
||||||
|
} else {
|
||||||
|
return MsgPackError::NotAnObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
return readObject(object, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgPackError parse(JsonVariant &variant) {
|
||||||
|
uint8_t c = readOne();
|
||||||
|
|
||||||
|
if ((c & 0x80) == 0) {
|
||||||
|
variant = c;
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c & 0xe0) == 0xe0) {
|
||||||
|
variant = static_cast<int8_t>(c);
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c & 0xe0) == 0xa0) {
|
||||||
|
return readString(variant, c & 0x1f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((c & 0xf0) == 0x90) return readArray(variant, c & 0x0F);
|
||||||
|
|
||||||
|
if ((c & 0xf0) == 0x80) return readObject(variant, c & 0x0F);
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case 0xc0:
|
||||||
|
variant = static_cast<char *>(0);
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xc2:
|
||||||
|
variant = false;
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xc3:
|
||||||
|
variant = true;
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xcc:
|
||||||
|
variant = readInteger<uint8_t>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xcd:
|
||||||
|
variant = readInteger<uint16_t>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xce:
|
||||||
|
variant = readInteger<uint32_t>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xcf:
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||||
|
variant = readInteger<uint64_t>();
|
||||||
|
#else
|
||||||
|
readInteger<uint32_t>();
|
||||||
|
variant = readInteger<uint32_t>();
|
||||||
|
#endif
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xd0:
|
||||||
|
variant = readInteger<int8_t>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xd1:
|
||||||
|
variant = readInteger<int16_t>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xd2:
|
||||||
|
variant = readInteger<int32_t>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xd3:
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||||
|
variant = readInteger<int64_t>();
|
||||||
|
#else
|
||||||
|
readInteger<int32_t>();
|
||||||
|
variant = readInteger<int32_t>();
|
||||||
|
#endif
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xca:
|
||||||
|
variant = readFloat<float>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xcb:
|
||||||
|
variant = readDouble<double>();
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
|
||||||
|
case 0xd9: {
|
||||||
|
uint8_t n = readInteger<uint8_t>();
|
||||||
|
return readString(variant, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xda: {
|
||||||
|
uint16_t n = readInteger<uint16_t>();
|
||||||
|
return readString(variant, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xdb: {
|
||||||
|
uint32_t n = readInteger<uint32_t>();
|
||||||
|
return readString(variant, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0xdc:
|
||||||
|
return readArray(variant, readInteger<uint16_t>());
|
||||||
|
|
||||||
|
case 0xdd:
|
||||||
|
return readArray(variant, readInteger<uint32_t>());
|
||||||
|
|
||||||
|
case 0xde:
|
||||||
|
return readObject(variant, readInteger<uint16_t>());
|
||||||
|
|
||||||
|
case 0xdf:
|
||||||
|
return readObject(variant, readInteger<uint32_t>());
|
||||||
|
|
||||||
|
default:
|
||||||
|
return MsgPackError::NotSupported;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read(uint8_t *p, size_t n) {
|
||||||
|
for (size_t i = 0; i < n; i++) p[i] = readOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void read(T &value) {
|
||||||
|
read(reinterpret_cast<uint8_t *>(&value), sizeof(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T readInteger() {
|
||||||
|
T value;
|
||||||
|
read(value);
|
||||||
|
fixEndianess(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename EnableIf<sizeof(T) == 4, T>::type readFloat() {
|
||||||
|
T value;
|
||||||
|
read(value);
|
||||||
|
fixEndianess(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename EnableIf<sizeof(T) == 8, T>::type readDouble() {
|
||||||
|
T value;
|
||||||
|
read(value);
|
||||||
|
fixEndianess(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
typename EnableIf<sizeof(T) == 4, T>::type readDouble() {
|
||||||
|
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);
|
||||||
|
doubleToFloat(i, o);
|
||||||
|
fixEndianess(value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgPackError readString(JsonVariant &variant, size_t n) {
|
||||||
|
typename RemoveReference<TWriter>::type::String str = _writer.startString();
|
||||||
|
for (; n; --n) str.append(static_cast<char>(readOne()));
|
||||||
|
const char *s = str.c_str();
|
||||||
|
if (s == NULL) return MsgPackError::NoMemory;
|
||||||
|
variant = s;
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgPackError readArray(JsonVariant &variant, size_t n) {
|
||||||
|
JsonArray *array = new (_buffer) JsonArray(_buffer);
|
||||||
|
if (!array) return MsgPackError::NoMemory;
|
||||||
|
variant = array;
|
||||||
|
return readArray(*array, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgPackError readArray(JsonArray &array, size_t n) {
|
||||||
|
if (_nestingLimit == 0) return MsgPackError::TooDeep;
|
||||||
|
--_nestingLimit;
|
||||||
|
for (; n; --n) {
|
||||||
|
JsonVariant variant;
|
||||||
|
MsgPackError err = parse(variant);
|
||||||
|
if (err) return err;
|
||||||
|
if (!array.add(variant)) return MsgPackError::NoMemory;
|
||||||
|
}
|
||||||
|
++_nestingLimit;
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgPackError readObject(JsonVariant &variant, size_t n) {
|
||||||
|
JsonObject *object = new (_buffer) JsonObject(_buffer);
|
||||||
|
if (!object) return MsgPackError::NoMemory;
|
||||||
|
variant = object;
|
||||||
|
return readObject(*object, n);
|
||||||
|
}
|
||||||
|
|
||||||
|
MsgPackError readObject(JsonObject &object, size_t n) {
|
||||||
|
if (_nestingLimit == 0) return MsgPackError::TooDeep;
|
||||||
|
--_nestingLimit;
|
||||||
|
for (; n; --n) {
|
||||||
|
MsgPackError err;
|
||||||
|
JsonVariant variant;
|
||||||
|
err = parse(variant);
|
||||||
|
if (err) return err;
|
||||||
|
const char *key = variant.as<char *>();
|
||||||
|
if (!key) return MsgPackError::NotSupported;
|
||||||
|
err = parse(variant);
|
||||||
|
if (err) return err;
|
||||||
|
if (!object.set(key, variant)) return MsgPackError::NoMemory;
|
||||||
|
}
|
||||||
|
++_nestingLimit;
|
||||||
|
return MsgPackError::Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonBuffer *_buffer;
|
||||||
|
TReader _reader;
|
||||||
|
TWriter _writer;
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
67
src/ArduinoJson/MsgPack/MsgPackError.hpp
Normal file
67
src/ArduinoJson/MsgPack/MsgPackError.hpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
|
||||||
|
class MsgPackError {
|
||||||
|
public:
|
||||||
|
enum Code { Ok, NotSupported, NoMemory, NotAnArray, NotAnObject, TooDeep };
|
||||||
|
|
||||||
|
MsgPackError() {}
|
||||||
|
|
||||||
|
MsgPackError(Code code) : _code(code) {}
|
||||||
|
|
||||||
|
operator bool() const {
|
||||||
|
return _code != Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(const MsgPackError& err, Code code) {
|
||||||
|
return err._code == code;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator==(Code code, const MsgPackError& err) {
|
||||||
|
return err._code == code;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(const MsgPackError& err, Code code) {
|
||||||
|
return err._code != code;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend bool operator!=(Code code, const MsgPackError& err) {
|
||||||
|
return err._code != code;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* c_str() const {
|
||||||
|
switch (_code) {
|
||||||
|
case Ok:
|
||||||
|
return "Ok";
|
||||||
|
case NotSupported:
|
||||||
|
return "NotSupported";
|
||||||
|
case NoMemory:
|
||||||
|
return "NoMemory";
|
||||||
|
case NotAnArray:
|
||||||
|
return "NotAnArray";
|
||||||
|
case NotAnObject:
|
||||||
|
return "NotAnObject";
|
||||||
|
case TooDeep:
|
||||||
|
return "TooDeep";
|
||||||
|
default:
|
||||||
|
return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Code _code;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if ARDUINOJSON_ENABLE_STD_STREAM
|
||||||
|
inline std::ostream& operator<<(std::ostream& os, const MsgPackError& err) {
|
||||||
|
os << err.c_str();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // namespace ArduinoJson
|
47
src/ArduinoJson/MsgPack/endianess.hpp
Normal file
47
src/ArduinoJson/MsgPack/endianess.hpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
template <class T, T v>
|
||||||
|
struct integral_constant {};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void swap(T& a, T& b) {
|
||||||
|
T t(a);
|
||||||
|
a = b;
|
||||||
|
b = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 8>) {
|
||||||
|
swap(p[0], p[7]);
|
||||||
|
swap(p[1], p[6]);
|
||||||
|
swap(p[2], p[5]);
|
||||||
|
swap(p[3], p[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 4>) {
|
||||||
|
swap(p[0], p[3]);
|
||||||
|
swap(p[1], p[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fixEndianess(uint8_t* p, integral_constant<size_t, 2>) {
|
||||||
|
swap(p[0], p[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fixEndianess(uint8_t*, integral_constant<size_t, 1>) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void fixEndianess(T& value) {
|
||||||
|
#if ARDUINOJSON_LITTLE_ENDIAN
|
||||||
|
fixEndianess(reinterpret_cast<uint8_t*>(&value),
|
||||||
|
integral_constant<size_t, sizeof(T)>());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
18
src/ArduinoJson/MsgPack/ieee754.hpp
Normal file
18
src/ArduinoJson/MsgPack/ieee754.hpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
namespace Internals {
|
||||||
|
|
||||||
|
inline void doubleToFloat(const uint8_t d[8], uint8_t f[4]) {
|
||||||
|
f[0] = uint8_t((d[0] & 0xC0) | (d[0] << 3 & 0x3f) | (d[1] >> 5));
|
||||||
|
f[1] = uint8_t((d[1] << 3) | (d[2] >> 5));
|
||||||
|
f[2] = uint8_t((d[2] << 3) | (d[3] >> 5));
|
||||||
|
f[3] = uint8_t((d[3] << 3) | (d[4] >> 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internals
|
||||||
|
} // namespace ArduinoJson
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../StringTraits/StringTraits.hpp"
|
#include "../Strings/StringTraits.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -31,5 +31,5 @@ class DynamicStringBuilder {
|
|||||||
|
|
||||||
TString &_str;
|
TString &_str;
|
||||||
};
|
};
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string.h> // for strcmp
|
#include <string.h> // for strcmp
|
||||||
#include "./ctype.hpp"
|
#include "../Polyfills/ctype.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -34,5 +34,5 @@ inline bool isFloat(const char* s) {
|
|||||||
|
|
||||||
return *s == '\0';
|
return *s == '\0';
|
||||||
}
|
}
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "./ctype.hpp"
|
#include "../Polyfills/ctype.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -15,5 +15,5 @@ inline bool isInteger(const char* s) {
|
|||||||
while (isdigit(*s)) s++;
|
while (isdigit(*s)) s++;
|
||||||
return *s == '\0';
|
return *s == '\0';
|
||||||
}
|
}
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../Polyfills/ctype.hpp"
|
||||||
|
#include "../Polyfills/math.hpp"
|
||||||
#include "../TypeTraits/FloatTraits.hpp"
|
#include "../TypeTraits/FloatTraits.hpp"
|
||||||
#include "./ctype.hpp"
|
|
||||||
#include "./math.hpp"
|
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -86,5 +86,5 @@ inline T parseFloat(const char* s) {
|
|||||||
|
|
||||||
return negative_result ? -result : result;
|
return negative_result ? -result : result;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
@ -7,7 +7,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "../Configuration.hpp"
|
#include "../Configuration.hpp"
|
||||||
#include "./ctype.hpp"
|
#include "../Polyfills/ctype.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
namespace Internals {
|
namespace Internals {
|
||||||
@ -37,5 +37,5 @@ T parseInteger(const char *s) {
|
|||||||
|
|
||||||
return negative_result ? T(~result + 1) : result;
|
return negative_result ? T(~result + 1) : result;
|
||||||
}
|
}
|
||||||
}
|
} // namespace Internals
|
||||||
}
|
} // namespace ArduinoJson
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Deserialization/JsonParser.hpp"
|
#include "Json/Deserialization/JsonParser.hpp"
|
||||||
|
|
||||||
namespace ArduinoJson {
|
namespace ArduinoJson {
|
||||||
// JsonError deserializeJson(TDestination& destination, TString json);
|
// JsonError deserializeJson(TDestination& destination, TString json);
|
||||||
|
49
src/ArduinoJson/deserializeMsgPack.hpp
Normal file
49
src/ArduinoJson/deserializeMsgPack.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "MsgPack/MsgPackDeserializer.hpp"
|
||||||
|
|
||||||
|
namespace ArduinoJson {
|
||||||
|
// MsgPackError deserializeMsgPack(TDestination& destination, TString json);
|
||||||
|
// TDestination = JsonArray, JsonObject, JsonVariant
|
||||||
|
// TString = const std::string&, const String&
|
||||||
|
template <typename TDestination, typename TString>
|
||||||
|
typename Internals::EnableIf<!Internals::IsArray<TString>::value,
|
||||||
|
MsgPackError>::type
|
||||||
|
deserializeMsgPack(TDestination &destination, const TString &json,
|
||||||
|
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||||
|
destination.clear();
|
||||||
|
return Internals::makeMsgPackDeserializer(&destination.buffer(), json,
|
||||||
|
nestingLimit)
|
||||||
|
.parse(destination);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// MsgPackError deserializeMsgPack(TDestination& destination, TString json);
|
||||||
|
// TDestination = JsonArray, JsonObject, JsonVariant
|
||||||
|
// TString = const char*, const char[N], const FlashStringHelper*
|
||||||
|
template <typename TDestination, typename TString>
|
||||||
|
MsgPackError deserializeMsgPack(
|
||||||
|
TDestination &destination, TString *json,
|
||||||
|
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||||
|
destination.clear();
|
||||||
|
return Internals::makeMsgPackDeserializer(&destination.buffer(), json,
|
||||||
|
nestingLimit)
|
||||||
|
.parse(destination);
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// MsgPackError deserializeMsgPack(TDestination& destination, TString json);
|
||||||
|
// TDestination = JsonArray, JsonObject, JsonVariant
|
||||||
|
// TString = std::istream&, Stream&
|
||||||
|
template <typename TDestination, typename TString>
|
||||||
|
MsgPackError deserializeMsgPack(
|
||||||
|
TDestination &destination, TString &json,
|
||||||
|
uint8_t nestingLimit = ARDUINOJSON_DEFAULT_NESTING_LIMIT) {
|
||||||
|
destination.clear();
|
||||||
|
return Internals::makeMsgPackDeserializer(&destination.buffer(), json,
|
||||||
|
nestingLimit)
|
||||||
|
.parse(destination);
|
||||||
|
}
|
||||||
|
} // namespace ArduinoJson
|
@ -73,5 +73,6 @@ add_subdirectory(JsonSerializer)
|
|||||||
add_subdirectory(JsonVariant)
|
add_subdirectory(JsonVariant)
|
||||||
add_subdirectory(JsonWriter)
|
add_subdirectory(JsonWriter)
|
||||||
add_subdirectory(Misc)
|
add_subdirectory(Misc)
|
||||||
|
add_subdirectory(MsgPack)
|
||||||
add_subdirectory(Polyfills)
|
add_subdirectory(Polyfills)
|
||||||
add_subdirectory(StaticJsonBuffer)
|
add_subdirectory(StaticJsonBuffer)
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <ArduinoJson/Serialization/DynamicStringBuilder.hpp>
|
#include <ArduinoJson/Json/Serialization/JsonWriter.hpp>
|
||||||
#include <ArduinoJson/Serialization/JsonWriter.hpp>
|
#include <ArduinoJson/Print/DynamicStringBuilder.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
|
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
#include <ArduinoJson/Serialization/JsonWriter.hpp>
|
#include <ArduinoJson/Json/Serialization/JsonWriter.hpp>
|
||||||
#include <ArduinoJson/Serialization/StaticStringBuilder.hpp>
|
#include <ArduinoJson/Print/StaticStringBuilder.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2018
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Serialization/FloatParts.hpp>
|
#include <ArduinoJson/Json/Serialization/FloatParts.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
16
test/MsgPack/CMakeLists.txt
Normal file
16
test/MsgPack/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# ArduinoJson - arduinojson.org
|
||||||
|
# Copyright Benoit Blanchon 2014-2018
|
||||||
|
# MIT License
|
||||||
|
|
||||||
|
add_executable(MsgPackTests
|
||||||
|
deserializationErrors.cpp
|
||||||
|
deserializeArray.cpp
|
||||||
|
deserializeObject.cpp
|
||||||
|
deserializeVariant.cpp
|
||||||
|
deserializeStaticVariant.cpp
|
||||||
|
doubleToFloat.cpp
|
||||||
|
MsgPackError.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(MsgPackTests catch)
|
||||||
|
add_test(MsgPack MsgPackTests)
|
40
test/MsgPack/MsgPackError.cpp
Normal file
40
test/MsgPack/MsgPackError.cpp
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
void testStringification(MsgPackError error, std::string expected) {
|
||||||
|
REQUIRE(error.c_str() == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testBoolification(MsgPackError error, bool expected) {
|
||||||
|
CHECK(error == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_STRINGIFICATION(symbol) \
|
||||||
|
testStringification(MsgPackError::symbol, #symbol)
|
||||||
|
|
||||||
|
#define TEST_BOOLIFICATION(symbol, expected) \
|
||||||
|
testBoolification(MsgPackError::symbol, expected)
|
||||||
|
|
||||||
|
TEST_CASE("MsgPackError") {
|
||||||
|
SECTION("c_str()") {
|
||||||
|
TEST_STRINGIFICATION(Ok);
|
||||||
|
TEST_STRINGIFICATION(NotSupported);
|
||||||
|
TEST_STRINGIFICATION(NoMemory);
|
||||||
|
TEST_STRINGIFICATION(NotAnArray);
|
||||||
|
TEST_STRINGIFICATION(NotAnObject);
|
||||||
|
TEST_STRINGIFICATION(TooDeep);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("as boolean") {
|
||||||
|
TEST_BOOLIFICATION(Ok, false);
|
||||||
|
TEST_BOOLIFICATION(NotSupported, true);
|
||||||
|
TEST_BOOLIFICATION(NoMemory, true);
|
||||||
|
TEST_BOOLIFICATION(NotAnArray, true);
|
||||||
|
TEST_BOOLIFICATION(NotAnObject, true);
|
||||||
|
TEST_BOOLIFICATION(TooDeep, true);
|
||||||
|
}
|
||||||
|
}
|
58
test/MsgPack/deserializationErrors.cpp
Normal file
58
test/MsgPack/deserializationErrors.cpp
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
static void check(const char* input, MsgPackError expected,
|
||||||
|
uint8_t nestingLimit = 10) {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input, nestingLimit);
|
||||||
|
|
||||||
|
REQUIRE(error == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Errors returned by deserializeMsgPack()") {
|
||||||
|
SECTION("unsupported") {
|
||||||
|
check("\xc4", MsgPackError::NotSupported); // bin 8
|
||||||
|
check("\xc5", MsgPackError::NotSupported); // bin 16
|
||||||
|
check("\xc6", MsgPackError::NotSupported); // bin 32
|
||||||
|
check("\xc7", MsgPackError::NotSupported); // ext 8
|
||||||
|
check("\xc8", MsgPackError::NotSupported); // ext 16
|
||||||
|
check("\xc9", MsgPackError::NotSupported); // ext 32
|
||||||
|
check("\xd4", MsgPackError::NotSupported); // fixext 1
|
||||||
|
check("\xd5", MsgPackError::NotSupported); // fixext 2
|
||||||
|
check("\xd6", MsgPackError::NotSupported); // fixext 4
|
||||||
|
check("\xd7", MsgPackError::NotSupported); // fixext 8
|
||||||
|
check("\xd8", MsgPackError::NotSupported); // fixext 16
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("unsupported in array") {
|
||||||
|
check("\x91\xc4", MsgPackError::NotSupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("unsupported in map") {
|
||||||
|
check("\x81\xc4\x00\xA1H", MsgPackError::NotSupported);
|
||||||
|
check("\x81\xA1H\xc4\x00", MsgPackError::NotSupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("integer as key") {
|
||||||
|
check("\x81\x01\xA1H", MsgPackError::NotSupported);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("object too deep") {
|
||||||
|
check("\x80", MsgPackError::TooDeep, 0); // {}
|
||||||
|
check("\x80", MsgPackError::Ok, 1); // {}
|
||||||
|
check("\x81\xA1H\x80", MsgPackError::TooDeep, 1); // {H:{}}
|
||||||
|
check("\x81\xA1H\x80", MsgPackError::Ok, 2); // {H:{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array too deep") {
|
||||||
|
check("\x90", MsgPackError::TooDeep, 0); // []
|
||||||
|
check("\x90", MsgPackError::Ok, 1); // []
|
||||||
|
check("\x91\x90", MsgPackError::TooDeep, 1); // [[]]
|
||||||
|
check("\x91\x90", MsgPackError::Ok, 2); // [[]]
|
||||||
|
}
|
||||||
|
}
|
85
test/MsgPack/deserializeArray.cpp
Normal file
85
test/MsgPack/deserializeArray.cpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("deserializeMsgPack(JsonArray&)") {
|
||||||
|
DynamicJsonArray array;
|
||||||
|
|
||||||
|
SECTION("not an array") {
|
||||||
|
const char* input = "\xA0";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(array, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::NotAnArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixarray") {
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\x90";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(array, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(array.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two integers") {
|
||||||
|
const char* input = "\x92\x01\x02";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(array, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(array.size() == 2);
|
||||||
|
REQUIRE(array[0] == 1);
|
||||||
|
REQUIRE(array[1] == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array 16") {
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDC\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(array, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(array.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two strings") {
|
||||||
|
const char* input = "\xDC\x00\x02\xA5hello\xA5world";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(array, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(array.size() == 2);
|
||||||
|
REQUIRE(array[0] == "hello");
|
||||||
|
REQUIRE(array[1] == "world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array 32") {
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDD\x00\x00\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(array, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(array.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two floats") {
|
||||||
|
const char* input =
|
||||||
|
"\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(array, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(array.size() == 2);
|
||||||
|
REQUIRE(array[0] == 0.0f);
|
||||||
|
REQUIRE(array[1] == 3.14f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
86
test/MsgPack/deserializeObject.cpp
Normal file
86
test/MsgPack/deserializeObject.cpp
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("deserializeMsgPack(JsonObject&)") {
|
||||||
|
DynamicJsonObject object;
|
||||||
|
|
||||||
|
SECTION("not an object") {
|
||||||
|
const char* input = "\xA0";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(object, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::NotAnObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixmap") {
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\x80";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(object, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(object.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two integers") {
|
||||||
|
const char* input = "\x82\xA3one\x01\xA3two\x02";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(object, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(object.size() == 2);
|
||||||
|
REQUIRE(object["one"] == 1);
|
||||||
|
REQUIRE(object["two"] == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map 16") {
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDE\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(object, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(object.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two strings") {
|
||||||
|
const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(object, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(object.size() == 2);
|
||||||
|
REQUIRE(object["H"] == "hello");
|
||||||
|
REQUIRE(object["W"] == "world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map 32") {
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDF\x00\x00\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(object, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(object.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two floats") {
|
||||||
|
const char* input =
|
||||||
|
"\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48"
|
||||||
|
"\xF5\xC3";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(object, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(object.size() == 2);
|
||||||
|
REQUIRE(object["zero"] == 0.0f);
|
||||||
|
REQUIRE(object["pi"] == 3.14f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
131
test/MsgPack/deserializeStaticVariant.cpp
Normal file
131
test/MsgPack/deserializeStaticVariant.cpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
static const size_t epsilon = sizeof(void*);
|
||||||
|
|
||||||
|
template <size_t Capacity>
|
||||||
|
static void check(const char* input, MsgPackError expected) {
|
||||||
|
StaticJsonVariant<Capacity> variant;
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("deserializeMsgPack(StaticJsonVariant&)") {
|
||||||
|
SECTION("single values always fit") {
|
||||||
|
check<0>("\xc0", MsgPackError::Ok); // nil
|
||||||
|
check<0>("\xc2", MsgPackError::Ok); // false
|
||||||
|
check<0>("\xc3", MsgPackError::Ok); // true
|
||||||
|
check<0>("\xcc\x00", MsgPackError::Ok); // uint 8
|
||||||
|
check<0>("\xcd\x30\x39", MsgPackError::Ok); // uint 16
|
||||||
|
check<0>("\xCE\x12\x34\x56\x78", MsgPackError::Ok); // uint 32
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixstr") {
|
||||||
|
check<0>("\xA0", MsgPackError::Ok);
|
||||||
|
check<0>("\xA1H", MsgPackError::NoMemory);
|
||||||
|
check<4>("\xA1H", MsgPackError::Ok);
|
||||||
|
check<4>("\xA5Hello", MsgPackError::NoMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("str 8") {
|
||||||
|
check<0>("\xD9\x00", MsgPackError::Ok);
|
||||||
|
check<0>("\xD9\x01H", MsgPackError::NoMemory);
|
||||||
|
check<4>("\xD9\x01H", MsgPackError::Ok);
|
||||||
|
check<4>("\xD9\x05Hello", MsgPackError::NoMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("str 16") {
|
||||||
|
check<0>("\xDA\x00\x00", MsgPackError::Ok);
|
||||||
|
check<0>("\xDA\x00\x01H", MsgPackError::NoMemory);
|
||||||
|
check<4>("\xDA\x00\x01H", MsgPackError::Ok);
|
||||||
|
check<4>("\xDA\x00\x05Hello", MsgPackError::NoMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("str 32") {
|
||||||
|
check<0>("\xDB\x00\x00\x00\x00", MsgPackError::Ok);
|
||||||
|
check<0>("\xDB\x00\x00\x00\x01H", MsgPackError::NoMemory);
|
||||||
|
check<4>("\xDB\x00\x00\x00\x01H", MsgPackError::Ok);
|
||||||
|
check<4>("\xDB\x00\x00\x00\x05Hello", MsgPackError::NoMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixarray") {
|
||||||
|
check<JSON_ARRAY_SIZE(0)>("\x90", MsgPackError::Ok); // []
|
||||||
|
check<JSON_ARRAY_SIZE(0)>("\x91\x01", MsgPackError::NoMemory); // [1]
|
||||||
|
check<JSON_ARRAY_SIZE(1)>("\x91\x01", MsgPackError::Ok); // [1]
|
||||||
|
check<JSON_ARRAY_SIZE(1)>("\x92\x01\x02", MsgPackError::NoMemory); // [1,2]
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array 16") {
|
||||||
|
check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x00", MsgPackError::Ok);
|
||||||
|
check<JSON_ARRAY_SIZE(0)>("\xDC\x00\x01\x01", MsgPackError::NoMemory);
|
||||||
|
check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x01\x01", MsgPackError::Ok);
|
||||||
|
check<JSON_ARRAY_SIZE(1)>("\xDC\x00\x02\x01\x02", MsgPackError::NoMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array 32") {
|
||||||
|
check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x00", MsgPackError::Ok);
|
||||||
|
check<JSON_ARRAY_SIZE(0)>("\xDD\x00\x00\x00\x01\x01",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x01\x01", MsgPackError::Ok);
|
||||||
|
check<JSON_ARRAY_SIZE(1)>("\xDD\x00\x00\x00\x02\x01\x02",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixmap") {
|
||||||
|
SECTION("{}") {
|
||||||
|
check<JSON_OBJECT_SIZE(0)>("\x80", MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
SECTION("{H:1}") {
|
||||||
|
check<JSON_OBJECT_SIZE(0)>("\x81\xA1H\x01",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
check<JSON_OBJECT_SIZE(1) + epsilon>("\x81\xA1H\x01", MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
SECTION("{H:1,W:2}") {
|
||||||
|
check<JSON_OBJECT_SIZE(1) + epsilon>("\x82\xA1H\x01\xA1W\x02",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
check<JSON_OBJECT_SIZE(2) + 2*epsilon>("\x82\xA1H\x01\xA1W\x02",
|
||||||
|
MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map 16") {
|
||||||
|
SECTION("{}") {
|
||||||
|
check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x00", MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
SECTION("{H:1}") {
|
||||||
|
check<JSON_OBJECT_SIZE(0)>("\xDE\x00\x01\xA1H\x01",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x01\xA1H\x01", MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
SECTION("{H:1,W:2}") {
|
||||||
|
check<JSON_OBJECT_SIZE(1) + epsilon>("\xDE\x00\x02\xA1H\x01\xA1W\x02",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
check<JSON_OBJECT_SIZE(2) + 2*epsilon>("\xDE\x00\x02\xA1H\x01\xA1W\x02",
|
||||||
|
MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map 32") {
|
||||||
|
SECTION("{}") {
|
||||||
|
check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x00", MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
SECTION("{H:1}") {
|
||||||
|
check<JSON_OBJECT_SIZE(0)>("\xDF\x00\x00\x00\x01\xA1H\x01",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
check<JSON_OBJECT_SIZE(1) + epsilon>("\xDF\x00\x00\x00\x01\xA1H\x01",
|
||||||
|
MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
SECTION("{H:1,W:2}") {
|
||||||
|
check<JSON_OBJECT_SIZE(1) + epsilon>("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
|
||||||
|
MsgPackError::NoMemory);
|
||||||
|
check<JSON_OBJECT_SIZE(2) + 2*epsilon>("\xDF\x00\x00\x00\x02\xA1H\x01\xA1W\x02",
|
||||||
|
MsgPackError::Ok);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
277
test/MsgPack/deserializeVariant.cpp
Normal file
277
test/MsgPack/deserializeVariant.cpp
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
static void check(const char* input, U expected) {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.is<T>());
|
||||||
|
REQUIRE(variant.as<T>() == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("deserializeMsgPack(JsonVariant&)") {
|
||||||
|
SECTION("nil") {
|
||||||
|
const char* nil = 0; // ArduinoJson uses a string for null
|
||||||
|
check<const char*>("\xc0", nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("bool") {
|
||||||
|
check<bool>("\xc2", false);
|
||||||
|
check<bool>("\xc3", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("positive fixint") {
|
||||||
|
check<int>("\x00", 0);
|
||||||
|
check<int>("\x7F", 127);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("negative fixint") {
|
||||||
|
check<int>("\xe0", -32);
|
||||||
|
check<int>("\xff", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("uint 8") {
|
||||||
|
check<int>("\xcc\x00", 0);
|
||||||
|
check<int>("\xcc\xff", 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("uint 16") {
|
||||||
|
check<int>("\xcd\x00\x00", 0);
|
||||||
|
check<int>("\xcd\xFF\xFF", 65535);
|
||||||
|
check<int>("\xcd\x30\x39", 12345);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("uint 32") {
|
||||||
|
check<uint32_t>("\xCE\x00\x00\x00\x00", 0x00000000U);
|
||||||
|
check<uint32_t>("\xCE\xFF\xFF\xFF\xFF", 0xFFFFFFFFU);
|
||||||
|
check<uint32_t>("\xCE\x12\x34\x56\x78", 0x12345678U);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("uint 64") {
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||||
|
check<uint64_t>("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U);
|
||||||
|
check<uint64_t>("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
|
||||||
|
0xFFFFFFFFFFFFFFFFU);
|
||||||
|
check<uint64_t>("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
|
||||||
|
0x123456789ABCDEF0U);
|
||||||
|
#else
|
||||||
|
check<uint32_t>("\xCF\x00\x00\x00\x00\x00\x00\x00\x00", 0U);
|
||||||
|
check<uint32_t>("\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0xFFFFFFFF);
|
||||||
|
check<uint32_t>("\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0", 0x9ABCDEF0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int 8") {
|
||||||
|
check<int>("\xd0\x00", 0);
|
||||||
|
check<int>("\xd0\xff", -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int 16") {
|
||||||
|
check<int>("\xD1\x00\x00", 0);
|
||||||
|
check<int>("\xD1\xFF\xFF", -1);
|
||||||
|
check<int>("\xD1\xCF\xC7", -12345);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int 32") {
|
||||||
|
check<int>("\xD2\x00\x00\x00\x00", 0);
|
||||||
|
check<int>("\xD2\xFF\xFF\xFF\xFF", -1);
|
||||||
|
check<int>("\xD2\xB6\x69\xFD\x2E", -1234567890);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("int 64") {
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64
|
||||||
|
check<uint64_t>("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", 0U);
|
||||||
|
check<uint64_t>("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF",
|
||||||
|
0xFFFFFFFFFFFFFFFFU);
|
||||||
|
check<uint64_t>("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0",
|
||||||
|
0x123456789ABCDEF0U);
|
||||||
|
#else
|
||||||
|
check<uint32_t>("\xD3\x00\x00\x00\x00\x00\x00\x00\x00", 0U);
|
||||||
|
check<uint32_t>("\xD3\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0xFFFFFFFF);
|
||||||
|
check<uint32_t>("\xD3\x12\x34\x56\x78\x9A\xBC\xDE\xF0", 0x9ABCDEF0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("float 32") {
|
||||||
|
check<double>("\xCA\x00\x00\x00\x00", 0.0f);
|
||||||
|
check<double>("\xCA\x40\x48\xF5\xC3", 3.14f);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("float 64") {
|
||||||
|
check<double>("\xCB\x00\x00\x00\x00\x00\x00\x00\x00", 0.0);
|
||||||
|
check<double>("\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixstr") {
|
||||||
|
check<const char*>("\xA0", std::string(""));
|
||||||
|
check<const char*>("\xABhello world", std::string("hello world"));
|
||||||
|
check<const char*>("\xBFhello world hello world hello !",
|
||||||
|
std::string("hello world hello world hello !"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("str 8") {
|
||||||
|
check<const char*>("\xd9\x05hello", std::string("hello"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("str 16") {
|
||||||
|
check<const char*>("\xda\x00\x05hello", std::string("hello"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("str 32") {
|
||||||
|
check<const char*>("\xdb\x00\x00\x00\x05hello", std::string("hello"));
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixarray") {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\x90";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two integers") {
|
||||||
|
const char* input = "\x92\x01\x02";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 2);
|
||||||
|
REQUIRE(variant[0] == 1);
|
||||||
|
REQUIRE(variant[1] == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array 16") {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDC\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two strings") {
|
||||||
|
const char* input = "\xDC\x00\x02\xA5hello\xA5world";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 2);
|
||||||
|
REQUIRE(variant[0] == "hello");
|
||||||
|
REQUIRE(variant[1] == "world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("array 32") {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDD\x00\x00\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two floats") {
|
||||||
|
const char* input =
|
||||||
|
"\xDD\x00\x00\x00\x02\xCA\x00\x00\x00\x00\xCA\x40\x48\xF5\xC3";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 2);
|
||||||
|
REQUIRE(variant[0] == 0.0f);
|
||||||
|
REQUIRE(variant[1] == 3.14f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("fixmap") {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\x80";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two integers") {
|
||||||
|
const char* input = "\x82\xA3one\x01\xA3two\x02";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 2);
|
||||||
|
REQUIRE(variant["one"] == 1);
|
||||||
|
REQUIRE(variant["two"] == 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map 16") {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDE\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two strings") {
|
||||||
|
const char* input = "\xDE\x00\x02\xA1H\xA5hello\xA1W\xA5world";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 2);
|
||||||
|
REQUIRE(variant["H"] == "hello");
|
||||||
|
REQUIRE(variant["W"] == "world");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("map 32") {
|
||||||
|
DynamicJsonVariant variant;
|
||||||
|
|
||||||
|
SECTION("empty") {
|
||||||
|
const char* input = "\xDF\x00\x00\x00\x00";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("two floats") {
|
||||||
|
const char* input =
|
||||||
|
"\xDF\x00\x00\x00\x02\xA4zero\xCA\x00\x00\x00\x00\xA2pi\xCA\x40\x48"
|
||||||
|
"\xF5\xC3";
|
||||||
|
|
||||||
|
MsgPackError error = deserializeMsgPack(variant, input);
|
||||||
|
|
||||||
|
REQUIRE(error == MsgPackError::Ok);
|
||||||
|
REQUIRE(variant.size() == 2);
|
||||||
|
REQUIRE(variant["zero"] == 0.0f);
|
||||||
|
REQUIRE(variant["pi"] == 3.14f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
test/MsgPack/doubleToFloat.cpp
Normal file
25
test/MsgPack/doubleToFloat.cpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// ArduinoJson - arduinojson.org
|
||||||
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include <catch.hpp>
|
||||||
|
|
||||||
|
using namespace ArduinoJson::Internals;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void check(const char* input, T expected) {
|
||||||
|
T actual;
|
||||||
|
uint8_t* f = reinterpret_cast<uint8_t*>(&actual);
|
||||||
|
const uint8_t* d = reinterpret_cast<const uint8_t*>(input);
|
||||||
|
doubleToFloat(d, f);
|
||||||
|
fixEndianess(actual);
|
||||||
|
CHECK(actual == expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Internals::doubleToFloat()") {
|
||||||
|
check("\x40\x09\x21\xCA\xC0\x83\x12\x6F", 3.1415f);
|
||||||
|
check("\x00\x00\x00\x00\x00\x00\x00\x00", 0.0f);
|
||||||
|
check("\x80\x00\x00\x00\x00\x00\x00\x00", -0.0f);
|
||||||
|
check("\xC0\x5E\xDC\xCC\xCC\xCC\xCC\xCD", -123.45f);
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2018
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/isFloat.hpp>
|
#include <ArduinoJson/Text/isFloat.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2018
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/isInteger.hpp>
|
#include <ArduinoJson/Text/isInteger.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// Copyright Benoit Blanchon 2014-2018
|
// Copyright Benoit Blanchon 2014-2018
|
||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <ArduinoJson/Polyfills/parseFloat.hpp>
|
#include <ArduinoJson/Text/parseFloat.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
// MIT License
|
// MIT License
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <ArduinoJson/Polyfills/parseInteger.hpp>
|
#include <ArduinoJson/Text/parseInteger.hpp>
|
||||||
#include <catch.hpp>
|
#include <catch.hpp>
|
||||||
|
|
||||||
using namespace ArduinoJson::Internals;
|
using namespace ArduinoJson::Internals;
|
||||||
|
Reference in New Issue
Block a user