mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	Prototype working on GCC and Clang
This commit is contained in:
		| @@ -10,6 +10,7 @@ add_executable(JsonDeserializerTests | |||||||
| 	incomplete_input.cpp | 	incomplete_input.cpp | ||||||
| 	input_types.cpp | 	input_types.cpp | ||||||
| 	invalid_input.cpp | 	invalid_input.cpp | ||||||
|  | 	JsonDeserializer.cpp | ||||||
| 	misc.cpp | 	misc.cpp | ||||||
| 	nestingLimit.cpp | 	nestingLimit.cpp | ||||||
| 	number.cpp | 	number.cpp | ||||||
|   | |||||||
							
								
								
									
										126
									
								
								extras/tests/JsonDeserializer/JsonDeserializer.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								extras/tests/JsonDeserializer/JsonDeserializer.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,126 @@ | |||||||
|  | // ArduinoJson - arduinojson.org | ||||||
|  | // Copyright Benoit Blanchon 2014-2020 | ||||||
|  | // MIT License | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <malloc.h> | ||||||
|  | #include <setjmp.h> | ||||||
|  | #include <catch.hpp> | ||||||
|  |  | ||||||
|  | #ifdef _MSC_VER | ||||||
|  | #pragma warning(push) | ||||||
|  | #pragma warning(disable : 4611)  // interaction between '_setjmp' and C++ object | ||||||
|  |                                  // destruction is non-portable | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | size_t STACK = 1000; | ||||||
|  |  | ||||||
|  | class IncrementalDeserializer { | ||||||
|  |   struct Reader { | ||||||
|  |     IncrementalDeserializer* _parent; | ||||||
|  |  | ||||||
|  |    public: | ||||||
|  |     Reader(IncrementalDeserializer* parent) : _parent(parent) {} | ||||||
|  |  | ||||||
|  |     Reader(Reader& other) : _parent(other._parent) {} | ||||||
|  |  | ||||||
|  |     int read() { | ||||||
|  |       // std::cout << "read()" << std::endl; | ||||||
|  |       if (_parent->_size == 0) | ||||||
|  |         pause(); | ||||||
|  |       // std::cout << "avail = " << _parent->_size << std::endl; | ||||||
|  |       // std::cout << "avail = " << _parent->_data << std::endl; | ||||||
|  |       int result = _parent->_data[0]; | ||||||
|  |       consume(1); | ||||||
|  |       // std::cout << "read() -> " << result << std::endl; | ||||||
|  |       return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     size_t readBytes(char* buffer, size_t length) { | ||||||
|  |       // std::cout << "readBytes()" << std::endl; | ||||||
|  |       if (_parent->_size == 0) | ||||||
|  |         pause(); | ||||||
|  |       if (length > _parent->_size) | ||||||
|  |         length = _parent->_size; | ||||||
|  |       memcpy(buffer, _parent->_data, length); | ||||||
|  |       consume(length); | ||||||
|  |       return length; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |    private: | ||||||
|  |     void pause() { | ||||||
|  |       // std::cout << "pause" << std::endl; | ||||||
|  |       if (setjmp(_parent->_back_to_reader) == 0) { | ||||||
|  |         // std::cout << "paused" << std::endl; | ||||||
|  |         longjmp(_parent->_back_to_program, 1); | ||||||
|  |       } | ||||||
|  |       // std::cout << "resumed" << std::endl; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     void consume(size_t n) { | ||||||
|  |       _parent->_data += n; | ||||||
|  |       _parent->_size -= n; | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   jmp_buf _back_to_program; | ||||||
|  |   jmp_buf _back_to_reader; | ||||||
|  |   JsonDocument* _doc; | ||||||
|  |   const char* _data; | ||||||
|  |   size_t _size; | ||||||
|  |   DeserializationError _result; | ||||||
|  |  | ||||||
|  |  public: | ||||||
|  |   IncrementalDeserializer(JsonDocument& doc) : _doc(&doc) {} | ||||||
|  |  | ||||||
|  |   void start() { | ||||||
|  |     // std::cout << "start()" << std::endl; | ||||||
|  |     _data = 0; | ||||||
|  |     _size = 0; | ||||||
|  |     _result = DeserializationError::IncompleteInput; | ||||||
|  |     if (setjmp(_back_to_program) == 0) { | ||||||
|  |       char space[STACK];     // Reserve enough space for main to run | ||||||
|  |       space[STACK - 1] = 1;  // Do not optimize array out of existence | ||||||
|  |       (void)space; | ||||||
|  |       Reader reader(this); | ||||||
|  |       _result = deserializeJson(*_doc, reader); | ||||||
|  |       longjmp(_back_to_program, 2); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   bool feed(const char* data, size_t size) { | ||||||
|  |     // std::cout << "feed()" << std::endl; | ||||||
|  |     _data = data; | ||||||
|  |     _size = size; | ||||||
|  |     switch (setjmp(_back_to_program)) { | ||||||
|  |       case 0: | ||||||
|  |         longjmp(_back_to_reader, 1); | ||||||
|  |       case 1: | ||||||
|  |         // std::cout << "feed() -> false" << std::endl; | ||||||
|  |         return false;  // need more data | ||||||
|  |       default: | ||||||
|  |         // std::cout << "feed() -> true" << std::endl; | ||||||
|  |         return true;  // done | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   DeserializationError result() const { | ||||||
|  |     return _result; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #ifdef _MSC_VER | ||||||
|  | #pragma warning(pop) | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | TEST_CASE("prout") { | ||||||
|  |   StaticJsonDocument<1024> doc; | ||||||
|  |   IncrementalDeserializer deserializer(doc); | ||||||
|  |  | ||||||
|  |   SECTION("basics") { | ||||||
|  |     deserializer.start(); | ||||||
|  |     REQUIRE(deserializer.feed("{\"answ", 6) == false); | ||||||
|  |     REQUIRE(deserializer.feed("er\":42}", 7) == true); | ||||||
|  |     REQUIRE(doc["answer"] == 42); | ||||||
|  |   } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user