mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added support for custom reader classes
This commit is contained in:
		| @@ -4,7 +4,7 @@ ArduinoJson: change log | ||||
| HEAD | ||||
| ---- | ||||
|  | ||||
| * Added support for custom writer classes (issue #1088) | ||||
| * Added support for custom writer/reader classes (issue #1088) | ||||
| * Added conversion from `JsonArray` and `JsonObject` to `bool`, to be consistent with `JsonVariant` | ||||
| * Fixed `deserializeJson()` when input contains duplicate keys (issue #1095) | ||||
| * Improved `deserializeMsgPack()` speed by reading several bytes at once | ||||
|   | ||||
| @@ -72,6 +72,7 @@ if(MSVC) | ||||
| 	) | ||||
| endif() | ||||
|  | ||||
| include_directories(Helpers) | ||||
| add_subdirectory(ElementProxy) | ||||
| add_subdirectory(IntegrationTests) | ||||
| add_subdirectory(JsonArray) | ||||
|   | ||||
							
								
								
									
										26
									
								
								extras/tests/Helpers/CustomReader.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								extras/tests/Helpers/CustomReader.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <sstream> | ||||
|  | ||||
| class CustomReader { | ||||
|   std::stringstream _stream; | ||||
|  | ||||
|  public: | ||||
|   CustomReader(const char* input) : _stream(input) {} | ||||
|  | ||||
|   int read() { | ||||
|     return _stream.get(); | ||||
|   } | ||||
|  | ||||
|   size_t readBytes(char* buffer, size_t length) { | ||||
|     _stream.read(buffer, static_cast<std::streamsize>(length)); | ||||
|     return static_cast<size_t>(_stream.gcount()); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   CustomReader(const CustomReader&); | ||||
| }; | ||||
| @@ -6,6 +6,8 @@ | ||||
| #include <catch.hpp> | ||||
| #include <sstream> | ||||
|  | ||||
| #include "CustomReader.hpp" | ||||
|  | ||||
| TEST_CASE("deserializeJson(const std::string&)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
| @@ -113,3 +115,14 @@ TEST_CASE("deserializeJson(VLA)") { | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| TEST_CASE("deserializeJson(CustomReader)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   CustomReader reader("[4,2]"); | ||||
|   DeserializationError err = deserializeJson(doc, reader); | ||||
|  | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
|   REQUIRE(doc.size() == 2); | ||||
|   REQUIRE(doc[0] == 4); | ||||
|   REQUIRE(doc[1] == 2); | ||||
| } | ||||
|   | ||||
| @@ -2,15 +2,15 @@ | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <ArduinoJson/Deserialization/Reader.hpp> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
| TEST_CASE("StdStreamReader") { | ||||
| TEST_CASE("Reader<std::istringstream>") { | ||||
|   SECTION("read()") { | ||||
|     std::istringstream src("\x01\xFF"); | ||||
|     StdStreamReader reader(src); | ||||
|     Reader<std::istringstream> reader(src); | ||||
|  | ||||
|     REQUIRE(reader.read() == 0x01); | ||||
|     REQUIRE(reader.read() == 0xFF); | ||||
| @@ -19,7 +19,7 @@ TEST_CASE("StdStreamReader") { | ||||
|  | ||||
|   SECTION("readBytes() all at once") { | ||||
|     std::istringstream src("ABC"); | ||||
|     StdStreamReader reader(src); | ||||
|     Reader<std::istringstream> reader(src); | ||||
|  | ||||
|     char buffer[8] = "abcd"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 3); | ||||
| @@ -32,7 +32,7 @@ TEST_CASE("StdStreamReader") { | ||||
|  | ||||
|   SECTION("readBytes() in two parts") { | ||||
|     std::istringstream src("ABCDEF"); | ||||
|     StdStreamReader reader(src); | ||||
|     Reader<std::istringstream> reader(src); | ||||
|  | ||||
|     char buffer[12] = "abcdefg"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 4); | ||||
| @@ -48,9 +48,9 @@ TEST_CASE("StdStreamReader") { | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("SafeCharPointerReader") { | ||||
| TEST_CASE("BoundedReader<const char*>") { | ||||
|   SECTION("read") { | ||||
|     SafeCharPointerReader reader("\x01\xFF", 2); | ||||
|     BoundedReader<const char*> reader("\x01\xFF", 2); | ||||
|     REQUIRE(reader.read() == 0x01); | ||||
|     REQUIRE(reader.read() == 0xFF); | ||||
|     REQUIRE(reader.read() == -1); | ||||
| @@ -58,7 +58,7 @@ TEST_CASE("SafeCharPointerReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() all at once") { | ||||
|     SafeCharPointerReader reader("ABCD", 3); | ||||
|     BoundedReader<const char*> reader("ABCD", 3); | ||||
|  | ||||
|     char buffer[8] = "abcd"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 3); | ||||
| @@ -70,7 +70,7 @@ TEST_CASE("SafeCharPointerReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() in two parts") { | ||||
|     SafeCharPointerReader reader("ABCDEF", 6); | ||||
|     BoundedReader<const char*> reader("ABCDEF", 6); | ||||
|  | ||||
|     char buffer[8] = "abcdefg"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 4); | ||||
| @@ -86,9 +86,9 @@ TEST_CASE("SafeCharPointerReader") { | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("UnsafeCharPointerReader") { | ||||
| TEST_CASE("Reader<const char*>") { | ||||
|   SECTION("read()") { | ||||
|     UnsafeCharPointerReader reader("\x01\xFF\x00\x12"); | ||||
|     Reader<const char*> reader("\x01\xFF\x00\x12"); | ||||
|     REQUIRE(reader.read() == 0x01); | ||||
|     REQUIRE(reader.read() == 0xFF); | ||||
|     REQUIRE(reader.read() == 0); | ||||
| @@ -96,7 +96,7 @@ TEST_CASE("UnsafeCharPointerReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() all at once") { | ||||
|     UnsafeCharPointerReader reader("ABCD"); | ||||
|     Reader<const char*> reader("ABCD"); | ||||
|  | ||||
|     char buffer[8] = "abcd"; | ||||
|     REQUIRE(reader.readBytes(buffer, 3) == 3); | ||||
| @@ -108,7 +108,7 @@ TEST_CASE("UnsafeCharPointerReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() in two parts") { | ||||
|     UnsafeCharPointerReader reader("ABCDEF"); | ||||
|     Reader<const char*> reader("ABCDEF"); | ||||
|  | ||||
|     char buffer[8] = "abcdefg"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 4); | ||||
|   | ||||
| @@ -86,11 +86,11 @@ TEST_CASE("memcpy_P") { | ||||
|   CHECK(dst[3] == 0); | ||||
| } | ||||
|  | ||||
| TEST_CASE("SafeCharPointerReader") { | ||||
|   using ARDUINOJSON_NAMESPACE::SafeFlashStringReader; | ||||
| TEST_CASE("BoundedReader<const __FlashStringHelper*>") { | ||||
|   using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
|   SECTION("read") { | ||||
|     SafeFlashStringReader reader(F("\x01\xFF"), 2); | ||||
|     BoundedReader<const __FlashStringHelper*> reader(F("\x01\xFF"), 2); | ||||
|     REQUIRE(reader.read() == 0x01); | ||||
|     REQUIRE(reader.read() == 0xFF); | ||||
|     REQUIRE(reader.read() == -1); | ||||
| @@ -98,7 +98,7 @@ TEST_CASE("SafeCharPointerReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() all at once") { | ||||
|     SafeFlashStringReader reader(F("ABCD"), 3); | ||||
|     BoundedReader<const __FlashStringHelper*> reader(F("ABCD"), 3); | ||||
|  | ||||
|     char buffer[8] = "abcd"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 3); | ||||
| @@ -110,7 +110,7 @@ TEST_CASE("SafeCharPointerReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() in two parts") { | ||||
|     SafeFlashStringReader reader(F("ABCDEF"), 6); | ||||
|     BoundedReader<const __FlashStringHelper*> reader(F("ABCDEF"), 6); | ||||
|  | ||||
|     char buffer[8] = "abcdefg"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 4); | ||||
| @@ -126,11 +126,11 @@ TEST_CASE("SafeCharPointerReader") { | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("UnsafeFlashStringReader") { | ||||
|   using ARDUINOJSON_NAMESPACE::UnsafeFlashStringReader; | ||||
| TEST_CASE("Reader<const __FlashStringHelper*>") { | ||||
|   using namespace ARDUINOJSON_NAMESPACE; | ||||
|  | ||||
|   SECTION("read()") { | ||||
|     UnsafeFlashStringReader reader(F("\x01\xFF\x00\x12")); | ||||
|     Reader<const __FlashStringHelper*> reader(F("\x01\xFF\x00\x12")); | ||||
|     REQUIRE(reader.read() == 0x01); | ||||
|     REQUIRE(reader.read() == 0xFF); | ||||
|     REQUIRE(reader.read() == 0); | ||||
| @@ -138,7 +138,7 @@ TEST_CASE("UnsafeFlashStringReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() all at once") { | ||||
|     UnsafeFlashStringReader reader(F("ABCD")); | ||||
|     Reader<const __FlashStringHelper*> reader(F("ABCD")); | ||||
|  | ||||
|     char buffer[8] = "abcd"; | ||||
|     REQUIRE(reader.readBytes(buffer, 3) == 3); | ||||
| @@ -150,7 +150,7 @@ TEST_CASE("UnsafeFlashStringReader") { | ||||
|   } | ||||
|  | ||||
|   SECTION("readBytes() in two parts") { | ||||
|     UnsafeFlashStringReader reader(F("ABCDEF")); | ||||
|     Reader<const __FlashStringHelper*> reader(F("ABCDEF")); | ||||
|  | ||||
|     char buffer[8] = "abcdefg"; | ||||
|     REQUIRE(reader.readBytes(buffer, 4) == 4); | ||||
|   | ||||
| @@ -5,6 +5,8 @@ | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| #include "CustomReader.hpp" | ||||
|  | ||||
| TEST_CASE("deserializeMsgPack(const std::string&)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|  | ||||
| @@ -80,3 +82,14 @@ TEST_CASE("deserializeMsgPack(VLA)") { | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| TEST_CASE("deserializeMsgPack(CustomReader)") { | ||||
|   DynamicJsonDocument doc(4096); | ||||
|   CustomReader reader("\x92\xA5Hello\xA5world"); | ||||
|   DeserializationError err = deserializeMsgPack(doc, reader); | ||||
|  | ||||
|   REQUIRE(err == DeserializationError::Ok); | ||||
|   REQUIRE(doc.size() == 2); | ||||
|   REQUIRE(doc[0] == "Hello"); | ||||
|   REQUIRE(doc[1] == "world"); | ||||
| } | ||||
|   | ||||
| @@ -1,65 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Deserialization/IteratorReader.hpp> | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename T> | ||||
| struct IsCharOrVoid { | ||||
|   static const bool value = | ||||
|       is_same<T, void>::value || is_same<T, char>::value || | ||||
|       is_same<T, unsigned char>::value || is_same<T, signed char>::value; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| struct IsCharOrVoid<const T> : IsCharOrVoid<T> {}; | ||||
|  | ||||
| class UnsafeCharPointerReader { | ||||
|   const char* _ptr; | ||||
|  | ||||
|  public: | ||||
|   explicit UnsafeCharPointerReader(const char* ptr) | ||||
|       : _ptr(ptr ? ptr : reinterpret_cast<const char*>("")) {} | ||||
|  | ||||
|   int read() { | ||||
|     return static_cast<unsigned char>(*_ptr++); | ||||
|   } | ||||
|  | ||||
|   size_t readBytes(char* buffer, size_t length) { | ||||
|     for (size_t i = 0; i < length; i++) buffer[i] = *_ptr++; | ||||
|     return length; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| class SafeCharPointerReader : public IteratorReader<const char*> { | ||||
|  public: | ||||
|   explicit SafeCharPointerReader(const char* ptr, size_t len) | ||||
|       : IteratorReader<const char*>(ptr, ptr + len) {} | ||||
| }; | ||||
|  | ||||
| template <typename TChar> | ||||
| inline typename enable_if<IsCharOrVoid<TChar>::value, | ||||
|                           UnsafeCharPointerReader>::type | ||||
| makeReader(TChar* input) { | ||||
|   return UnsafeCharPointerReader(reinterpret_cast<const char*>(input)); | ||||
| } | ||||
|  | ||||
| template <typename TChar> | ||||
| inline | ||||
|     typename enable_if<IsCharOrVoid<TChar>::value, SafeCharPointerReader>::type | ||||
|     makeReader(TChar* input, size_t n) { | ||||
|   return SafeCharPointerReader(reinterpret_cast<const char*>(input), n); | ||||
| } | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STRING | ||||
| inline SafeCharPointerReader makeReader(const ::String& input) { | ||||
|   return SafeCharPointerReader(input.c_str(), input.length()); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
							
								
								
									
										55
									
								
								src/ArduinoJson/Deserialization/Reader.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/ArduinoJson/Deserialization/Reader.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
|  | ||||
| #include <stdlib.h>  // for size_t | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| // The default reader is a simple wrapper for Readers that are not copiable | ||||
| template <typename TSource, typename Enable = void> | ||||
| struct Reader { | ||||
|  public: | ||||
|   Reader(TSource& source) : _source(&source) {} | ||||
|  | ||||
|   int read() { | ||||
|     return _source->read(); | ||||
|   } | ||||
|  | ||||
|   size_t readBytes(char* buffer, size_t length) { | ||||
|     return _source->readBytes(buffer, length); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   TSource* _source; | ||||
| }; | ||||
|  | ||||
| template <typename TSource, typename Enable = void> | ||||
| struct BoundedReader { | ||||
|   // no default implementation because we need to pass the size to the | ||||
|   // constructor | ||||
| }; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|  | ||||
| #include <ArduinoJson/Deserialization/Readers/IteratorReader.hpp> | ||||
| #include <ArduinoJson/Deserialization/Readers/RamReader.hpp> | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STREAM | ||||
| #include <ArduinoJson/Deserialization/Readers/ArduinoStreamReader.hpp> | ||||
| #endif | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STRING | ||||
| #include <ArduinoJson/Deserialization/Readers/ArduinoStringReader.hpp> | ||||
| #endif | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_PROGMEM | ||||
| #include <ArduinoJson/Deserialization/Readers/FlashReader.hpp> | ||||
| #endif | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_STD_STREAM | ||||
| #include <ArduinoJson/Deserialization/Readers/StdStreamReader.hpp> | ||||
| #endif | ||||
| @@ -4,19 +4,17 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
| 
 | ||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STREAM | ||||
| 
 | ||||
| #include <Stream.h> | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| struct ArduinoStreamReader { | ||||
| template <typename TSource> | ||||
| struct Reader<TSource, | ||||
|               typename enable_if<is_base_of<Stream, TSource>::value>::type> { | ||||
|   Stream& _stream; | ||||
| 
 | ||||
|  public: | ||||
|   explicit ArduinoStreamReader(Stream& stream) : _stream(stream) {} | ||||
|   explicit Reader(Stream& stream) : _stream(stream) {} | ||||
| 
 | ||||
|   int read() { | ||||
|     // don't use _stream.read() as it ignores the timeout
 | ||||
| @@ -29,9 +27,4 @@ struct ArduinoStreamReader { | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| inline ArduinoStreamReader makeReader(Stream& input) { | ||||
|   return ArduinoStreamReader(input); | ||||
| } | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| 
 | ||||
| #endif | ||||
| @@ -0,0 +1,17 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TSource> | ||||
| struct Reader<TSource, | ||||
|               typename enable_if<is_base_of< ::String, TSource>::value>::type> | ||||
|     : BoundedReader<const char*> { | ||||
|   explicit Reader(const ::String& s) | ||||
|       : BoundedReader<const char*>(s.c_str(), s.length()) {} | ||||
| }; | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
| @@ -4,16 +4,14 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
| 
 | ||||
| #if ARDUINOJSON_ENABLE_PROGMEM | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| class UnsafeFlashStringReader { | ||||
| 
 | ||||
| template <> | ||||
| struct Reader<const __FlashStringHelper*, void> { | ||||
|   const char* _ptr; | ||||
| 
 | ||||
|  public: | ||||
|   explicit UnsafeFlashStringReader(const __FlashStringHelper* ptr) | ||||
|   explicit Reader(const __FlashStringHelper* ptr) | ||||
|       : _ptr(reinterpret_cast<const char*>(ptr)) {} | ||||
| 
 | ||||
|   int read() { | ||||
| @@ -27,12 +25,13 @@ class UnsafeFlashStringReader { | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| class SafeFlashStringReader { | ||||
| template <> | ||||
| struct BoundedReader<const __FlashStringHelper*, void> { | ||||
|   const char* _ptr; | ||||
|   const char* _end; | ||||
| 
 | ||||
|  public: | ||||
|   explicit SafeFlashStringReader(const __FlashStringHelper* ptr, size_t size) | ||||
|   explicit BoundedReader(const __FlashStringHelper* ptr, size_t size) | ||||
|       : _ptr(reinterpret_cast<const char*>(ptr)), _end(_ptr + size) {} | ||||
| 
 | ||||
|   int read() { | ||||
| @@ -50,15 +49,4 @@ class SafeFlashStringReader { | ||||
|     return length; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| inline UnsafeFlashStringReader makeReader(const __FlashStringHelper* input) { | ||||
|   return UnsafeFlashStringReader(input); | ||||
| } | ||||
| 
 | ||||
| inline SafeFlashStringReader makeReader(const __FlashStringHelper* input, | ||||
|                                         size_t size) { | ||||
|   return SafeFlashStringReader(input, size); | ||||
| } | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| 
 | ||||
| #endif | ||||
| @@ -4,8 +4,6 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| template <typename TIterator> | ||||
| @@ -30,10 +28,16 @@ class IteratorReader { | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| template <typename TInput> | ||||
| inline IteratorReader<typename TInput::const_iterator> makeReader( | ||||
|     const TInput& input) { | ||||
|   return IteratorReader<typename TInput::const_iterator>(input.begin(), | ||||
|                                                          input.end()); | ||||
| } | ||||
| template <typename T> | ||||
| struct void_ { | ||||
|   typedef void type; | ||||
| }; | ||||
| 
 | ||||
| template <typename TSource> | ||||
| struct Reader<TSource, typename void_<typename TSource::const_iterator>::type> | ||||
|     : IteratorReader<typename TSource::const_iterator> { | ||||
|   explicit Reader(const TSource& source) | ||||
|       : IteratorReader<typename TSource::const_iterator>(source.begin(), | ||||
|                                                          source.end()) {} | ||||
| }; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
							
								
								
									
										50
									
								
								src/ArduinoJson/Deserialization/Readers/RamReader.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/ArduinoJson/Deserialization/Readers/RamReader.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Polyfills/type_traits.hpp> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename T> | ||||
| struct IsCharOrVoid { | ||||
|   static const bool value = | ||||
|       is_same<T, void>::value || is_same<T, char>::value || | ||||
|       is_same<T, unsigned char>::value || is_same<T, signed char>::value; | ||||
| }; | ||||
|  | ||||
| template <typename T> | ||||
| struct IsCharOrVoid<const T> : IsCharOrVoid<T> {}; | ||||
|  | ||||
| template <typename TSource> | ||||
| struct Reader<TSource*, | ||||
|               typename enable_if<IsCharOrVoid<TSource>::value>::type> { | ||||
|   const char* _ptr; | ||||
|  | ||||
|  public: | ||||
|   explicit Reader(const void* ptr) | ||||
|       : _ptr(ptr ? reinterpret_cast<const char*>(ptr) : "") {} | ||||
|  | ||||
|   int read() { | ||||
|     return static_cast<unsigned char>(*_ptr++); | ||||
|   } | ||||
|  | ||||
|   size_t readBytes(char* buffer, size_t length) { | ||||
|     for (size_t i = 0; i < length; i++) buffer[i] = *_ptr++; | ||||
|     return length; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TSource> | ||||
| struct BoundedReader<TSource*, | ||||
|                      typename enable_if<IsCharOrVoid<TSource>::value>::type> | ||||
|     : public IteratorReader<const char*> { | ||||
|  public: | ||||
|   explicit BoundedReader(const void* ptr, size_t len) | ||||
|       : IteratorReader<const char*>(reinterpret_cast<const char*>(ptr), | ||||
|                                     reinterpret_cast<const char*>(ptr) + len) {} | ||||
| }; | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
							
								
								
									
										29
									
								
								src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/ArduinoJson/Deserialization/Readers/StdStreamReader.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <istream> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TSource> | ||||
| struct Reader<TSource, typename enable_if< | ||||
|                            is_base_of<std::istream, TSource>::value>::type> { | ||||
|  public: | ||||
|   explicit Reader(std::istream& stream) : _stream(&stream) {} | ||||
|  | ||||
|   int read() { | ||||
|     return _stream->get(); | ||||
|   } | ||||
|  | ||||
|   size_t readBytes(char* buffer, size_t length) { | ||||
|     _stream->read(buffer, static_cast<std::streamsize>(length)); | ||||
|     return static_cast<size_t>(_stream->gcount()); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   std::istream* _stream; | ||||
| }; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
| @@ -1,41 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2019 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Namespace.hpp> | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_STD_STREAM | ||||
|  | ||||
| #include <istream> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| class StdStreamReader { | ||||
|   std::istream& _stream; | ||||
|   char _current; | ||||
|  | ||||
|  public: | ||||
|   explicit StdStreamReader(std::istream& stream) | ||||
|       : _stream(stream), _current(0) {} | ||||
|  | ||||
|   int read() { | ||||
|     return _stream.get(); | ||||
|   } | ||||
|  | ||||
|   size_t readBytes(char* buffer, size_t length) { | ||||
|     _stream.read(buffer, static_cast<std::streamsize>(length)); | ||||
|     return static_cast<size_t>(_stream.gcount()); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   StdStreamReader& operator=(const StdStreamReader&);  // Visual Studio C4512 | ||||
| }; | ||||
|  | ||||
| inline StdStreamReader makeReader(std::istream& input) { | ||||
|   return StdStreamReader(input); | ||||
| } | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|  | ||||
| #endif | ||||
| @@ -4,13 +4,9 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <ArduinoJson/Deserialization/ArduinoStreamReader.hpp> | ||||
| #include <ArduinoJson/Deserialization/CharPointerReader.hpp> | ||||
| #include <ArduinoJson/Deserialization/DeserializationError.hpp> | ||||
| #include <ArduinoJson/Deserialization/FlashStringReader.hpp> | ||||
| #include <ArduinoJson/Deserialization/IteratorReader.hpp> | ||||
| #include <ArduinoJson/Deserialization/NestingLimit.hpp> | ||||
| #include <ArduinoJson/Deserialization/StdStreamReader.hpp> | ||||
| #include <ArduinoJson/Deserialization/Reader.hpp> | ||||
| #include <ArduinoJson/StringStorage/StringStorage.hpp> | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| @@ -25,26 +21,17 @@ TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool &pool, | ||||
|  | ||||
| // deserialize(JsonDocument&, const std::string&); | ||||
| // deserialize(JsonDocument&, const String&); | ||||
| // deserialize(JsonDocument&, char*); | ||||
| // deserialize(JsonDocument&, const char*); | ||||
| // deserialize(JsonDocument&, const __FlashStringHelper*); | ||||
| template <template <typename, typename> class TDeserializer, typename TString> | ||||
| typename enable_if<!is_array<TString>::value, DeserializationError>::type | ||||
| deserialize(JsonDocument &doc, const TString &input, | ||||
|             NestingLimit nestingLimit) { | ||||
|   Reader<TString> reader(input); | ||||
|   doc.clear(); | ||||
|   return makeDeserializer<TDeserializer>( | ||||
|              doc.memoryPool(), makeReader(input), | ||||
|              makeStringStorage(doc.memoryPool(), input), nestingLimit.value) | ||||
|       .parse(doc.data()); | ||||
| } | ||||
| // | ||||
| // deserialize(JsonDocument&, char*); | ||||
| // deserialize(JsonDocument&, const char*); | ||||
| // deserialize(JsonDocument&, const __FlashStringHelper*); | ||||
| template <template <typename, typename> class TDeserializer, typename TChar> | ||||
| DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
|                                  NestingLimit nestingLimit) { | ||||
|   doc.clear(); | ||||
|   return makeDeserializer<TDeserializer>( | ||||
|              doc.memoryPool(), makeReader(input), | ||||
|              doc.memoryPool(), reader, | ||||
|              makeStringStorage(doc.memoryPool(), input), nestingLimit.value) | ||||
|       .parse(doc.data()); | ||||
| } | ||||
| @@ -55,9 +42,10 @@ DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
| template <template <typename, typename> class TDeserializer, typename TChar> | ||||
| DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
|                                  size_t inputSize, NestingLimit nestingLimit) { | ||||
|   BoundedReader<TChar *> reader(input, inputSize); | ||||
|   doc.clear(); | ||||
|   return makeDeserializer<TDeserializer>( | ||||
|              doc.memoryPool(), makeReader(input, inputSize), | ||||
|              doc.memoryPool(), reader, | ||||
|              makeStringStorage(doc.memoryPool(), input), nestingLimit.value) | ||||
|       .parse(doc.data()); | ||||
| } | ||||
| @@ -67,9 +55,10 @@ DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
| template <template <typename, typename> class TDeserializer, typename TStream> | ||||
| DeserializationError deserialize(JsonDocument &doc, TStream &input, | ||||
|                                  NestingLimit nestingLimit) { | ||||
|   Reader<TStream> reader(input); | ||||
|   doc.clear(); | ||||
|   return makeDeserializer<TDeserializer>( | ||||
|              doc.memoryPool(), makeReader(input), | ||||
|              doc.memoryPool(), reader, | ||||
|              makeStringStorage(doc.memoryPool(), input), nestingLimit.value) | ||||
|       .parse(doc.data()); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user