forked from bblanchon/ArduinoJson
Added deserializeMsgPack() (issue #358)
This commit is contained in:
1 parent
923d3e8a84
commit
cb723840d9
58 files changed
+1311
-89
No files matched your search
@@ -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()`
|
||||||
|
|||||||
+4
-2
@@ -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 {
|
||||||
|
|||||||
File renamed without changes.
+5
-5
@@ -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 {
|
||||||
+1
-1
@@ -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"
|
||||||
|
|
||||||
File renamed without changes.
+5
-5
@@ -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
|
||||||
File renamed without changes.
+7
-7
@@ -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 {
|
||||||
+5
-5
@@ -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>
|
||||||
+4
-4
@@ -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 {
|
||||||
File renamed without changes.
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
File renamed without changes.
+3
-3
@@ -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
|
||||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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)
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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); // [[]]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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