mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Added deserializeMsgPack() (issue #358)
				
					
				
			This commit is contained in:
		| @@ -2,12 +2,6 @@ sudo: false | ||||
| language: cpp | ||||
| matrix: | ||||
|   include: | ||||
|     - compiler: gcc | ||||
|       addons: | ||||
|         apt: | ||||
|           sources: ['ubuntu-toolchain-r-test'] | ||||
|           packages: ['g++-4.4'] | ||||
|       env: SCRIPT=cmake GCC=4.4 | ||||
|     - compiler: gcc | ||||
|       addons: | ||||
|         apt: | ||||
|   | ||||
| @@ -12,6 +12,7 @@ HEAD | ||||
| * Added `deserializeJson()` | ||||
| * Added `serializeJson()` and `serializeJsonPretty()` | ||||
| * Added `measureJson()` and `measureJsonPretty()` | ||||
| * Added `deserializeMsgPack()` (issue #358) | ||||
| * Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` | ||||
| * Removed `JsonBuffer::createArray()` and `createObject()` | ||||
| * Removed `printTo()` and `prettyPrintTo()` | ||||
|   | ||||
| @@ -7,13 +7,15 @@ | ||||
| #include "ArduinoJson/DynamicJsonArray.hpp" | ||||
| #include "ArduinoJson/DynamicJsonObject.hpp" | ||||
| #include "ArduinoJson/DynamicJsonVariant.hpp" | ||||
| #include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" | ||||
| #include "ArduinoJson/StaticJsonArray.hpp" | ||||
| #include "ArduinoJson/StaticJsonObject.hpp" | ||||
| #include "ArduinoJson/StaticJsonVariant.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/JsonObjectImpl.hpp" | ||||
| #include "ArduinoJson/JsonVariantImpl.hpp" | ||||
| #include "ArduinoJson/Serialization/JsonSerializerImpl.hpp" | ||||
|   | ||||
| @@ -144,3 +144,13 @@ | ||||
| #if ARDUINOJSON_USE_LONG_LONG && ARDUINOJSON_USE_INT64 | ||||
| #error ARDUINOJSON_USE_LONG_LONG and ARDUINOJSON_USE_INT64 cannot be set together | ||||
| #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 "../Memory/JsonBuffer.hpp" | ||||
| #include "../StringTraits/StringTraits.hpp" | ||||
| #include "../Strings/StringTraits.hpp" | ||||
| #include "../TypeTraits/EnableIf.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|   | ||||
| @@ -4,11 +4,11 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "../JsonError.hpp" | ||||
| #include "../JsonVariant.hpp" | ||||
| #include "../Memory/JsonBuffer.hpp" | ||||
| #include "../TypeTraits/IsConst.hpp" | ||||
| #include "StringWriter.hpp" | ||||
| #include "../../JsonError.hpp" | ||||
| #include "../../JsonVariant.hpp" | ||||
| #include "../../Memory/JsonBuffer.hpp" | ||||
| #include "../../Strings/StringWriter.hpp" | ||||
| #include "../../TypeTraits/IsConst.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -4,7 +4,7 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "../Data/Encoding.hpp" | ||||
| #include "../Encoding.hpp" | ||||
| #include "Comments.hpp" | ||||
| #include "JsonParser.hpp" | ||||
| 
 | ||||
| @@ -4,9 +4,9 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "../Configuration.hpp" | ||||
| #include "../Polyfills/math.hpp" | ||||
| #include "../TypeTraits/FloatTraits.hpp" | ||||
| #include "../../Configuration.hpp" | ||||
| #include "../../Polyfills/math.hpp" | ||||
| #include "../../TypeTraits/FloatTraits.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -85,5 +85,5 @@ struct FloatParts { | ||||
|     return powersOf10; | ||||
|   } | ||||
| }; | ||||
| } | ||||
| } | ||||
| }  // namespace Internals
 | ||||
| }  // namespace ArduinoJson
 | ||||
| @@ -4,15 +4,15 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "DummyPrint.hpp" | ||||
| #include "DynamicStringBuilder.hpp" | ||||
| #include "IndentedPrint.hpp" | ||||
| #include "JsonWriter.hpp" | ||||
| #include "Prettyfier.hpp" | ||||
| #include "StaticStringBuilder.hpp" | ||||
| #include "../../Print/DummyPrint.hpp" | ||||
| #include "../../Print/DynamicStringBuilder.hpp" | ||||
| #include "../../Print/StaticStringBuilder.hpp" | ||||
| #include "./IndentedPrint.hpp" | ||||
| #include "./JsonWriter.hpp" | ||||
| #include "./Prettyfier.hpp" | ||||
| 
 | ||||
| #if ARDUINOJSON_ENABLE_STD_STREAM | ||||
| #include "StreamPrintAdapter.hpp" | ||||
| #include "../../Print/StreamPrintAdapter.hpp" | ||||
| #endif | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| @@ -4,11 +4,11 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "../JsonArray.hpp" | ||||
| #include "../JsonArraySubscript.hpp" | ||||
| #include "../JsonObject.hpp" | ||||
| #include "../JsonObjectSubscript.hpp" | ||||
| #include "../JsonVariant.hpp" | ||||
| #include "../../JsonArray.hpp" | ||||
| #include "../../JsonArraySubscript.hpp" | ||||
| #include "../../JsonObject.hpp" | ||||
| #include "../../JsonObjectSubscript.hpp" | ||||
| #include "../../JsonVariant.hpp" | ||||
| #include "JsonSerializer.hpp" | ||||
| 
 | ||||
| template <typename Writer> | ||||
| @@ -5,10 +5,10 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <stdint.h> | ||||
| #include "../Data/Encoding.hpp" | ||||
| #include "../Data/JsonInteger.hpp" | ||||
| #include "../Polyfills/attributes.hpp" | ||||
| #include "../Serialization/FloatParts.hpp" | ||||
| #include "../../Data/JsonInteger.hpp" | ||||
| #include "../../Polyfills/attributes.hpp" | ||||
| #include "../Encoding.hpp" | ||||
| #include "./FloatParts.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include "Data/ValueSaver.hpp" | ||||
| #include "JsonVariant.hpp" | ||||
| #include "Memory/JsonBufferAllocated.hpp" | ||||
| #include "StringTraits/StringTraits.hpp" | ||||
| #include "Strings/StringTraits.hpp" | ||||
| #include "TypeTraits/EnableIf.hpp" | ||||
| #include "TypeTraits/IsArray.hpp" | ||||
| #include "TypeTraits/IsFloatingPoint.hpp" | ||||
|   | ||||
| @@ -42,15 +42,7 @@ class JsonError { | ||||
|   } | ||||
|  | ||||
|   const char* c_str() const { | ||||
|     return to_string(_code); | ||||
|   } | ||||
|  | ||||
|   friend const char* to_string(const JsonError err) { | ||||
|     return to_string(err._code); | ||||
|   } | ||||
|  | ||||
|   friend const char* to_string(JsonError::Code code) { | ||||
|     switch (code) { | ||||
|     switch (_code) { | ||||
|       case Ok: | ||||
|         return "Ok"; | ||||
|       case OpeningBraceExpected: | ||||
| @@ -78,12 +70,7 @@ class JsonError { | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_STD_STREAM | ||||
| inline std::ostream& operator<<(std::ostream& s, const JsonError& e) { | ||||
|   s << to_string(e); | ||||
|   return s; | ||||
| } | ||||
|  | ||||
| inline std::ostream& operator<<(std::ostream& s, JsonError::Code e) { | ||||
|   s << to_string(e); | ||||
|   s << e.c_str(); | ||||
|   return s; | ||||
| } | ||||
| #endif | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include "Data/ValueSaver.hpp" | ||||
| #include "JsonPair.hpp" | ||||
| #include "Memory/JsonBufferAllocated.hpp" | ||||
| #include "StringTraits/StringTraits.hpp" | ||||
| #include "Strings/StringTraits.hpp" | ||||
| #include "TypeTraits/EnableIf.hpp" | ||||
| #include "TypeTraits/IsArray.hpp" | ||||
| #include "TypeTraits/IsFloatingPoint.hpp" | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "StringTraits/StringTraits.hpp" | ||||
| #include "Strings/StringTraits.hpp" | ||||
| #include "TypeTraits/EnableIf.hpp" | ||||
| #include "TypeTraits/IsVariant.hpp" | ||||
|  | ||||
| @@ -134,5 +134,5 @@ class JsonVariantComparisons { | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
| } | ||||
| } | ||||
| }  // namespace Internals | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -8,10 +8,10 @@ | ||||
| #include "JsonArray.hpp" | ||||
| #include "JsonObject.hpp" | ||||
| #include "JsonVariant.hpp" | ||||
| #include "Polyfills/isFloat.hpp" | ||||
| #include "Polyfills/isInteger.hpp" | ||||
| #include "Polyfills/parseFloat.hpp" | ||||
| #include "Polyfills/parseInteger.hpp" | ||||
| #include "Text/isFloat.hpp" | ||||
| #include "Text/isInteger.hpp" | ||||
| #include "Text/parseFloat.hpp" | ||||
| #include "Text/parseInteger.hpp" | ||||
|  | ||||
| #include <string.h>  // for strcmp | ||||
|  | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
|  | ||||
| #include "Data/JsonVariantAs.hpp" | ||||
| #include "Polyfills/attributes.hpp" | ||||
| #include "StringTraits/StringTraits.hpp" | ||||
| #include "Strings/StringTraits.hpp" | ||||
| #include "TypeTraits/EnableIf.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| @@ -82,5 +82,5 @@ class JsonVariantSubscripts { | ||||
|     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 | ||||
| 
 | ||||
| #include "../StringTraits/StringTraits.hpp" | ||||
| #include "../Strings/StringTraits.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -31,5 +31,5 @@ class DynamicStringBuilder { | ||||
| 
 | ||||
|   TString &_str; | ||||
| }; | ||||
| } | ||||
| } | ||||
| }  // namespace Internals
 | ||||
| }  // namespace ArduinoJson
 | ||||
| @@ -5,7 +5,7 @@ | ||||
| #pragma once | ||||
| 
 | ||||
| #include <string.h>  // for strcmp
 | ||||
| #include "./ctype.hpp" | ||||
| #include "../Polyfills/ctype.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -34,5 +34,5 @@ inline bool isFloat(const char* s) { | ||||
| 
 | ||||
|   return *s == '\0'; | ||||
| } | ||||
| } | ||||
| } | ||||
| }  // namespace Internals
 | ||||
| }  // namespace ArduinoJson
 | ||||
| @@ -4,7 +4,7 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "./ctype.hpp" | ||||
| #include "../Polyfills/ctype.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -15,5 +15,5 @@ inline bool isInteger(const char* s) { | ||||
|   while (isdigit(*s)) s++; | ||||
|   return *s == '\0'; | ||||
| } | ||||
| } | ||||
| } | ||||
| }  // namespace Internals
 | ||||
| }  // namespace ArduinoJson
 | ||||
| @@ -4,9 +4,9 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "../Polyfills/ctype.hpp" | ||||
| #include "../Polyfills/math.hpp" | ||||
| #include "../TypeTraits/FloatTraits.hpp" | ||||
| #include "./ctype.hpp" | ||||
| #include "./math.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -86,5 +86,5 @@ inline T parseFloat(const char* s) { | ||||
| 
 | ||||
|   return negative_result ? -result : result; | ||||
| } | ||||
| } | ||||
| } | ||||
| }  // namespace Internals
 | ||||
| }  // namespace ArduinoJson
 | ||||
| @@ -7,7 +7,7 @@ | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| #include "../Configuration.hpp" | ||||
| #include "./ctype.hpp" | ||||
| #include "../Polyfills/ctype.hpp" | ||||
| 
 | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
| @@ -37,5 +37,5 @@ T parseInteger(const char *s) { | ||||
| 
 | ||||
|   return negative_result ? T(~result + 1) : result; | ||||
| } | ||||
| } | ||||
| } | ||||
| }  // namespace Internals
 | ||||
| }  // namespace ArduinoJson
 | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "Deserialization/JsonParser.hpp" | ||||
| #include "Json/Deserialization/JsonParser.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| // 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(JsonWriter) | ||||
| add_subdirectory(Misc) | ||||
| add_subdirectory(MsgPack) | ||||
| add_subdirectory(Polyfills) | ||||
| add_subdirectory(StaticJsonBuffer) | ||||
|   | ||||
| @@ -6,8 +6,8 @@ | ||||
| #include <limits> | ||||
| #include <string> | ||||
|  | ||||
| #include <ArduinoJson/Serialization/DynamicStringBuilder.hpp> | ||||
| #include <ArduinoJson/Serialization/JsonWriter.hpp> | ||||
| #include <ArduinoJson/Json/Serialization/JsonWriter.hpp> | ||||
| #include <ArduinoJson/Print/DynamicStringBuilder.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
|   | ||||
| @@ -4,8 +4,8 @@ | ||||
|  | ||||
| #include <catch.hpp> | ||||
|  | ||||
| #include <ArduinoJson/Serialization/JsonWriter.hpp> | ||||
| #include <ArduinoJson/Serialization/StaticStringBuilder.hpp> | ||||
| #include <ArduinoJson/Json/Serialization/JsonWriter.hpp> | ||||
| #include <ArduinoJson/Print/StaticStringBuilder.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson/Serialization/FloatParts.hpp> | ||||
| #include <ArduinoJson/Json/Serialization/FloatParts.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| 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 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson/Polyfills/isFloat.hpp> | ||||
| #include <ArduinoJson/Text/isFloat.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson/Polyfills/isInteger.hpp> | ||||
| #include <ArduinoJson/Text/isInteger.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson/Polyfills/parseFloat.hpp> | ||||
| #include <ArduinoJson/Text/parseFloat.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| // MIT License | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <ArduinoJson/Polyfills/parseInteger.hpp> | ||||
| #include <ArduinoJson/Text/parseInteger.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ArduinoJson::Internals; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user