mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added serializeMsgPack() and measureMsgPack() (closes #358)
				
					
				
			This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -9,3 +9,4 @@ | |||||||
| /fuzzing/*_fuzzer | /fuzzing/*_fuzzer | ||||||
| /fuzzing/*_fuzzer.options | /fuzzing/*_fuzzer.options | ||||||
| /fuzzing/*_fuzzer_seed_corpus.zip | /fuzzing/*_fuzzer_seed_corpus.zip | ||||||
|  | .vs/ | ||||||
|   | |||||||
| @@ -10,7 +10,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) | * Added `serializeMsgPack()`, `deserializeMsgPack()` and `measureMsgPack()` (issue #358) | ||||||
| * Added example `MsgPackParser.ino` (issue #358) | * Added example `MsgPackParser.ino` (issue #358) | ||||||
| * Added support for non zero-terminated strings (issue #704) | * Added support for non zero-terminated strings (issue #704) | ||||||
| * Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` | * Removed `JsonBuffer::parseArray()`, `parseObject()` and `parse()` | ||||||
|   | |||||||
| @@ -5,11 +5,13 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "ArduinoJson/DynamicJsonDocument.hpp" | #include "ArduinoJson/DynamicJsonDocument.hpp" | ||||||
| #include "ArduinoJson/StaticJsonDocument.hpp" | #include "ArduinoJson/Json/JsonDeserializer.hpp" | ||||||
| #include "ArduinoJson/deserializeJson.hpp" |  | ||||||
| #include "ArduinoJson/deserializeMsgPack.hpp" |  | ||||||
|  |  | ||||||
| #include "ArduinoJson/Json/JsonSerializer.hpp" | #include "ArduinoJson/Json/JsonSerializer.hpp" | ||||||
|  | #include "ArduinoJson/Json/PrettyJsonSerializer.hpp" | ||||||
|  | #include "ArduinoJson/MsgPack/MsgPackDeserializer.hpp" | ||||||
|  | #include "ArduinoJson/MsgPack/MsgPackSerializer.hpp" | ||||||
|  | #include "ArduinoJson/StaticJsonDocument.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" | ||||||
|   | |||||||
							
								
								
									
										82
									
								
								src/ArduinoJson/Deserialization/deserialize.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								src/ArduinoJson/Deserialization/deserialize.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "../StringStorage/StringStorage.hpp" | ||||||
|  | #include "./ArduinoStreamReader.hpp" | ||||||
|  | #include "./CharPointerReader.hpp" | ||||||
|  | #include "./DeserializationError.hpp" | ||||||
|  | #include "./FlashStringReader.hpp" | ||||||
|  | #include "./IteratorReader.hpp" | ||||||
|  | #include "./StdStreamReader.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <template <typename, typename> class TDeserializer, | ||||||
|  |           typename TJsonBuffer, typename TReader, typename TWriter> | ||||||
|  | TDeserializer<TReader, TWriter> makeDeserializer(TJsonBuffer *buffer, | ||||||
|  |                                                  TReader reader, TWriter writer, | ||||||
|  |                                                  uint8_t nestingLimit) { | ||||||
|  |   return TDeserializer<TReader, TWriter>(buffer, reader, writer, nestingLimit); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // DeserializationError deserialize(TDocument& doc, TString input); | ||||||
|  | // TDocument = DynamicJsonDocument, StaticJsonDocument | ||||||
|  | // TString = const std::string&, const String& | ||||||
|  | template <template <typename, typename> class TDeserializer, typename TDocument, | ||||||
|  |           typename TString> | ||||||
|  | typename Internals::enable_if<!Internals::is_array<TString>::value, | ||||||
|  |                               DeserializationError>::type | ||||||
|  | deserialize(TDocument &doc, const TString &input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return makeDeserializer<TDeserializer>(&doc.buffer(), makeReader(input), | ||||||
|  |                                          makeStringStorage(doc.buffer(), input), | ||||||
|  |                                          doc.nestingLimit) | ||||||
|  |       .parse(doc.template to<JsonVariant>()); | ||||||
|  | } | ||||||
|  | // | ||||||
|  | // DeserializationError deserialize(TDocument& doc, TChar* input); | ||||||
|  | // TDocument = DynamicJsonDocument, StaticJsonDocument | ||||||
|  | // TChar* = char*, const char*, const FlashStringHelper* | ||||||
|  | template <template <typename, typename> class TDeserializer, typename TDocument, | ||||||
|  |           typename TChar> | ||||||
|  | DeserializationError deserialize(TDocument &doc, TChar *input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return makeDeserializer<TDeserializer>(&doc.buffer(), makeReader(input), | ||||||
|  |                                          makeStringStorage(doc.buffer(), input), | ||||||
|  |                                          doc.nestingLimit) | ||||||
|  |       .parse(doc.template to<JsonVariant>()); | ||||||
|  | } | ||||||
|  | // | ||||||
|  | // DeserializationError deserialize(TDocument& doc, TChar* input, size_t | ||||||
|  | // inputSize); | ||||||
|  | // TDocument = DynamicJsonDocument, StaticJsonDocument | ||||||
|  | // TChar* = char*, const char*, const FlashStringHelper* | ||||||
|  | template <template <typename, typename> class TDeserializer, typename TDocument, | ||||||
|  |           typename TChar> | ||||||
|  | DeserializationError deserialize(TDocument &doc, TChar *input, | ||||||
|  |                                  size_t inputSize) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return makeDeserializer<TDeserializer>( | ||||||
|  |              &doc.buffer(), makeReader(input, inputSize), | ||||||
|  |              makeStringStorage(doc.buffer(), input), doc.nestingLimit) | ||||||
|  |       .parse(doc.template to<JsonVariant>()); | ||||||
|  | } | ||||||
|  | // | ||||||
|  | // DeserializationError deserialize(TDocument& doc, TStream input); | ||||||
|  | // TDocument = DynamicJsonDocument, StaticJsonDocument | ||||||
|  | // TStream = std::istream&, Stream& | ||||||
|  | template <template <typename, typename> class TDeserializer, typename TDocument, | ||||||
|  |           typename TStream> | ||||||
|  | DeserializationError deserialize(TDocument &doc, TStream &input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return makeDeserializer<TDeserializer>(&doc.buffer(), makeReader(input), | ||||||
|  |                                          makeStringStorage(doc.buffer(), input), | ||||||
|  |                                          doc.nestingLimit) | ||||||
|  |       .parse(doc.template to<JsonVariant>()); | ||||||
|  | } | ||||||
|  | }  // namespace Internals | ||||||
|  | }  // namespace ArduinoJson | ||||||
| @@ -79,7 +79,7 @@ class DynamicJsonDocument { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename Visitor> | ||||||
|   void visit(Visitor visitor) const { |   void visit(Visitor& visitor) const { | ||||||
|     return _root.visit(visitor); |     return _root.visit(visitor); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -4,24 +4,23 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../DeserializationError.hpp" | #include "../Deserialization/deserialize.hpp" | ||||||
| #include "../JsonVariant.hpp" | #include "../JsonVariant.hpp" | ||||||
| #include "../Memory/JsonBuffer.hpp" | #include "../Memory/JsonBuffer.hpp" | ||||||
| #include "../Polyfills/type_traits.hpp" | #include "../Polyfills/type_traits.hpp" | ||||||
| #include "../Reading/Reader.hpp" |  | ||||||
| #include "./EscapeSequence.hpp" | #include "./EscapeSequence.hpp" | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| template <typename TReader, typename TWriter> | template <typename TReader, typename TStringStorage> | ||||||
| class JsonDeserializer { | class JsonDeserializer { | ||||||
|  public: |  public: | ||||||
|   JsonDeserializer(JsonBuffer *buffer, TReader reader, TWriter writer, |   JsonDeserializer(JsonBuffer *buffer, TReader reader, | ||||||
|                    uint8_t nestingLimit) |                    TStringStorage stringStorage, uint8_t nestingLimit) | ||||||
|       : _buffer(buffer), |       : _buffer(buffer), | ||||||
|         _reader(reader), |         _reader(reader), | ||||||
|         _writer(writer), |         _stringStorage(stringStorage), | ||||||
|         _nestingLimit(nestingLimit), |         _nestingLimit(nestingLimit), | ||||||
|         _loaded(false) {} |         _loaded(false) {} | ||||||
|   DeserializationError parse(JsonVariant &variant) { |   DeserializationError parse(JsonVariant &variant) { | ||||||
| @@ -168,8 +167,8 @@ class JsonDeserializer { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   DeserializationError parseString(const char **result) { |   DeserializationError parseString(const char **result) { | ||||||
|     typename remove_reference<TWriter>::type::String str = |     typename remove_reference<TStringStorage>::type::String str = | ||||||
|         _writer.startString(); |         _stringStorage.startString(); | ||||||
|  |  | ||||||
|     char c = current(); |     char c = current(); | ||||||
|     if (c == '\0') return DeserializationError::IncompleteInput; |     if (c == '\0') return DeserializationError::IncompleteInput; | ||||||
| @@ -285,19 +284,35 @@ class JsonDeserializer { | |||||||
|  |  | ||||||
|   JsonBuffer *_buffer; |   JsonBuffer *_buffer; | ||||||
|   TReader _reader; |   TReader _reader; | ||||||
|   TWriter _writer; |   TStringStorage _stringStorage; | ||||||
|   uint8_t _nestingLimit; |   uint8_t _nestingLimit; | ||||||
|   char _current; |   char _current; | ||||||
|   bool _loaded; |   bool _loaded; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TReader, typename TWriter> |  | ||||||
| JsonDeserializer<TReader, TWriter> makeJsonDeserializer(TJsonBuffer *buffer, |  | ||||||
|                                                         TReader reader, |  | ||||||
|                                                         TWriter writer, |  | ||||||
|                                                         uint8_t nestingLimit) { |  | ||||||
|   return JsonDeserializer<TReader, TWriter>(buffer, reader, writer, |  | ||||||
|                                             nestingLimit); |  | ||||||
| } |  | ||||||
| }  // namespace Internals | }  // namespace Internals | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeJson(TDocument &doc, const TInput &input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<JsonDeserializer>(doc, input); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeJson(TDocument &doc, TInput *input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<JsonDeserializer>(doc, input); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeJson(TDocument &doc, TInput *input, | ||||||
|  |                                      size_t inputSize) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<JsonDeserializer>(doc, input, inputSize); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeJson(TDocument &doc, TInput &input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<JsonDeserializer>(doc, input); | ||||||
|  | } | ||||||
| }  // namespace ArduinoJson | }  // namespace ArduinoJson | ||||||
|   | |||||||
| @@ -4,37 +4,24 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Print/DummyPrint.hpp" | #include "../Serialization/measure.hpp" | ||||||
| #include "../Print/DynamicStringBuilder.hpp" | #include "../Serialization/serialize.hpp" | ||||||
| #include "../Print/StaticStringBuilder.hpp" |  | ||||||
| #include "./IndentedPrint.hpp" |  | ||||||
| #include "./JsonWriter.hpp" | #include "./JsonWriter.hpp" | ||||||
| #include "./Prettyfier.hpp" |  | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_STD_STREAM |  | ||||||
| #include "../Print/StreamPrintAdapter.hpp" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| template <typename Writer> | template <typename TPrint> | ||||||
| class JsonSerializer { | class JsonSerializer { | ||||||
|  public: |  public: | ||||||
|   template <typename TSource> |   JsonSerializer(TPrint &destination) : _writer(destination) {} | ||||||
|   static void serialize(const TSource &source, Writer &writer) { |  | ||||||
|     source.visit(Visitor(&writer)); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   struct Visitor { |  | ||||||
|     Visitor(Writer *writer) : _writer(writer) {} |  | ||||||
|  |  | ||||||
|   void acceptFloat(JsonFloat value) { |   void acceptFloat(JsonFloat value) { | ||||||
|       _writer->writeFloat(value); |     _writer.writeFloat(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptArray(const JsonArray &array) { |   void acceptArray(const JsonArray &array) { | ||||||
|       _writer->beginArray(); |     _writer.beginArray(); | ||||||
|  |  | ||||||
|     JsonArray::const_iterator it = array.begin(); |     JsonArray::const_iterator it = array.begin(); | ||||||
|     while (it != array.end()) { |     while (it != array.end()) { | ||||||
| @@ -43,141 +30,79 @@ class JsonSerializer { | |||||||
|       ++it; |       ++it; | ||||||
|       if (it == array.end()) break; |       if (it == array.end()) break; | ||||||
|  |  | ||||||
|         _writer->writeComma(); |       _writer.writeComma(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|       _writer->endArray(); |     _writer.endArray(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptObject(const JsonObject &object) { |   void acceptObject(const JsonObject &object) { | ||||||
|       _writer->beginObject(); |     _writer.beginObject(); | ||||||
|  |  | ||||||
|     JsonObject::const_iterator it = object.begin(); |     JsonObject::const_iterator it = object.begin(); | ||||||
|     while (it != object.end()) { |     while (it != object.end()) { | ||||||
|         _writer->writeString(it->key); |       _writer.writeString(it->key); | ||||||
|         _writer->writeColon(); |       _writer.writeColon(); | ||||||
|       it->value.visit(*this); |       it->value.visit(*this); | ||||||
|  |  | ||||||
|       ++it; |       ++it; | ||||||
|       if (it == object.end()) break; |       if (it == object.end()) break; | ||||||
|  |  | ||||||
|         _writer->writeComma(); |       _writer.writeComma(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|       _writer->endObject(); |     _writer.endObject(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptString(const char *value) { |   void acceptString(const char *value) { | ||||||
|       _writer->writeString(value); |     _writer.writeString(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptRawJson(const char *value) { |   void acceptRawJson(const char *value) { | ||||||
|       _writer->writeRaw(value); |     _writer.writeRaw(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptNegativeInteger(JsonUInt value) { |   void acceptNegativeInteger(JsonUInt value) { | ||||||
|       _writer->writeRaw('-'); |     _writer.writeRaw('-'); | ||||||
|       _writer->writeInteger(value); |     _writer.writeInteger(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptPositiveInteger(JsonUInt value) { |   void acceptPositiveInteger(JsonUInt value) { | ||||||
|       _writer->writeInteger(value); |     _writer.writeInteger(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptBoolean(bool value) { |   void acceptBoolean(bool value) { | ||||||
|       _writer->writeBoolean(value); |     _writer.writeBoolean(value); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   void acceptUndefined() {} |   void acceptUndefined() {} | ||||||
|  |  | ||||||
|     Writer *_writer; |   size_t bytesWritten() const { | ||||||
|   }; |     return _writer.bytesWritten(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   JsonWriter<TPrint> _writer; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| }  // namespace Internals | }  // namespace Internals | ||||||
|  |  | ||||||
| template <typename TSource, typename TDestination> | template <typename TSource, typename TDestination> | ||||||
| typename Internals::enable_if< | size_t serializeJson(TSource &source, TDestination &destination) { | ||||||
|     !Internals::StringTraits<TDestination>::has_append, size_t>::type |   using namespace Internals; | ||||||
| serializeJson(const TSource &source, TDestination &destination) { |   return serialize<JsonSerializer>(source, destination); | ||||||
|   Internals::JsonWriter<TDestination> writer(destination); |  | ||||||
|   Internals::JsonSerializer<Internals::JsonWriter<TDestination> >::serialize( |  | ||||||
|       source, writer); |  | ||||||
|   return writer.bytesWritten(); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_STD_STREAM |  | ||||||
| template <typename TSource> |  | ||||||
| std::ostream &serializeJson(const TSource &source, std::ostream &os) { |  | ||||||
|   Internals::StreamPrintAdapter adapter(os); |  | ||||||
|   serializeJson(source, adapter); |  | ||||||
|   return os; |  | ||||||
| } |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TSource> | ||||||
| size_t serializeJson(const TSource &source, char *buffer, size_t bufferSize) { | size_t serializeJson(const TSource &source, char *buffer, size_t bufferSize) { | ||||||
|   Internals::StaticStringBuilder sb(buffer, bufferSize); |   using namespace Internals; | ||||||
|   return serializeJson(source, sb); |   return serialize<JsonSerializer>(source, buffer, bufferSize); | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource, size_t N> |  | ||||||
| size_t serializeJson(const TSource &source, char (&buffer)[N]) { |  | ||||||
|   return serializeJson(source, buffer, N); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource, typename TDestination> |  | ||||||
| typename Internals::enable_if<Internals::StringTraits<TDestination>::has_append, |  | ||||||
|                               size_t>::type |  | ||||||
| serializeJson(const TSource &source, TDestination &str) { |  | ||||||
|   Internals::DynamicStringBuilder<TDestination> sb(str); |  | ||||||
|   return serializeJson(source, sb); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource, typename TDestination> |  | ||||||
| size_t serializeJsonPretty(const TSource &source, |  | ||||||
|                            Internals::IndentedPrint<TDestination> &print) { |  | ||||||
|   Internals::Prettyfier<TDestination> p(print); |  | ||||||
|   return serializeJson(source, p); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource> |  | ||||||
| size_t serializeJsonPretty(const TSource &source, char *buffer, |  | ||||||
|                            size_t bufferSize) { |  | ||||||
|   Internals::StaticStringBuilder sb(buffer, bufferSize); |  | ||||||
|   return serializeJsonPretty(source, sb); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource, size_t N> |  | ||||||
| size_t serializeJsonPretty(const TSource &source, char (&buffer)[N]) { |  | ||||||
|   return serializeJsonPretty(source, buffer, N); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource, typename TDestination> |  | ||||||
| typename Internals::enable_if< |  | ||||||
|     !Internals::StringTraits<TDestination>::has_append, size_t>::type |  | ||||||
| serializeJsonPretty(const TSource &source, TDestination &print) { |  | ||||||
|   Internals::IndentedPrint<TDestination> indentedPrint(print); |  | ||||||
|   return serializeJsonPretty(source, indentedPrint); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource, typename TDestination> |  | ||||||
| typename Internals::enable_if<Internals::StringTraits<TDestination>::has_append, |  | ||||||
|                               size_t>::type |  | ||||||
| serializeJsonPretty(const TSource &source, TDestination &str) { |  | ||||||
|   Internals::DynamicStringBuilder<TDestination> sb(str); |  | ||||||
|   return serializeJsonPretty(source, sb); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| template <typename TSource> | template <typename TSource> | ||||||
| size_t measureJson(const TSource &source) { | size_t measureJson(const TSource &source) { | ||||||
|   Internals::DummyPrint dp; |   using namespace Internals; | ||||||
|   return serializeJson(source, dp); |   return measure<JsonSerializer>(source); | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TSource> |  | ||||||
| size_t measureJsonPretty(const TSource &source) { |  | ||||||
|   Internals::DummyPrint dp; |  | ||||||
|   return serializeJsonPretty(source, dp); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_STD_STREAM | #if ARDUINOJSON_ENABLE_STD_STREAM | ||||||
|   | |||||||
							
								
								
									
										57
									
								
								src/ArduinoJson/Json/PrettyJsonSerializer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/ArduinoJson/Json/PrettyJsonSerializer.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "../Serialization/measure.hpp" | ||||||
|  | #include "../Serialization/serialize.hpp" | ||||||
|  | #include "./IndentedPrint.hpp" | ||||||
|  | #include "./JsonSerializer.hpp" | ||||||
|  | #include "./Prettyfier.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <typename TPrint> | ||||||
|  | class PrettyJsonSerializer_Base { | ||||||
|  |  public: | ||||||
|  |   PrettyJsonSerializer_Base(TPrint &output) | ||||||
|  |       : _indentedPrint(output), _prettyfier(_indentedPrint) {} | ||||||
|  |  | ||||||
|  |  protected: | ||||||
|  |   IndentedPrint<TPrint> _indentedPrint; | ||||||
|  |   Prettyfier<TPrint> _prettyfier; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename TPrint> | ||||||
|  | class PrettyJsonSerializer : PrettyJsonSerializer_Base<TPrint>, | ||||||
|  |                              public JsonSerializer<Prettyfier<TPrint> > { | ||||||
|  |  public: | ||||||
|  |   PrettyJsonSerializer(TPrint &output) | ||||||
|  |       : PrettyJsonSerializer_Base<TPrint>(output), | ||||||
|  |         JsonSerializer<Prettyfier<TPrint> >( | ||||||
|  |             PrettyJsonSerializer_Base<TPrint>::_prettyfier) {} | ||||||
|  | }; | ||||||
|  | }  // namespace Internals | ||||||
|  |  | ||||||
|  | template <typename TSource, typename TDestination> | ||||||
|  | size_t serializeJsonPretty(TSource &source, TDestination &destination) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return serialize<PrettyJsonSerializer>(source, destination); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TSource> | ||||||
|  | size_t serializeJsonPretty(const TSource &source, char *buffer, | ||||||
|  |                            size_t bufferSize) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return serialize<PrettyJsonSerializer>(source, buffer, bufferSize); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TSource> | ||||||
|  | size_t measureJsonPretty(const TSource &source) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return measure<PrettyJsonSerializer>(source); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace ArduinoJson | ||||||
| @@ -179,7 +179,7 @@ class JsonArray : public Internals::ReferenceType, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename Visitor> | ||||||
|   void visit(Visitor visitor) const { |   void visit(Visitor &visitor) const { | ||||||
|     return visitor.acceptArray(*this); |     return visitor.acceptArray(*this); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -75,7 +75,7 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename Visitor> | ||||||
|   void visit(Visitor visitor) const { |   void visit(Visitor& visitor) const { | ||||||
|     return _array.get<JsonVariant>(_index).visit(visitor); |     return _array.get<JsonVariant>(_index).visit(visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -227,7 +227,7 @@ class JsonObject : public Internals::ReferenceType, | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename Visitor> | ||||||
|   void visit(Visitor visitor) const { |   void visit(Visitor& visitor) const { | ||||||
|     return visitor.acceptObject(*this); |     return visitor.acceptObject(*this); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -83,7 +83,7 @@ class JsonObjectSubscript | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename Visitor> | ||||||
|   void visit(Visitor visitor) const { |   void visit(Visitor& visitor) const { | ||||||
|     return _object.get<JsonVariant>(_key).visit(visitor); |     return _object.get<JsonVariant>(_key).visit(visitor); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> { | |||||||
|       _content.asInteger = static_cast<JsonUInt>(value); |       _content.asInteger = static_cast<JsonUInt>(value); | ||||||
|     } else { |     } else { | ||||||
|       _type = JSON_NEGATIVE_INTEGER; |       _type = JSON_NEGATIVE_INTEGER; | ||||||
|       _content.asInteger = static_cast<JsonUInt>(-value); |       _content.asInteger = ~static_cast<JsonUInt>(value) + 1; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|   // JsonVariant(unsigned short) |   // JsonVariant(unsigned short) | ||||||
| @@ -308,7 +308,7 @@ class JsonVariant : public Internals::JsonVariantBase<JsonVariant> { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename Visitor> | ||||||
|   void visit(Visitor visitor) const { |   void visit(Visitor &visitor) const { | ||||||
|     using namespace Internals; |     using namespace Internals; | ||||||
|     switch (_type) { |     switch (_type) { | ||||||
|       case JSON_FLOAT: |       case JSON_FLOAT: | ||||||
|   | |||||||
| @@ -4,26 +4,24 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../DeserializationError.hpp" | #include "../Deserialization/deserialize.hpp" | ||||||
| #include "../JsonVariant.hpp" | #include "../JsonVariant.hpp" | ||||||
| #include "../Memory/JsonBuffer.hpp" | #include "../Memory/JsonBuffer.hpp" | ||||||
| #include "../Polyfills/type_traits.hpp" | #include "../Polyfills/type_traits.hpp" | ||||||
| #include "../Reading/Reader.hpp" |  | ||||||
| #include "../Writing/Writer.hpp" |  | ||||||
| #include "./endianess.hpp" | #include "./endianess.hpp" | ||||||
| #include "./ieee754.hpp" | #include "./ieee754.hpp" | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| template <typename TReader, typename TWriter> | template <typename TReader, typename TStringStorage> | ||||||
| class MsgPackDeserializer { | class MsgPackDeserializer { | ||||||
|  public: |  public: | ||||||
|   MsgPackDeserializer(JsonBuffer *buffer, TReader reader, TWriter writer, |   MsgPackDeserializer(JsonBuffer *buffer, TReader reader, | ||||||
|                       uint8_t nestingLimit) |                       TStringStorage stringStorage, uint8_t nestingLimit) | ||||||
|       : _buffer(buffer), |       : _buffer(buffer), | ||||||
|         _reader(reader), |         _reader(reader), | ||||||
|         _writer(writer), |         _stringStorage(stringStorage), | ||||||
|         _nestingLimit(nestingLimit) {} |         _nestingLimit(nestingLimit) {} | ||||||
|  |  | ||||||
|   DeserializationError parse(JsonVariant &variant) { |   DeserializationError parse(JsonVariant &variant) { | ||||||
| @@ -221,8 +219,8 @@ class MsgPackDeserializer { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   DeserializationError readString(JsonVariant &variant, size_t n) { |   DeserializationError readString(JsonVariant &variant, size_t n) { | ||||||
|     typename remove_reference<TWriter>::type::String str = |     typename remove_reference<TStringStorage>::type::String str = | ||||||
|         _writer.startString(); |         _stringStorage.startString(); | ||||||
|     for (; n; --n) { |     for (; n; --n) { | ||||||
|       uint8_t c; |       uint8_t c; | ||||||
|       if (!readBytes(c)) return DeserializationError::IncompleteInput; |       if (!readBytes(c)) return DeserializationError::IncompleteInput; | ||||||
| @@ -295,15 +293,33 @@ class MsgPackDeserializer { | |||||||
|  |  | ||||||
|   JsonBuffer *_buffer; |   JsonBuffer *_buffer; | ||||||
|   TReader _reader; |   TReader _reader; | ||||||
|   TWriter _writer; |   TStringStorage _stringStorage; | ||||||
|   uint8_t _nestingLimit; |   uint8_t _nestingLimit; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TReader, typename TWriter> |  | ||||||
| MsgPackDeserializer<TReader, TWriter> makeMsgPackDeserializer( |  | ||||||
|     TJsonBuffer *buffer, TReader reader, TWriter writer, uint8_t nestingLimit) { |  | ||||||
|   return MsgPackDeserializer<TReader, TWriter>(buffer, reader, writer, |  | ||||||
|                                                nestingLimit); |  | ||||||
| } |  | ||||||
| }  // namespace Internals | }  // namespace Internals | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeMsgPack(TDocument &doc, const TInput &input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<MsgPackDeserializer>(doc, input); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeMsgPack(TDocument &doc, TInput *input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<MsgPackDeserializer>(doc, input); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeMsgPack(TDocument &doc, TInput *input, | ||||||
|  |                                         size_t inputSize) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<MsgPackDeserializer>(doc, input, inputSize); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TDocument, typename TInput> | ||||||
|  | DeserializationError deserializeMsgPack(TDocument &doc, TInput &input) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return deserialize<MsgPackDeserializer>(doc, input); | ||||||
|  | } | ||||||
| }  // namespace ArduinoJson | }  // namespace ArduinoJson | ||||||
|   | |||||||
							
								
								
									
										191
									
								
								src/ArduinoJson/MsgPack/MsgPackSerializer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								src/ArduinoJson/MsgPack/MsgPackSerializer.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,191 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "../JsonVariant.hpp" | ||||||
|  | #include "../Polyfills/type_traits.hpp" | ||||||
|  | #include "../Serialization/measure.hpp" | ||||||
|  | #include "../Serialization/serialize.hpp" | ||||||
|  | #include "./endianess.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <typename TPrint> | ||||||
|  | class MsgPackSerializer { | ||||||
|  |  public: | ||||||
|  |   MsgPackSerializer(TPrint& output) : _output(&output), _bytesWritten(0) {} | ||||||
|  |  | ||||||
|  |   template <typename T> | ||||||
|  |   typename enable_if<sizeof(T) == 4>::type acceptFloat(T value32) { | ||||||
|  |     writeByte(0xCA); | ||||||
|  |     writeInteger(value32); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename T> | ||||||
|  |   typename enable_if<sizeof(T) == 8>::type acceptFloat(T value64) { | ||||||
|  |     float value32 = float(value64); | ||||||
|  |     if (value32 == value64) { | ||||||
|  |       writeByte(0xCA); | ||||||
|  |       writeInteger(value32); | ||||||
|  |     } else { | ||||||
|  |       writeByte(0xCB); | ||||||
|  |       writeInteger(value64); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void acceptArray(const JsonArray& array) { | ||||||
|  |     size_t n = array.size(); | ||||||
|  |     if (n < 0x10) { | ||||||
|  |       writeByte(uint8_t(0x90 + array.size())); | ||||||
|  |     } else if (n < 0x10000) { | ||||||
|  |       writeByte(0xDC); | ||||||
|  |       writeInteger(uint16_t(n)); | ||||||
|  |     } else { | ||||||
|  |       writeByte(0xDD); | ||||||
|  |       writeInteger(uint32_t(n)); | ||||||
|  |     } | ||||||
|  |     for (JsonArray::const_iterator it = array.begin(); it != array.end(); | ||||||
|  |          ++it) { | ||||||
|  |       it->visit(*this); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void acceptObject(const JsonObject& object) { | ||||||
|  |     size_t n = object.size(); | ||||||
|  |     if (n < 0x10) { | ||||||
|  |       writeByte(uint8_t(0x80 + n)); | ||||||
|  |     } else if (n < 0x10000) { | ||||||
|  |       writeByte(0xDE); | ||||||
|  |       writeInteger(uint16_t(n)); | ||||||
|  |     } else { | ||||||
|  |       writeByte(0xDF); | ||||||
|  |       writeInteger(uint32_t(n)); | ||||||
|  |     } | ||||||
|  |     for (JsonObject::const_iterator it = object.begin(); it != object.end(); | ||||||
|  |          ++it) { | ||||||
|  |       acceptString(it->key); | ||||||
|  |       it->value.visit(*this); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void acceptString(const char* value) { | ||||||
|  |     if (!value) return writeByte(0xC0);  // nil | ||||||
|  |  | ||||||
|  |     size_t n = strlen(value); | ||||||
|  |  | ||||||
|  |     if (n < 0x20) { | ||||||
|  |       writeByte(uint8_t(0xA0 + n)); | ||||||
|  |     } else if (n < 0x100) { | ||||||
|  |       writeByte(0xD9); | ||||||
|  |       writeInteger(uint8_t(n)); | ||||||
|  |     } else if (n < 0x10000) { | ||||||
|  |       writeByte(0xDA); | ||||||
|  |       writeInteger(uint16_t(n)); | ||||||
|  |     } else { | ||||||
|  |       writeByte(0xDB); | ||||||
|  |       writeInteger(uint32_t(n)); | ||||||
|  |     } | ||||||
|  |     writeBytes(reinterpret_cast<const uint8_t*>(value), n); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void acceptRawJson(const char* /*value*/) {} | ||||||
|  |  | ||||||
|  |   void acceptNegativeInteger(JsonUInt value) { | ||||||
|  |     JsonUInt negated = JsonUInt(~value + 1); | ||||||
|  |     if (value <= 0x20) { | ||||||
|  |       writeInteger(int8_t(negated)); | ||||||
|  |     } else if (value <= 0x80) { | ||||||
|  |       writeByte(0xD0); | ||||||
|  |       writeInteger(int8_t(negated)); | ||||||
|  |     } else if (value <= 0x8000) { | ||||||
|  |       writeByte(0xD1); | ||||||
|  |       writeInteger(int16_t(negated)); | ||||||
|  |     } else if (value <= 0x80000000) { | ||||||
|  |       writeByte(0xD2); | ||||||
|  |       writeInteger(int32_t(negated)); | ||||||
|  |     } | ||||||
|  | #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 | ||||||
|  |     else { | ||||||
|  |       writeByte(0xD3); | ||||||
|  |       writeInteger(int64_t(negated)); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void acceptPositiveInteger(JsonUInt value) { | ||||||
|  |     if (value <= 0x7F) { | ||||||
|  |       writeInteger(uint8_t(value)); | ||||||
|  |     } else if (value <= 0xFF) { | ||||||
|  |       writeByte(0xCC); | ||||||
|  |       writeInteger(uint8_t(value)); | ||||||
|  |     } else if (value <= 0xFFFF) { | ||||||
|  |       writeByte(0xCD); | ||||||
|  |       writeInteger(uint16_t(value)); | ||||||
|  |     } else if (value <= 0xFFFFFFFF) { | ||||||
|  |       writeByte(0xCE); | ||||||
|  |       writeInteger(uint32_t(value)); | ||||||
|  |     } | ||||||
|  | #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 | ||||||
|  |     else { | ||||||
|  |       writeByte(0xCF); | ||||||
|  |       writeInteger(uint64_t(value)); | ||||||
|  |     } | ||||||
|  | #endif | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void acceptBoolean(bool value) { | ||||||
|  |     writeByte(value ? 0xC3 : 0xC2); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void acceptUndefined() { | ||||||
|  |     writeByte(0xC0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   size_t bytesWritten() const { | ||||||
|  |     return _bytesWritten; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  private: | ||||||
|  |   void writeByte(uint8_t c) { | ||||||
|  |     _output->print(char(c)); | ||||||
|  |     _bytesWritten++; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   void writeBytes(const uint8_t* c, size_t n) { | ||||||
|  |     for (; n > 0; --n, ++c) writeByte(*c); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename T> | ||||||
|  |   void writeInteger(T value) { | ||||||
|  |     fixEndianess(value); | ||||||
|  |     writeBytes(reinterpret_cast<uint8_t*>(&value), sizeof(value)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   TPrint* _output; | ||||||
|  |   size_t _bytesWritten; | ||||||
|  | }; | ||||||
|  | }  // namespace Internals | ||||||
|  |  | ||||||
|  | template <typename TSource, typename TDestination> | ||||||
|  | inline size_t serializeMsgPack(const TSource& source, TDestination& output) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return serialize<MsgPackSerializer>(source, output); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TSource, typename TDestination> | ||||||
|  | inline size_t serializeMsgPack(const TSource& source, TDestination* output, | ||||||
|  |                                size_t size) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return serialize<MsgPackSerializer>(source, output, size); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TSource> | ||||||
|  | inline size_t measureMsgPack(const TSource& source) { | ||||||
|  |   using namespace Internals; | ||||||
|  |   return measure<MsgPackSerializer>(source); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace ArduinoJson | ||||||
| @@ -5,17 +5,11 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Polyfills/type_traits.hpp" | #include "../Polyfills/type_traits.hpp" | ||||||
|  | #include "../Polyfills/utility.hpp" | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|  |  | ||||||
| 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>) { | inline void fixEndianess(uint8_t* p, integral_constant<size_t, 8>) { | ||||||
|   swap(p[0], p[7]); |   swap(p[0], p[7]); | ||||||
|   swap(p[1], p[6]); |   swap(p[1], p[6]); | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								src/ArduinoJson/Polyfills/utility.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/ArduinoJson/Polyfills/utility.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  | template <typename T> | ||||||
|  | inline void swap(T& a, T& b) { | ||||||
|  |   T t(a); | ||||||
|  |   a = b; | ||||||
|  |   b = t; | ||||||
|  | } | ||||||
|  | }  // namespace Internals | ||||||
|  | }  // namespace ArduinoJson | ||||||
| @@ -1,11 +0,0 @@ | |||||||
| // ArduinoJson - arduinojson.org |  | ||||||
| // Copyright Benoit Blanchon 2014-2018 |  | ||||||
| // MIT License |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "./ArduinoStreamReader.hpp" |  | ||||||
| #include "./CharPointerReader.hpp" |  | ||||||
| #include "./FlashStringReader.hpp" |  | ||||||
| #include "./IteratorReader.hpp" |  | ||||||
| #include "./StdStreamReader.hpp" |  | ||||||
| @@ -7,7 +7,6 @@ | |||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
| 
 | 
 | ||||||
| // A dummy Print implementation used in measureJson()
 |  | ||||||
| class DummyPrint { | class DummyPrint { | ||||||
|  public: |  public: | ||||||
|   size_t print(char) { |   size_t print(char) { | ||||||
| @@ -32,5 +32,5 @@ class StaticStringBuilder { | |||||||
|   char *end; |   char *end; | ||||||
|   char *p; |   char *p; | ||||||
| }; | }; | ||||||
| } | }  // namespace Internals
 | ||||||
| } | }  // namespace ArduinoJson
 | ||||||
							
								
								
									
										21
									
								
								src/ArduinoJson/Serialization/measure.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/ArduinoJson/Serialization/measure.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "./DummyPrint.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <template <typename> class TSerializer, typename TSource> | ||||||
|  | size_t measure(const TSource &source) { | ||||||
|  |   DummyPrint dp; | ||||||
|  |   TSerializer<DummyPrint> serializer(dp); | ||||||
|  |   source.visit(serializer); | ||||||
|  |   return serializer.bytesWritten(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace Internals | ||||||
|  | }  // namespace ArduinoJson | ||||||
							
								
								
									
										55
									
								
								src/ArduinoJson/Serialization/serialize.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/ArduinoJson/Serialization/serialize.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "./DynamicStringBuilder.hpp" | ||||||
|  | #include "./StaticStringBuilder.hpp" | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_STD_STREAM | ||||||
|  | #include "./StreamPrintAdapter.hpp" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <template <typename> class TSerializer, typename TSource, | ||||||
|  |           typename TPrint> | ||||||
|  | typename enable_if<!StringTraits<TPrint>::has_append, size_t>::type serialize( | ||||||
|  |     const TSource &source, TPrint &destination) { | ||||||
|  |   TSerializer<TPrint> serializer(destination); | ||||||
|  |   source.visit(serializer); | ||||||
|  |   return serializer.bytesWritten(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_STD_STREAM | ||||||
|  | template <template <typename> class TSerializer, typename TSource> | ||||||
|  | size_t serialize(const TSource &source, std::ostream &os) { | ||||||
|  |   StreamPrintAdapter adapter(os); | ||||||
|  |   return serialize<TSerializer>(source, adapter); | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | template <template <typename> class TSerializer, typename TSource> | ||||||
|  | size_t serialize(const TSource &source, char *buffer, size_t bufferSize) { | ||||||
|  |   StaticStringBuilder sb(buffer, bufferSize); | ||||||
|  |   return serialize<TSerializer>(source, sb); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <template <typename> class TSerializer, typename TSource, size_t N> | ||||||
|  | size_t serialize(const TSource &source, char (&buffer)[N]) { | ||||||
|  |   StaticStringBuilder sb(buffer, N); | ||||||
|  |   return serialize<TSerializer>(source, sb); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <template <typename> class TSerializer, typename TSource, | ||||||
|  |           typename TString> | ||||||
|  | typename enable_if<StringTraits<TString>::has_append, size_t>::type serialize( | ||||||
|  |     const TSource &source, TString &str) { | ||||||
|  |   DynamicStringBuilder<TString> sb(str); | ||||||
|  |   return serialize<TSerializer>(source, sb); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | }  // namespace Internals | ||||||
|  | }  // namespace ArduinoJson | ||||||
| @@ -76,7 +76,7 @@ class StaticJsonDocument { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   template <typename Visitor> |   template <typename Visitor> | ||||||
|   void visit(Visitor visitor) const { |   void visit(Visitor& visitor) const { | ||||||
|     return _root.visit(visitor); |     return _root.visit(visitor); | ||||||
|   } |   } | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -4,15 +4,13 @@ | |||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "./StringWriter.hpp" |  | ||||||
| 
 |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
| 
 | 
 | ||||||
| template <typename TJsonBuffer> | template <typename TJsonBuffer> | ||||||
| class JsonBufferWriter { | class StringCopier { | ||||||
|  public: |  public: | ||||||
|   JsonBufferWriter(TJsonBuffer& jb) : _jb(&jb) {} |   StringCopier(TJsonBuffer& jb) : _jb(&jb) {} | ||||||
| 
 | 
 | ||||||
|   typedef typename TJsonBuffer::String String; |   typedef typename TJsonBuffer::String String; | ||||||
| 
 | 
 | ||||||
| @@ -8,7 +8,7 @@ namespace ArduinoJson { | |||||||
| namespace Internals { | namespace Internals { | ||||||
| 
 | 
 | ||||||
| template <typename TChar> | template <typename TChar> | ||||||
| class StringWriter { | class StringMover { | ||||||
|  public: |  public: | ||||||
|   class String { |   class String { | ||||||
|    public: |    public: | ||||||
| @@ -28,7 +28,7 @@ class StringWriter { | |||||||
|     TChar* _startPtr; |     TChar* _startPtr; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   StringWriter(TChar* buffer) : _ptr(buffer) {} |   StringMover(TChar* buffer) : _ptr(buffer) {} | ||||||
| 
 | 
 | ||||||
|   String startString() { |   String startString() { | ||||||
|     return String(&_ptr); |     return String(&_ptr); | ||||||
| @@ -37,5 +37,5 @@ class StringWriter { | |||||||
|  private: |  private: | ||||||
|   TChar* _ptr; |   TChar* _ptr; | ||||||
| }; | }; | ||||||
| } | }  // namespace Internals
 | ||||||
| } | }  // namespace ArduinoJson
 | ||||||
							
								
								
									
										44
									
								
								src/ArduinoJson/StringStorage/StringStorage.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/ArduinoJson/StringStorage/StringStorage.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "./StringCopier.hpp" | ||||||
|  | #include "./StringMover.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <typename TJsonBuffer, typename TInput, typename Enable = void> | ||||||
|  | struct StringStorage { | ||||||
|  |   typedef StringCopier<TJsonBuffer> type; | ||||||
|  |  | ||||||
|  |   static type create(TJsonBuffer& jb, TInput&) { | ||||||
|  |     return type(jb); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename TJsonBuffer, typename TChar> | ||||||
|  | struct StringStorage<TJsonBuffer, TChar*, | ||||||
|  |                      typename enable_if<!is_const<TChar>::value>::type> { | ||||||
|  |   typedef StringMover<TChar> type; | ||||||
|  |  | ||||||
|  |   static type create(TJsonBuffer&, TChar* input) { | ||||||
|  |     return type(input); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename TJsonBuffer, typename TInput> | ||||||
|  | typename StringStorage<TJsonBuffer, TInput>::type makeStringStorage( | ||||||
|  |     TJsonBuffer& jb, TInput& input) { | ||||||
|  |   return StringStorage<TJsonBuffer, TInput>::create(jb, input); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <typename TJsonBuffer, typename TChar> | ||||||
|  | typename StringStorage<TJsonBuffer, TChar*>::type makeStringStorage( | ||||||
|  |     TJsonBuffer& jb, TChar* input) { | ||||||
|  |   return StringStorage<TJsonBuffer, TChar*>::create(jb, input); | ||||||
|  | } | ||||||
|  | }  // namespace Internals | ||||||
|  | }  // namespace ArduinoJson | ||||||
| @@ -1,44 +0,0 @@ | |||||||
| // ArduinoJson - arduinojson.org |  | ||||||
| // Copyright Benoit Blanchon 2014-2018 |  | ||||||
| // MIT License |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "./JsonBufferWriter.hpp" |  | ||||||
| #include "./StringWriter.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { |  | ||||||
| namespace Internals { |  | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TInput, typename Enable = void> |  | ||||||
| struct Writer { |  | ||||||
|   typedef JsonBufferWriter<TJsonBuffer> type; |  | ||||||
|  |  | ||||||
|   static type create(TJsonBuffer& jb, TInput&) { |  | ||||||
|     return type(jb); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TChar> |  | ||||||
| struct Writer<TJsonBuffer, TChar*, |  | ||||||
|               typename enable_if<!is_const<TChar>::value>::type> { |  | ||||||
|   typedef StringWriter<TChar> type; |  | ||||||
|  |  | ||||||
|   static type create(TJsonBuffer&, TChar* input) { |  | ||||||
|     return type(input); |  | ||||||
|   } |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TInput> |  | ||||||
| typename Writer<TJsonBuffer, TInput>::type makeWriter(TJsonBuffer& jb, |  | ||||||
|                                                       TInput& input) { |  | ||||||
|   return Writer<TJsonBuffer, TInput>::create(jb, input); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TChar> |  | ||||||
| typename Writer<TJsonBuffer, TChar*>::type makeWriter(TJsonBuffer& jb, |  | ||||||
|                                                       TChar* input) { |  | ||||||
|   return Writer<TJsonBuffer, TChar*>::create(jb, input); |  | ||||||
| } |  | ||||||
| }  // namespace Internals |  | ||||||
| }  // namespace ArduinoJson |  | ||||||
| @@ -1,58 +0,0 @@ | |||||||
| // ArduinoJson - arduinojson.org |  | ||||||
| // Copyright Benoit Blanchon 2014-2018 |  | ||||||
| // MIT License |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "Json/JsonDeserializer.hpp" |  | ||||||
| #include "Reading/Reader.hpp" |  | ||||||
| #include "Writing/Writer.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { |  | ||||||
| // DeserializationError deserializeJson(TDocument& doc, TString input); |  | ||||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument |  | ||||||
| // TString = const std::string&, const String& |  | ||||||
| template <typename TDocument, typename TString> |  | ||||||
| typename Internals::enable_if<!Internals::is_array<TString>::value, |  | ||||||
|                               DeserializationError>::type |  | ||||||
| deserializeJson(TDocument &doc, const TString &input) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeJsonDeserializer(&doc.buffer(), makeReader(input), |  | ||||||
|                               makeWriter(doc.buffer(), input), doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| // |  | ||||||
| // DeserializationError deserializeJson(TDocument& doc, TChar* input); |  | ||||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument |  | ||||||
| // TChar* = char*, const char*, const FlashStringHelper* |  | ||||||
| template <typename TDocument, typename TChar> |  | ||||||
| DeserializationError deserializeJson(TDocument &doc, TChar *input) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeJsonDeserializer(&doc.buffer(), makeReader(input), |  | ||||||
|                               makeWriter(doc.buffer(), input), doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| // |  | ||||||
| // DeserializationError deserializeJson(TDocument& doc, TChar* input, size_t |  | ||||||
| // inputSize); TDocument = DynamicJsonDocument, StaticJsonDocument TChar* = |  | ||||||
| // char*, const char*, const FlashStringHelper* |  | ||||||
| template <typename TDocument, typename TChar> |  | ||||||
| DeserializationError deserializeJson(TDocument &doc, TChar *input, |  | ||||||
|                                      size_t inputSize) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeJsonDeserializer(&doc.buffer(), makeReader(input, inputSize), |  | ||||||
|                               makeWriter(doc.buffer(), input), doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| // |  | ||||||
| // DeserializationError deserializeJson(TDocument& doc, TStream input); |  | ||||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument |  | ||||||
| // TStream = std::istream&, Stream& |  | ||||||
| template <typename TDocument, typename TStream> |  | ||||||
| DeserializationError deserializeJson(TDocument &doc, TStream &input) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeJsonDeserializer(&doc.buffer(), makeReader(input), |  | ||||||
|                               makeWriter(doc.buffer(), input), doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| }  // namespace ArduinoJson |  | ||||||
| @@ -1,63 +0,0 @@ | |||||||
| // ArduinoJson - arduinojson.org |  | ||||||
| // Copyright Benoit Blanchon 2014-2018 |  | ||||||
| // MIT License |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "MsgPack/MsgPackDeserializer.hpp" |  | ||||||
| #include "Reading/Reader.hpp" |  | ||||||
| #include "Writing/Writer.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { |  | ||||||
| // DeserializationError deserializeMsgPack(TDocument& doc, TString input); |  | ||||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument |  | ||||||
| // TString = const std::string&, const String& |  | ||||||
| template <typename TDocument, typename TString> |  | ||||||
| typename Internals::enable_if<!Internals::is_array<TString>::value, |  | ||||||
|                               DeserializationError>::type |  | ||||||
| deserializeMsgPack(TDocument &doc, const TString &input) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), |  | ||||||
|                                  makeWriter(doc.buffer(), input), |  | ||||||
|                                  doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| // |  | ||||||
| // DeserializationError deserializeMsgPack(TDocument& doc, TChar* input); |  | ||||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument |  | ||||||
| // TChar* = char*, const char*, const FlashStringHelper* |  | ||||||
| template <typename TDocument, typename TChar> |  | ||||||
| DeserializationError deserializeMsgPack(TDocument &doc, TChar *input) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), |  | ||||||
|                                  makeWriter(doc.buffer(), input), |  | ||||||
|                                  doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| // |  | ||||||
| // DeserializationError deserializeMsgPack(TDocument& doc, TChar* input, size_t |  | ||||||
| // inputSize); |  | ||||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument |  | ||||||
| // TChar* = char*, const char*, const FlashStringHelper* |  | ||||||
| template <typename TDocument, typename TChar> |  | ||||||
| DeserializationError deserializeMsgPack(TDocument &doc, TChar *input, |  | ||||||
|                                         size_t inputSize) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeMsgPackDeserializer(&doc.buffer(), makeReader(input, inputSize), |  | ||||||
|                                  makeWriter(doc.buffer(), input), |  | ||||||
|                                  doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| // |  | ||||||
| // DeserializationError deserializeMsgPack(TDocument& doc, TStream input); |  | ||||||
| // TDocument = DynamicJsonDocument, StaticJsonDocument |  | ||||||
| // TStream = std::istream&, Stream& |  | ||||||
| template <typename TDocument, typename TStream> |  | ||||||
| DeserializationError deserializeMsgPack(TDocument &doc, TStream &input) { |  | ||||||
|   using namespace Internals; |  | ||||||
|   return makeMsgPackDeserializer(&doc.buffer(), makeReader(input), |  | ||||||
|                                  makeWriter(doc.buffer(), input), |  | ||||||
|                                  doc.nestingLimit) |  | ||||||
|       .parse(doc.template to<JsonVariant>()); |  | ||||||
| } |  | ||||||
| }  // namespace ArduinoJson |  | ||||||
| @@ -73,6 +73,7 @@ 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(MsgPackDeserializer) | ||||||
|  | add_subdirectory(MsgPackSerializer) | ||||||
| add_subdirectory(Polyfills) | add_subdirectory(Polyfills) | ||||||
| add_subdirectory(StaticJsonBuffer) | add_subdirectory(StaticJsonBuffer) | ||||||
|   | |||||||
| @@ -38,7 +38,13 @@ TEST_CASE("DeserializationError") { | |||||||
|     TEST_BOOLIFICATION(NotSupported, true); |     TEST_BOOLIFICATION(NotSupported, true); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("ostream") { |   SECTION("ostream code") { | ||||||
|  |     std::stringstream s; | ||||||
|  |     s << DeserializationError(DeserializationError::InvalidInput); | ||||||
|  |     REQUIRE(s.str() == "InvalidInput"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("ostream code") { | ||||||
|     std::stringstream s; |     std::stringstream s; | ||||||
|     s << DeserializationError::InvalidInput; |     s << DeserializationError::InvalidInput; | ||||||
|     REQUIRE(s.str() == "InvalidInput"); |     REQUIRE(s.str() == "InvalidInput"); | ||||||
|   | |||||||
| @@ -15,14 +15,14 @@ TEST_CASE("serialize JsonArray to std::string") { | |||||||
|     std::string json; |     std::string json; | ||||||
|     serializeJson(array, json); |     serializeJson(array, json); | ||||||
|  |  | ||||||
|     REQUIRE(std::string("[4,2]") == json); |     REQUIRE("[4,2]" == json); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("serializeJsonPretty") { |   SECTION("serializeJsonPretty") { | ||||||
|     std::string json; |     std::string json; | ||||||
|     serializeJsonPretty(array, json); |     serializeJsonPretty(array, json); | ||||||
|  |  | ||||||
|     REQUIRE(std::string("[\r\n  4,\r\n  2\r\n]") == json); |     REQUIRE("[\r\n  4,\r\n  2\r\n]" == json); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -35,13 +35,13 @@ TEST_CASE("serialize JsonObject to std::string") { | |||||||
|     std::string json; |     std::string json; | ||||||
|     serializeJson(doc, json); |     serializeJson(doc, json); | ||||||
|  |  | ||||||
|     REQUIRE(std::string("{\"key\":\"value\"}") == json); |     REQUIRE("{\"key\":\"value\"}" == json); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   SECTION("serializeJsonPretty") { |   SECTION("serializeJsonPretty") { | ||||||
|     std::string json; |     std::string json; | ||||||
|     serializeJsonPretty(doc, json); |     serializeJsonPretty(doc, json); | ||||||
|  |  | ||||||
|     REQUIRE(std::string("{\r\n  \"key\": \"value\"\r\n}") == json); |     REQUIRE("{\r\n  \"key\": \"value\"\r\n}" == json); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| #include <string> | #include <string> | ||||||
|  |  | ||||||
| #include <ArduinoJson/Json/JsonWriter.hpp> | #include <ArduinoJson/Json/JsonWriter.hpp> | ||||||
| #include <ArduinoJson/Print/DynamicStringBuilder.hpp> | #include <ArduinoJson/Serialization/DynamicStringBuilder.hpp> | ||||||
|  |  | ||||||
| using namespace ArduinoJson::Internals; | using namespace ArduinoJson::Internals; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ | |||||||
| #include <catch.hpp> | #include <catch.hpp> | ||||||
|  |  | ||||||
| #include <ArduinoJson/Json/JsonWriter.hpp> | #include <ArduinoJson/Json/JsonWriter.hpp> | ||||||
| #include <ArduinoJson/Print/StaticStringBuilder.hpp> | #include <ArduinoJson/Serialization/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 | ||||||
| 
 | 
 | ||||||
| add_executable(MsgPackTests | add_executable(MsgPackDeserializerTests | ||||||
| 	deserializeArray.cpp | 	deserializeArray.cpp | ||||||
| 	deserializeObject.cpp | 	deserializeObject.cpp | ||||||
| 	deserializeStaticVariant.cpp | 	deserializeStaticVariant.cpp | ||||||
| @@ -15,5 +15,5 @@ add_executable(MsgPackTests | |||||||
| 	std_istream.cpp | 	std_istream.cpp | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| target_link_libraries(MsgPackTests catch) | target_link_libraries(MsgPackDeserializerTests catch) | ||||||
| add_test(MsgPack MsgPackTests) | add_test(MsgPackDeserializer MsgPackDeserializerTests) | ||||||
| @@ -5,7 +5,7 @@ | |||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <catch.hpp> | #include <catch.hpp> | ||||||
| 
 | 
 | ||||||
| TEST_CASE("deserializeMsgPack(JsonArray&)") { | TEST_CASE("deserialize MsgPack array") { | ||||||
|   DynamicJsonDocument doc; |   DynamicJsonDocument doc; | ||||||
| 
 | 
 | ||||||
|   SECTION("fixarray") { |   SECTION("fixarray") { | ||||||
| @@ -16,7 +16,7 @@ static void check(const char* input, U expected) { | |||||||
|   REQUIRE(variant.as<T>() == expected); |   REQUIRE(variant.as<T>() == expected); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TEST_CASE("deserializeMsgPack(JsonVariant&)") { | TEST_CASE("deserialize MsgPack value") { | ||||||
|   SECTION("nil") { |   SECTION("nil") { | ||||||
|     const char* nil = 0;  // ArduinoJson uses a string for null
 |     const char* nil = 0;  // ArduinoJson uses a string for null
 | ||||||
|     check<const char*>("\xc0", nil); |     check<const char*>("\xc0", nil); | ||||||
							
								
								
									
										14
									
								
								test/MsgPackSerializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								test/MsgPackSerializer/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | # ArduinoJson - arduinojson.org | ||||||
|  | # Copyright Benoit Blanchon 2014-2018 | ||||||
|  | # MIT License | ||||||
|  |  | ||||||
|  | add_executable(MsgPackSerializerTests | ||||||
|  | 	destination_types.cpp | ||||||
|  | 	measure.cpp | ||||||
|  | 	serializeArray.cpp | ||||||
|  | 	serializeObject.cpp | ||||||
|  | 	serializeVariant.cpp | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | target_link_libraries(MsgPackSerializerTests catch) | ||||||
|  | add_test(MsgPackSerializer MsgPackSerializerTests) | ||||||
							
								
								
									
										47
									
								
								test/MsgPackSerializer/destination_types.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								test/MsgPackSerializer/destination_types.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <catch.hpp> | ||||||
|  |  | ||||||
|  | TEST_CASE("serialize MsgPack to various destination types") { | ||||||
|  |   DynamicJsonDocument doc; | ||||||
|  |   JsonObject &object = doc.to<JsonObject>(); | ||||||
|  |   object["hello"] = "world"; | ||||||
|  |   const char *expected_result = "\x81\xA5hello\xA5world"; | ||||||
|  |   const size_t expected_length = 13; | ||||||
|  |  | ||||||
|  |   SECTION("std::string") { | ||||||
|  |     std::string result; | ||||||
|  |     size_t len = serializeMsgPack(object, result); | ||||||
|  |  | ||||||
|  |     REQUIRE(expected_result == result); | ||||||
|  |     REQUIRE(expected_length == len); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   /*  SECTION("std::vector<char>") { | ||||||
|  |       std::vector<char> result; | ||||||
|  |       size_t len = serializeMsgPack(object, result); | ||||||
|  |  | ||||||
|  |       REQUIRE(std::vector<char>(expected_result, expected_result + 13) == | ||||||
|  |     result); | ||||||
|  |     REQUIRE(expected_length == len); | ||||||
|  |     } */ | ||||||
|  |  | ||||||
|  |   SECTION("char[]") { | ||||||
|  |     char result[64]; | ||||||
|  |     size_t len = serializeMsgPack(object, result); | ||||||
|  |  | ||||||
|  |     REQUIRE(std::string(expected_result) == result); | ||||||
|  |     REQUIRE(expected_length == len); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("char*") { | ||||||
|  |     char result[64]; | ||||||
|  |     size_t len = serializeMsgPack(object, result, 64); | ||||||
|  |  | ||||||
|  |     REQUIRE(std::string(expected_result) == result); | ||||||
|  |     REQUIRE(expected_length == len); | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										14
									
								
								test/MsgPackSerializer/measure.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								test/MsgPackSerializer/measure.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <catch.hpp> | ||||||
|  |  | ||||||
|  | TEST_CASE("measureMsgPack()") { | ||||||
|  |   DynamicJsonDocument doc; | ||||||
|  |   JsonObject &object = doc.to<JsonObject>(); | ||||||
|  |   object["hello"] = "world"; | ||||||
|  |  | ||||||
|  |   REQUIRE(measureMsgPack(doc) == 13); | ||||||
|  | } | ||||||
							
								
								
									
										60
									
								
								test/MsgPackSerializer/serializeArray.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								test/MsgPackSerializer/serializeArray.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,60 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <catch.hpp> | ||||||
|  |  | ||||||
|  | static void check(const JsonArray& array, const char* expected_data, | ||||||
|  |                   size_t expected_len) { | ||||||
|  |   std::string expected(expected_data, expected_data + expected_len); | ||||||
|  |   std::string actual; | ||||||
|  |   size_t len = serializeMsgPack(array, actual); | ||||||
|  |   CAPTURE(array); | ||||||
|  |   REQUIRE(len == expected_len); | ||||||
|  |   REQUIRE(actual == expected); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <size_t N> | ||||||
|  | static void check(const JsonArray& array, const char (&expected_data)[N]) { | ||||||
|  |   const size_t expected_len = N - 1; | ||||||
|  |   check(array, expected_data, expected_len); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TODO: this function is used by the commented test | ||||||
|  | // static void check(const JsonArray& array, const std::string& expected) { | ||||||
|  | //   check(array, expected.data(), expected.length()); | ||||||
|  | // } | ||||||
|  |  | ||||||
|  | TEST_CASE("serialize MsgPack array") { | ||||||
|  |   DynamicJsonDocument doc; | ||||||
|  |   JsonArray& array = doc.to<JsonArray>(); | ||||||
|  |  | ||||||
|  |   SECTION("empty") { | ||||||
|  |     check(array, "\x90"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("fixarray") { | ||||||
|  |     array.add("hello"); | ||||||
|  |     array.add("world"); | ||||||
|  |  | ||||||
|  |     check(array, "\x92\xA5hello\xA5world"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("array 16") { | ||||||
|  |     for (int i = 0; i < 16; i++) array.add(i); | ||||||
|  |  | ||||||
|  |     check(array, | ||||||
|  |           "\xDC\x00\x10\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D" | ||||||
|  |           "\x0E\x0F"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // TODO: this test is too slow | ||||||
|  |   // SECTION("array 32") { | ||||||
|  |   //   const char* nil = 0; | ||||||
|  |   //   for (int i = 0; i < 65536; i++) array.add(nil); | ||||||
|  |   // | ||||||
|  |   //   check(array, | ||||||
|  |   //         std::string("\xDD\x00\x01\x00\x00", 5) + std::string(65536, 0xC0)); | ||||||
|  |   // } | ||||||
|  | } | ||||||
							
								
								
									
										73
									
								
								test/MsgPackSerializer/serializeObject.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								test/MsgPackSerializer/serializeObject.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,73 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <catch.hpp> | ||||||
|  |  | ||||||
|  | static void check(const JsonObject& object, const char* expected_data, | ||||||
|  |                   size_t expected_len) { | ||||||
|  |   std::string expected(expected_data, expected_data + expected_len); | ||||||
|  |   std::string actual; | ||||||
|  |   size_t len = serializeMsgPack(object, actual); | ||||||
|  |   CAPTURE(object); | ||||||
|  |   REQUIRE(len == expected_len); | ||||||
|  |   REQUIRE(actual == expected); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <size_t N> | ||||||
|  | static void check(const JsonObject& object, const char (&expected_data)[N]) { | ||||||
|  |   const size_t expected_len = N - 1; | ||||||
|  |   check(object, expected_data, expected_len); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // TODO: used by the commented test | ||||||
|  | // static void check(const JsonObject& object, const std::string& expected) { | ||||||
|  | //  check(object, expected.data(), expected.length()); | ||||||
|  | //} | ||||||
|  |  | ||||||
|  | TEST_CASE("serialize MsgPack object") { | ||||||
|  |   DynamicJsonDocument doc; | ||||||
|  |   JsonObject& object = doc.to<JsonObject>(); | ||||||
|  |  | ||||||
|  |   SECTION("empty") { | ||||||
|  |     check(object, "\x80"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("fixmap") { | ||||||
|  |     object["hello"] = "world"; | ||||||
|  |  | ||||||
|  |     check(object, "\x81\xA5hello\xA5world"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("map 16") { | ||||||
|  |     for (int i = 0; i < 16; ++i) { | ||||||
|  |       char key[16]; | ||||||
|  |       sprintf(key, "i%X", i); | ||||||
|  |       object[key] = i; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     check(object, | ||||||
|  |           "\xDE\x00\x10\xA2i0\x00\xA2i1\x01\xA2i2\x02\xA2i3\x03\xA2i4\x04\xA2i5" | ||||||
|  |           "\x05\xA2i6\x06\xA2i7\x07\xA2i8\x08\xA2i9\x09\xA2iA\x0A\xA2iB\x0B\xA2" | ||||||
|  |           "iC\x0C\xA2iD\x0D\xA2iE\x0E\xA2iF\x0F"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // TODO: improve performance and uncomment | ||||||
|  |   // SECTION("map 32") { | ||||||
|  |   //   std::string expected("\xDF\x00\x01\x00\x00", 5); | ||||||
|  |   // | ||||||
|  |   //   for (int i = 0; i < 65536; ++i) { | ||||||
|  |   //     char kv[16]; | ||||||
|  |   //     sprintf(kv, "%04x", i); | ||||||
|  |   //     object[kv] = kv; | ||||||
|  |   //     expected += '\xA4'; | ||||||
|  |   //     expected += kv; | ||||||
|  |   //     expected += '\xA4'; | ||||||
|  |   //     expected += kv; | ||||||
|  |   //   } | ||||||
|  |   // | ||||||
|  |   //   check(object, expected); | ||||||
|  |   // } | ||||||
|  | } | ||||||
							
								
								
									
										129
									
								
								test/MsgPackSerializer/serializeVariant.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								test/MsgPackSerializer/serializeVariant.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2018 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <catch.hpp> | ||||||
|  |  | ||||||
|  | void check(JsonVariant variant, const char* expected_data, | ||||||
|  |            size_t expected_len) { | ||||||
|  |   std::string expected(expected_data, expected_data + expected_len); | ||||||
|  |   std::string actual; | ||||||
|  |   size_t len = serializeMsgPack(variant, actual); | ||||||
|  |   CAPTURE(variant); | ||||||
|  |   REQUIRE(len == expected_len); | ||||||
|  |   REQUIRE(actual == expected); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | template <size_t N> | ||||||
|  | void check(JsonVariant variant, const char (&expected_data)[N]) { | ||||||
|  |   const size_t expected_len = N - 1; | ||||||
|  |   check(variant, expected_data, expected_len); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void check(JsonVariant variant, const std::string& expected) { | ||||||
|  |   check(variant, expected.data(), expected.length()); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST_CASE("serialize MsgPack value") { | ||||||
|  |   SECTION("undefined") { | ||||||
|  |     check(JsonVariant(), "\xC0");  // we represent undefined as nil | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("nil") { | ||||||
|  |     const char* nil = 0;  // ArduinoJson uses a string for null | ||||||
|  |     check(nil, "\xC0"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("bool") { | ||||||
|  |     check(false, "\xC2"); | ||||||
|  |     check(true, "\xC3"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("positive fixint") { | ||||||
|  |     check(0, "\x00"); | ||||||
|  |     check(127, "\x7F"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("uint 8") { | ||||||
|  |     check(128, "\xCC\x80"); | ||||||
|  |     check(255, "\xCC\xFF"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("uint 16") { | ||||||
|  |     check(256, "\xCD\x01\x00"); | ||||||
|  |     check(0xFFFF, "\xCD\xFF\xFF"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("uint 32") { | ||||||
|  |     check(0x00010000U, "\xCE\x00\x01\x00\x00"); | ||||||
|  |     check(0x12345678U, "\xCE\x12\x34\x56\x78"); | ||||||
|  |     check(0xFFFFFFFFU, "\xCE\xFF\xFF\xFF\xFF"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 | ||||||
|  |   SECTION("uint 64") { | ||||||
|  |     check(0x0001000000000000U, "\xCF\x00\x01\x00\x00\x00\x00\x00\x00"); | ||||||
|  |     check(0x123456789ABCDEF0U, "\xCF\x12\x34\x56\x78\x9A\xBC\xDE\xF0"); | ||||||
|  |     check(0xFFFFFFFFFFFFFFFFU, "\xCF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"); | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   SECTION("negative fixint") { | ||||||
|  |     check(-1, "\xFF"); | ||||||
|  |     check(-32, "\xE0"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("int 8") { | ||||||
|  |     check(-33, "\xD0\xDF"); | ||||||
|  |     check(-128, "\xD0\x80"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("int 16") { | ||||||
|  |     check(-129, "\xD1\xFF\x7F"); | ||||||
|  |     check(-32768, "\xD1\x80\x00"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("int 32") { | ||||||
|  |     check(-32769, "\xD2\xFF\xFF\x7F\xFF"); | ||||||
|  |     check(-2147483647 - 1, "\xD2\x80\x00\x00\x00"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_USE_LONG_LONG || ARDUINOJSON_USE_INT64 | ||||||
|  |   SECTION("int 64") { | ||||||
|  |     check(int64_t(0xFEDCBA9876543210), "\xD3\xFE\xDC\xBA\x98\x76\x54\x32\x10"); | ||||||
|  |   } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |   SECTION("float 32") { | ||||||
|  |     check(1.25, "\xCA\x3F\xA0\x00\x00"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("float 64") { | ||||||
|  |     check(3.1415, "\xCB\x40\x09\x21\xCA\xC0\x83\x12\x6F"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("fixstr") { | ||||||
|  |     check("", "\xA0"); | ||||||
|  |     check("hello world hello world hello !", | ||||||
|  |           "\xBFhello world hello world hello !"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("str 8") { | ||||||
|  |     check("hello world hello world hello !!", | ||||||
|  |           "\xD9\x20hello world hello world hello !!"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("str 16") { | ||||||
|  |     std::string shortest(256, '?'); | ||||||
|  |     check(shortest.c_str(), std::string("\xDA\x01\x00", 3) + shortest); | ||||||
|  |  | ||||||
|  |     std::string longest(65535, '?'); | ||||||
|  |     check(longest.c_str(), std::string("\xDA\xFF\xFF", 3) + longest); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   SECTION("str 32") { | ||||||
|  |     std::string shortest(65536, '?'); | ||||||
|  |     check(shortest.c_str(), std::string("\xDB\x00\x01\x00\x00", 5) + shortest); | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user