mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Added support for Stream (issue #300)
				
					
				
			This commit is contained in:
		| @@ -5,6 +5,7 @@ HEAD | |||||||
| ---- | ---- | ||||||
|  |  | ||||||
| * Added operator `==` to compare `JsonVariant` and strings (issue #402) | * Added operator `==` to compare `JsonVariant` and strings (issue #402) | ||||||
|  | * Added support for `Stream` (issue #300) | ||||||
| * Reduced memory consumption by not duplicating spaces and comments | * Reduced memory consumption by not duplicating spaces and comments | ||||||
|  |  | ||||||
| v5.7.3 | v5.7.3 | ||||||
|   | |||||||
| @@ -5,9 +5,10 @@ Arduino JSON library | |||||||
|  |  | ||||||
| *An elegant and efficient JSON library for embedded systems.* | *An elegant and efficient JSON library for embedded systems.* | ||||||
|  |  | ||||||
| It's designed to have the most intuitive API, the smallest footprint and works without any allocation on the heap (no malloc). | It's designed to have the most intuitive API, the smallest footprint and is able to work without any allocation on the heap (no malloc). | ||||||
|  |  | ||||||
| It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project. | It has been written with Arduino in mind, but it isn't linked to Arduino libraries so you can use this library in any other C++ project. | ||||||
|  | For instance, it supports Aduino's `String` and `Stream`, but also `std::string`, `std::istream` and `std::ostream`. | ||||||
|  |  | ||||||
| Features | Features | ||||||
| -------- | -------- | ||||||
| @@ -55,6 +56,8 @@ double latitude    = root["data"][0]; | |||||||
| double longitude   = root["data"][1]; | double longitude   = root["data"][1]; | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | [See JsonParserExample.ino](examples/JsonParserExample/JsonParserExample.ino) | ||||||
|  |  | ||||||
| #### Encoding / Generating | #### Encoding / Generating | ||||||
|  |  | ||||||
| ```c++ | ```c++ | ||||||
| @@ -73,6 +76,8 @@ root.printTo(Serial); | |||||||
| // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | // {"sensor":"gps","time":1351824120,"data":[48.756080,2.302038]} | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | [See JsonGeneratorExample.ino](examples/JsonGeneratorExample/JsonGeneratorExample.ino) | ||||||
|  |  | ||||||
|  |  | ||||||
| Documentation | Documentation | ||||||
| ------------- | ------------- | ||||||
|   | |||||||
| @@ -9,8 +9,8 @@ | |||||||
| // If you like this project, please add a star! | // If you like this project, please add a star! | ||||||
|  |  | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
| #include <SPI.h> |  | ||||||
| #include <Ethernet.h> | #include <Ethernet.h> | ||||||
|  | #include <SPI.h> | ||||||
|  |  | ||||||
| EthernetClient client; | EthernetClient client; | ||||||
|  |  | ||||||
| @@ -36,11 +36,8 @@ void setup() { | |||||||
| void loop() { | void loop() { | ||||||
|   if (connect(server)) { |   if (connect(server)) { | ||||||
|     if (sendRequest(server, resource) && skipResponseHeaders()) { |     if (sendRequest(server, resource) && skipResponseHeaders()) { | ||||||
|       char response[MAX_CONTENT_SIZE]; |  | ||||||
|       readReponseContent(response, sizeof(response)); |  | ||||||
|  |  | ||||||
|       UserData userData; |       UserData userData; | ||||||
|       if (parseUserData(response, &userData)) { |       if (readReponseContent(&userData)) { | ||||||
|         printUserData(&userData); |         printUserData(&userData); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -89,7 +86,7 @@ bool sendRequest(const char* host, const char* resource) { | |||||||
|   client.print(resource); |   client.print(resource); | ||||||
|   client.println(" HTTP/1.0"); |   client.println(" HTTP/1.0"); | ||||||
|   client.print("Host: "); |   client.print("Host: "); | ||||||
|   client.println(server); |   client.println(host); | ||||||
|   client.println("Connection: close"); |   client.println("Connection: close"); | ||||||
|   client.println(); |   client.println(); | ||||||
|  |  | ||||||
| @@ -111,13 +108,6 @@ bool skipResponseHeaders() { | |||||||
|   return ok; |   return ok; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Read the body of the response from the HTTP server |  | ||||||
| void readReponseContent(char* content, size_t maxSize) { |  | ||||||
|   size_t length = client.readBytes(content, maxSize); |  | ||||||
|   content[length] = 0; |  | ||||||
|   Serial.println(content); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| // Parse the JSON from the input string and extract the interesting values | // Parse the JSON from the input string and extract the interesting values | ||||||
| // Here is the JSON we need to parse | // Here is the JSON we need to parse | ||||||
| // { | // { | ||||||
| @@ -143,21 +133,20 @@ void readReponseContent(char* content, size_t maxSize) { | |||||||
| //     "bs": "harness real-time e-markets" | //     "bs": "harness real-time e-markets" | ||||||
| //   } | //   } | ||||||
| // } | // } | ||||||
| bool parseUserData(char* content, struct UserData* userData) { | bool readReponseContent(struct UserData* userData) { | ||||||
|   // Compute optimal size of the JSON buffer according to what we need to parse. |   // Compute optimal size of the JSON buffer according to what we need to parse. | ||||||
|   // This is only required if you use StaticJsonBuffer. |   // This is only required if you use StaticJsonBuffer. | ||||||
|   const size_t BUFFER_SIZE = |   const size_t BUFFER_SIZE = | ||||||
|       JSON_OBJECT_SIZE(8)     // the root object has 8 elements |       JSON_OBJECT_SIZE(8)    // the root object has 8 elements | ||||||
|       + JSON_OBJECT_SIZE(5)   // the "address" object has 5 elements |       + JSON_OBJECT_SIZE(5)  // the "address" object has 5 elements | ||||||
|       + JSON_OBJECT_SIZE(2)   // the "geo" object has 2 elements |       + JSON_OBJECT_SIZE(2)  // the "geo" object has 2 elements | ||||||
|       + JSON_OBJECT_SIZE(3);  // the "company" object has 3 elements |       + JSON_OBJECT_SIZE(3)  // the "company" object has 3 elements | ||||||
|  |       + MAX_CONTENT_SIZE;    // additional space for strings | ||||||
|  |  | ||||||
|   // Allocate a temporary memory pool on the stack |   // Allocate a temporary memory pool | ||||||
|   StaticJsonBuffer<BUFFER_SIZE> jsonBuffer; |   DynamicJsonBuffer jsonBuffer(BUFFER_SIZE); | ||||||
|   // If the memory pool is too big for the stack, use this instead: |  | ||||||
|   // DynamicJsonBuffer jsonBuffer; |  | ||||||
|  |  | ||||||
|   JsonObject& root = jsonBuffer.parseObject(content); |   JsonObject& root = jsonBuffer.parseObject(client); | ||||||
|  |  | ||||||
|   if (!root.success()) { |   if (!root.success()) { | ||||||
|     Serial.println("JSON parsing failed!"); |     Serial.println("JSON parsing failed!"); | ||||||
|   | |||||||
| @@ -27,6 +27,10 @@ | |||||||
| #define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 | #define ARDUINOJSON_ENABLE_ARDUINO_STRING 1 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | #ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM | ||||||
|  | #define ARDUINOJSON_ENABLE_ARDUINO_STREAM 1 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| // On AVR archiecture, we can use PROGMEM | // On AVR archiecture, we can use PROGMEM | ||||||
| #ifndef ARDUINOJSON_ENABLE_PROGMEM | #ifndef ARDUINOJSON_ENABLE_PROGMEM | ||||||
| #ifdef PROGMEM | #ifdef PROGMEM | ||||||
| @@ -106,6 +110,11 @@ | |||||||
| #define ARDUINOJSON_ENABLE_STD_STREAM 1 | #define ARDUINOJSON_ENABLE_STD_STREAM 1 | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | // on a computer, there is no reason to beleive Arduino Stream is available | ||||||
|  | #ifndef ARDUINOJSON_ENABLE_ARDUINO_STREAM | ||||||
|  | #define ARDUINOJSON_ENABLE_ARDUINO_STREAM 0 | ||||||
|  | #endif | ||||||
|  |  | ||||||
| #ifndef ARDUINOJSON_ENABLE_ALIGNMENT | #ifndef ARDUINOJSON_ENABLE_ALIGNMENT | ||||||
| // even if not required, most cpu's are faster with aligned pointers | // even if not required, most cpu's are faster with aligned pointers | ||||||
| #define ARDUINOJSON_ENABLE_ALIGNMENT 1 | #define ARDUINOJSON_ENABLE_ALIGNMENT 1 | ||||||
|   | |||||||
| @@ -1,148 +0,0 @@ | |||||||
| // Copyright Benoit Blanchon 2014-2016 |  | ||||||
| // MIT License |  | ||||||
| // |  | ||||||
| // Arduino JSON library |  | ||||||
| // https://github.com/bblanchon/ArduinoJson |  | ||||||
| // If you like this project, please add a star! |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "../Configuration.hpp" |  | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STRING |  | ||||||
| #include <WString.h> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_STD_STRING |  | ||||||
| #include <string> |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { |  | ||||||
| namespace Internals { |  | ||||||
|  |  | ||||||
| template <typename TString> |  | ||||||
| struct StringFuncs {}; |  | ||||||
|  |  | ||||||
| template <typename TString> |  | ||||||
| struct StringFuncs<const TString> : StringFuncs<TString> {}; |  | ||||||
|  |  | ||||||
| template <typename TString> |  | ||||||
| struct StringFuncs<TString&> : StringFuncs<TString> {}; |  | ||||||
|  |  | ||||||
| struct CharPtrFuncs { |  | ||||||
|   class Iterator { |  | ||||||
|     const char* _ptr; |  | ||||||
|  |  | ||||||
|    public: |  | ||||||
|     Iterator(const char* ptr) : _ptr(ptr ? ptr : "") {} |  | ||||||
|  |  | ||||||
|     char next() { |  | ||||||
|       return *_ptr++; |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   static bool equals(const char* str, const char* expected) { |  | ||||||
|     return strcmp(str, expected) == 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   template <typename Buffer> |  | ||||||
|   static char* duplicate(const char* str, Buffer* buffer) { |  | ||||||
|     if (!str) return NULL; |  | ||||||
|     size_t size = strlen(str) + 1; |  | ||||||
|     void* dup = buffer->alloc(size); |  | ||||||
|     if (dup != NULL) memcpy(dup, str, size); |  | ||||||
|     return static_cast<char*>(dup); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static const bool has_append = false; |  | ||||||
|   static const bool has_equals = true; |  | ||||||
|   static const bool should_duplicate = false; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| template <> |  | ||||||
| struct StringFuncs<const char*> : CharPtrFuncs {}; |  | ||||||
|  |  | ||||||
| template <> |  | ||||||
| struct StringFuncs<char*> : CharPtrFuncs {}; |  | ||||||
|  |  | ||||||
| template <size_t N> |  | ||||||
| struct StringFuncs<char[N]> : CharPtrFuncs {}; |  | ||||||
|  |  | ||||||
| template <size_t N> |  | ||||||
| struct StringFuncs<const char[N]> : CharPtrFuncs {}; |  | ||||||
|  |  | ||||||
| template <typename TString> |  | ||||||
| struct StdStringFuncs { |  | ||||||
|   template <typename Buffer> |  | ||||||
|   static char* duplicate(const TString& str, Buffer* buffer) { |  | ||||||
|     if (!str.c_str()) return NULL;  // <- Arduino string can return NULL |  | ||||||
|     size_t size = str.length() + 1; |  | ||||||
|     void* dup = buffer->alloc(size); |  | ||||||
|     if (dup != NULL) memcpy(dup, str.c_str(), size); |  | ||||||
|     return static_cast<char*>(dup); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   struct Iterator : CharPtrFuncs::Iterator { |  | ||||||
|     Iterator(const TString& str) : CharPtrFuncs::Iterator(str.c_str()) {} |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   static bool equals(const TString& str, const char* expected) { |  | ||||||
|     return str == expected; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static void append(TString& str, char c) { |  | ||||||
|     str += c; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static const bool has_append = true; |  | ||||||
|   static const bool has_equals = true; |  | ||||||
|   static const bool should_duplicate = true; |  | ||||||
| }; |  | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STRING |  | ||||||
| template <> |  | ||||||
| struct StringFuncs<String> : StdStringFuncs<String> {}; |  | ||||||
| template <> |  | ||||||
| struct StringFuncs<StringSumHelper> : StdStringFuncs<StringSumHelper> {}; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_STD_STRING |  | ||||||
| template <> |  | ||||||
| struct StringFuncs<std::string> : StdStringFuncs<std::string> {}; |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if ARDUINOJSON_ENABLE_PROGMEM |  | ||||||
| template <> |  | ||||||
| struct StringFuncs<const __FlashStringHelper*> { |  | ||||||
|   class Iterator { |  | ||||||
|     const char* _ptr; |  | ||||||
|  |  | ||||||
|    public: |  | ||||||
|     Iterator(const __FlashStringHelper* ptr) |  | ||||||
|         : _ptr(reinterpret_cast<const char*>(ptr)) {} |  | ||||||
|  |  | ||||||
|     char next() { |  | ||||||
|       return pgm_read_byte_near(_ptr++); |  | ||||||
|     } |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
|   static bool equals(const __FlashStringHelper* str, const char* expected) { |  | ||||||
|     return strcmp_P(expected, (PGM_P)str) == 0; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   template <typename Buffer> |  | ||||||
|   static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) { |  | ||||||
|     if (!str) return NULL; |  | ||||||
|     size_t size = strlen_P((PGM_P)str) + 1; |  | ||||||
|     void* dup = buffer->alloc(size); |  | ||||||
|     if (dup != NULL) memcpy_P(dup, (PGM_P)str, size); |  | ||||||
|     return static_cast<char*>(dup); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   static const bool has_append = false; |  | ||||||
|   static const bool has_equals = true; |  | ||||||
|   static const bool should_duplicate = true; |  | ||||||
| }; |  | ||||||
| #endif |  | ||||||
| } |  | ||||||
| } |  | ||||||
| @@ -9,8 +9,8 @@ | |||||||
|  |  | ||||||
| #include "../JsonBuffer.hpp" | #include "../JsonBuffer.hpp" | ||||||
| #include "../JsonVariant.hpp" | #include "../JsonVariant.hpp" | ||||||
|  | #include "../StringTraits/StringTraits.hpp" | ||||||
| #include "../TypeTraits/EnableIf.hpp" | #include "../TypeTraits/EnableIf.hpp" | ||||||
| #include "StringFuncs.hpp" |  | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|   | |||||||
| @@ -77,7 +77,7 @@ struct JsonParserBuilder { | |||||||
|   typedef typename Internals::StringFuncs<TString>::Iterator InputIterator; |   typedef typename Internals::StringFuncs<TString>::Iterator InputIterator; | ||||||
|   typedef JsonParser<StringReader<InputIterator>, TJsonBuffer &> TParser; |   typedef JsonParser<StringReader<InputIterator>, TJsonBuffer &> TParser; | ||||||
|  |  | ||||||
|   static TParser makeParser(TJsonBuffer *buffer, const TString &json, |   static TParser makeParser(TJsonBuffer *buffer, TString &json, | ||||||
|                             uint8_t nestingLimit) { |                             uint8_t nestingLimit) { | ||||||
|     return TParser(buffer, InputIterator(json), *buffer, nestingLimit); |     return TParser(buffer, InputIterator(json), *buffer, nestingLimit); | ||||||
|   } |   } | ||||||
| @@ -94,9 +94,9 @@ struct JsonParserBuilder<TJsonBuffer, char *> { | |||||||
|   } |   } | ||||||
| }; | }; | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TChar, size_t N> | template <typename TJsonBuffer, size_t N> | ||||||
| struct JsonParserBuilder<TJsonBuffer, TChar[N]> | struct JsonParserBuilder<TJsonBuffer, char[N]> | ||||||
|     : JsonParserBuilder<TJsonBuffer, TChar *> {}; |     : JsonParserBuilder<TJsonBuffer, char *> {}; | ||||||
|  |  | ||||||
| template <typename TJsonBuffer, typename TString> | template <typename TJsonBuffer, typename TString> | ||||||
| inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser( | inline typename JsonParserBuilder<TJsonBuffer, TString>::TParser makeParser( | ||||||
|   | |||||||
| @@ -10,10 +10,10 @@ | |||||||
| #include "Data/JsonBufferAllocated.hpp" | #include "Data/JsonBufferAllocated.hpp" | ||||||
| #include "Data/List.hpp" | #include "Data/List.hpp" | ||||||
| #include "Data/ReferenceType.hpp" | #include "Data/ReferenceType.hpp" | ||||||
| #include "Data/StringFuncs.hpp" |  | ||||||
| #include "Data/ValueSetter.hpp" | #include "Data/ValueSetter.hpp" | ||||||
| #include "JsonVariant.hpp" | #include "JsonVariant.hpp" | ||||||
| #include "Serialization/JsonPrintable.hpp" | #include "Serialization/JsonPrintable.hpp" | ||||||
|  | #include "StringTraits/StringTraits.hpp" | ||||||
| #include "TypeTraits/ConstRefOrConstPtr.hpp" | #include "TypeTraits/ConstRefOrConstPtr.hpp" | ||||||
| #include "TypeTraits/EnableIf.hpp" | #include "TypeTraits/EnableIf.hpp" | ||||||
| #include "TypeTraits/IsFloatingPoint.hpp" | #include "TypeTraits/IsFloatingPoint.hpp" | ||||||
|   | |||||||
| @@ -10,10 +10,10 @@ | |||||||
| #include "Data/JsonBufferAllocated.hpp" | #include "Data/JsonBufferAllocated.hpp" | ||||||
| #include "Data/List.hpp" | #include "Data/List.hpp" | ||||||
| #include "Data/ReferenceType.hpp" | #include "Data/ReferenceType.hpp" | ||||||
| #include "Data/StringFuncs.hpp" |  | ||||||
| #include "Data/ValueSetter.hpp" | #include "Data/ValueSetter.hpp" | ||||||
| #include "JsonPair.hpp" | #include "JsonPair.hpp" | ||||||
| #include "Serialization/JsonPrintable.hpp" | #include "Serialization/JsonPrintable.hpp" | ||||||
|  | #include "StringTraits/StringTraits.hpp" | ||||||
| #include "TypeTraits/ConstRefOrConstPtr.hpp" | #include "TypeTraits/ConstRefOrConstPtr.hpp" | ||||||
| #include "TypeTraits/EnableIf.hpp" | #include "TypeTraits/EnableIf.hpp" | ||||||
| #include "TypeTraits/IsFloatingPoint.hpp" | #include "TypeTraits/IsFloatingPoint.hpp" | ||||||
|   | |||||||
| @@ -7,8 +7,8 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "Data/StringFuncs.hpp" |  | ||||||
| #include "JsonVariantBase.hpp" | #include "JsonVariantBase.hpp" | ||||||
|  | #include "StringTraits/StringTraits.hpp" | ||||||
| #include "TypeTraits/EnableIf.hpp" | #include "TypeTraits/EnableIf.hpp" | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
|   | |||||||
| @@ -7,8 +7,8 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "../Data/StringFuncs.hpp" |  | ||||||
| #include "../Print.hpp" | #include "../Print.hpp" | ||||||
|  | #include "../StringTraits/StringTraits.hpp" | ||||||
|  |  | ||||||
| namespace ArduinoJson { | namespace ArduinoJson { | ||||||
| namespace Internals { | namespace Internals { | ||||||
|   | |||||||
							
								
								
									
										39
									
								
								include/ArduinoJson/StringTraits/ArduinoStream.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								include/ArduinoJson/StringTraits/ArduinoStream.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "../TypeTraits/EnableIf.hpp" | ||||||
|  | #include "../TypeTraits/IsBaseOf.hpp" | ||||||
|  | #include "../TypeTraits/RemoveReference.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | struct StdStreamFuncs { | ||||||
|  |   class Iterator { | ||||||
|  |     Stream& _stream; | ||||||
|  |  | ||||||
|  |    public: | ||||||
|  |     Iterator(Stream& stream) : _stream(stream) {} | ||||||
|  |  | ||||||
|  |     char next() { | ||||||
|  |       int n = _stream.read(); | ||||||
|  |       return n >= 0 ? static_cast<char>(n) : '\0'; | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename TStream> | ||||||
|  | struct StringFuncs<TStream, | ||||||
|  |                    // match any type that is derived from std::istream: | ||||||
|  |                    typename TypeTraits::EnableIf<TypeTraits::IsBaseOf< | ||||||
|  |                        Stream, typename TypeTraits::RemoveReference< | ||||||
|  |                                    TStream>::type>::value>::type> | ||||||
|  |     : StdStreamFuncs {}; | ||||||
|  | } | ||||||
|  | } | ||||||
							
								
								
									
										57
									
								
								include/ArduinoJson/StringTraits/CharPointer.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								include/ArduinoJson/StringTraits/CharPointer.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | struct CharPtrFuncs { | ||||||
|  |   class Iterator { | ||||||
|  |     const char* _ptr; | ||||||
|  |  | ||||||
|  |    public: | ||||||
|  |     Iterator(const char* ptr) : _ptr(ptr ? ptr : "") {} | ||||||
|  |  | ||||||
|  |     char next() { | ||||||
|  |       char c = *_ptr; | ||||||
|  |       if (c) ++_ptr; | ||||||
|  |       return c; | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   static bool equals(const char* str, const char* expected) { | ||||||
|  |     return strcmp(str, expected) == 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename Buffer> | ||||||
|  |   static char* duplicate(const char* str, Buffer* buffer) { | ||||||
|  |     if (!str) return NULL; | ||||||
|  |     size_t size = strlen(str) + 1; | ||||||
|  |     void* dup = buffer->alloc(size); | ||||||
|  |     if (dup != NULL) memcpy(dup, str, size); | ||||||
|  |     return static_cast<char*>(dup); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static const bool has_append = false; | ||||||
|  |   static const bool has_equals = true; | ||||||
|  |   static const bool should_duplicate = false; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <> | ||||||
|  | struct StringFuncs<const char*, void> : CharPtrFuncs {}; | ||||||
|  |  | ||||||
|  | template <> | ||||||
|  | struct StringFuncs<char*, void> : CharPtrFuncs {}; | ||||||
|  |  | ||||||
|  | template <size_t N> | ||||||
|  | struct StringFuncs<char[N], void> : CharPtrFuncs {}; | ||||||
|  |  | ||||||
|  | template <size_t N> | ||||||
|  | struct StringFuncs<const char[N], void> : CharPtrFuncs {}; | ||||||
|  | } | ||||||
|  | } | ||||||
							
								
								
									
										44
									
								
								include/ArduinoJson/StringTraits/FlashString.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								include/ArduinoJson/StringTraits/FlashString.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  | template <> | ||||||
|  | struct StringFuncs<const __FlashStringHelper*, void> { | ||||||
|  |   class Iterator { | ||||||
|  |     const char* _ptr; | ||||||
|  |  | ||||||
|  |    public: | ||||||
|  |     Iterator(const __FlashStringHelper* ptr) | ||||||
|  |         : _ptr(reinterpret_cast<const char*>(ptr)) {} | ||||||
|  |  | ||||||
|  |     char next() { | ||||||
|  |       return pgm_read_byte_near(_ptr++); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   static bool equals(const __FlashStringHelper* str, const char* expected) { | ||||||
|  |     return strcmp_P(expected, (PGM_P)str) == 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   template <typename Buffer> | ||||||
|  |   static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) { | ||||||
|  |     if (!str) return NULL; | ||||||
|  |     size_t size = strlen_P((PGM_P)str) + 1; | ||||||
|  |     void* dup = buffer->alloc(size); | ||||||
|  |     if (dup != NULL) memcpy_P(dup, (PGM_P)str, size); | ||||||
|  |     return static_cast<char*>(dup); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static const bool has_append = false; | ||||||
|  |   static const bool has_equals = true; | ||||||
|  |   static const bool should_duplicate = true; | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								include/ArduinoJson/StringTraits/StdStream.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								include/ArduinoJson/StringTraits/StdStream.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <istream> | ||||||
|  | #include "../TypeTraits/EnableIf.hpp" | ||||||
|  | #include "../TypeTraits/IsBaseOf.hpp" | ||||||
|  | #include "../TypeTraits/RemoveReference.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | struct StdStreamFuncs { | ||||||
|  |   class Iterator { | ||||||
|  |     std::istream& _stream; | ||||||
|  |  | ||||||
|  |    public: | ||||||
|  |     Iterator(std::istream& stream) : _stream(stream) {} | ||||||
|  |  | ||||||
|  |     char next() { | ||||||
|  |       return _stream.eof() ? '\0' : static_cast<char>(_stream.get()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |    private: | ||||||
|  |     Iterator& operator=(const Iterator&);  // Visual Studio C4512 | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | template <typename TStream> | ||||||
|  | struct StringFuncs<TStream, | ||||||
|  |                    // match any type that is derived from std::istream: | ||||||
|  |                    typename TypeTraits::EnableIf<TypeTraits::IsBaseOf< | ||||||
|  |                        std::istream, typename TypeTraits::RemoveReference< | ||||||
|  |                                          TStream>::type>::value>::type> | ||||||
|  |     : StdStreamFuncs {}; | ||||||
|  | } | ||||||
|  | } | ||||||
							
								
								
									
										61
									
								
								include/ArduinoJson/StringTraits/StdString.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								include/ArduinoJson/StringTraits/StdString.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_ARDUINO_STRING | ||||||
|  | #include <WString.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_STD_STRING | ||||||
|  | #include <string> | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <typename TString> | ||||||
|  | struct StdStringFuncs { | ||||||
|  |   template <typename Buffer> | ||||||
|  |   static char* duplicate(const TString& str, Buffer* buffer) { | ||||||
|  |     if (!str.c_str()) return NULL;  // <- Arduino string can return NULL | ||||||
|  |     size_t size = str.length() + 1; | ||||||
|  |     void* dup = buffer->alloc(size); | ||||||
|  |     if (dup != NULL) memcpy(dup, str.c_str(), size); | ||||||
|  |     return static_cast<char*>(dup); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   struct Iterator : CharPtrFuncs::Iterator { | ||||||
|  |     Iterator(const TString& str) : CharPtrFuncs::Iterator(str.c_str()) {} | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  |   static bool equals(const TString& str, const char* expected) { | ||||||
|  |     return str == expected; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static void append(TString& str, char c) { | ||||||
|  |     str += c; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   static const bool has_append = true; | ||||||
|  |   static const bool has_equals = true; | ||||||
|  |   static const bool should_duplicate = true; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_ARDUINO_STRING | ||||||
|  | template <> | ||||||
|  | struct StringFuncs<String, void> : StdStringFuncs<String> {}; | ||||||
|  | template <> | ||||||
|  | struct StringFuncs<StringSumHelper, void> : StdStringFuncs<StringSumHelper> {}; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_STD_STRING | ||||||
|  | template <> | ||||||
|  | struct StringFuncs<std::string, void> : StdStringFuncs<std::string> {}; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | } | ||||||
							
								
								
									
										42
									
								
								include/ArduinoJson/StringTraits/StringTraits.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								include/ArduinoJson/StringTraits/StringTraits.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "../Configuration.hpp" | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace Internals { | ||||||
|  |  | ||||||
|  | template <typename TString, typename Enable = void> | ||||||
|  | struct StringFuncs {}; | ||||||
|  |  | ||||||
|  | template <typename TString> | ||||||
|  | struct StringFuncs<const TString, void> : StringFuncs<TString> {}; | ||||||
|  |  | ||||||
|  | template <typename TString> | ||||||
|  | struct StringFuncs<TString&, void> : StringFuncs<TString> {}; | ||||||
|  | } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #include "CharPointer.hpp" | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_STD_STRING || ARDUINOJSON_ENABLE_ARDUINO_STRING | ||||||
|  | #include "StdString.hpp" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_STD_STREAM | ||||||
|  | #include "StdStream.hpp" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_ARDUINO_STREAM | ||||||
|  | #include "ArduinoStream.hpp" | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #if ARDUINOJSON_ENABLE_PROGMEM | ||||||
|  | #include "FlashString.hpp" | ||||||
|  | #endif | ||||||
							
								
								
									
										30
									
								
								include/ArduinoJson/TypeTraits/IsBaseOf.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								include/ArduinoJson/TypeTraits/IsBaseOf.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,30 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace ArduinoJson { | ||||||
|  | namespace TypeTraits { | ||||||
|  |  | ||||||
|  | // A meta-function that returns true if Derived inherits from TBase is an | ||||||
|  | // integral type. | ||||||
|  | template <typename TBase, typename TDerived> | ||||||
|  | class IsBaseOf { | ||||||
|  |  protected:  // <- to avoid GCC's "all member functions in class are private" | ||||||
|  |   typedef char Yes[1]; | ||||||
|  |   typedef char No[2]; | ||||||
|  |  | ||||||
|  |   static Yes &probe(const TBase *); | ||||||
|  |   static No &probe(const void *); | ||||||
|  |  | ||||||
|  |  public: | ||||||
|  |   enum { | ||||||
|  |     value = sizeof(probe(reinterpret_cast<TDerived *>(0))) == sizeof(Yes) | ||||||
|  |   }; | ||||||
|  | }; | ||||||
|  | } | ||||||
|  | } | ||||||
| @@ -3,5 +3,5 @@ | |||||||
| curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1 | curl https://cmake.org/files/v3.4/cmake-3.4.0-Linux-x86_64.tar.gz | tar xz -C /tmp --strip 1 | ||||||
|  |  | ||||||
| /tmp/bin/cmake -DSANITIZE=true . | /tmp/bin/cmake -DSANITIZE=true . | ||||||
| make  | cmake --build . | ||||||
| make test | ctest -VV . | ||||||
|   | |||||||
| @@ -351,6 +351,16 @@ TEST_F(JsonParser_Array_Tests, UnfinishedCComment) { | |||||||
|   parseMustFail(); |   parseMustFail(); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | TEST_F(JsonParser_Array_Tests, EndsInCppComment) { | ||||||
|  |   whenInputIs("[//COMMENT"); | ||||||
|  |   parseMustFail(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | TEST_F(JsonParser_Array_Tests, AfterClosingStar) { | ||||||
|  |   whenInputIs("[/*COMMENT*"); | ||||||
|  |   parseMustFail(); | ||||||
|  | } | ||||||
|  |  | ||||||
| TEST_F(JsonParser_Array_Tests, DeeplyNested) { | TEST_F(JsonParser_Array_Tests, DeeplyNested) { | ||||||
|   whenInputIs("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"); |   whenInputIs("[[[[[[[[[[[[[[[[[[[\"Not too deep\"]]]]]]]]]]]]]]]]]]]"); | ||||||
|   parseMustSucceed(); |   parseMustSucceed(); | ||||||
|   | |||||||
| @@ -5,25 +5,25 @@ | |||||||
| // https://github.com/bblanchon/ArduinoJson
 | // https://github.com/bblanchon/ArduinoJson
 | ||||||
| // If you like this project, please add a star!
 | // If you like this project, please add a star!
 | ||||||
| 
 | 
 | ||||||
| #include <sstream> |  | ||||||
| #include <gtest/gtest.h> |  | ||||||
| #include <ArduinoJson.h> | #include <ArduinoJson.h> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <sstream> | ||||||
| 
 | 
 | ||||||
| TEST(StdStream, JsonVariantFalse) { | TEST(StdStream_Tests, JsonVariantFalse) { | ||||||
|   std::ostringstream os; |   std::ostringstream os; | ||||||
|   JsonVariant variant = false; |   JsonVariant variant = false; | ||||||
|   os << variant; |   os << variant; | ||||||
|   ASSERT_EQ("false", os.str()); |   ASSERT_EQ("false", os.str()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TEST(StdStream, JsonVariantString) { | TEST(StdStream_Tests, JsonVariantString) { | ||||||
|   std::ostringstream os; |   std::ostringstream os; | ||||||
|   JsonVariant variant = "coucou"; |   JsonVariant variant = "coucou"; | ||||||
|   os << variant; |   os << variant; | ||||||
|   ASSERT_EQ("\"coucou\"", os.str()); |   ASSERT_EQ("\"coucou\"", os.str()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TEST(StdStream, JsonObject) { | TEST(StdStream_Tests, JsonObject) { | ||||||
|   std::ostringstream os; |   std::ostringstream os; | ||||||
|   DynamicJsonBuffer jsonBuffer; |   DynamicJsonBuffer jsonBuffer; | ||||||
|   JsonObject& object = jsonBuffer.createObject(); |   JsonObject& object = jsonBuffer.createObject(); | ||||||
| @@ -32,7 +32,7 @@ TEST(StdStream, JsonObject) { | |||||||
|   ASSERT_EQ("{\"key\":\"value\"}", os.str()); |   ASSERT_EQ("{\"key\":\"value\"}", os.str()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TEST(StdStream, JsonObjectSubscript) { | TEST(StdStream_Tests, JsonObjectSubscript) { | ||||||
|   std::ostringstream os; |   std::ostringstream os; | ||||||
|   DynamicJsonBuffer jsonBuffer; |   DynamicJsonBuffer jsonBuffer; | ||||||
|   JsonObject& object = jsonBuffer.createObject(); |   JsonObject& object = jsonBuffer.createObject(); | ||||||
| @@ -41,7 +41,7 @@ TEST(StdStream, JsonObjectSubscript) { | |||||||
|   ASSERT_EQ("\"value\"", os.str()); |   ASSERT_EQ("\"value\"", os.str()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TEST(StdStream, JsonArray) { | TEST(StdStream_Tests, JsonArray) { | ||||||
|   std::ostringstream os; |   std::ostringstream os; | ||||||
|   DynamicJsonBuffer jsonBuffer; |   DynamicJsonBuffer jsonBuffer; | ||||||
|   JsonArray& array = jsonBuffer.createArray(); |   JsonArray& array = jsonBuffer.createArray(); | ||||||
| @@ -50,7 +50,7 @@ TEST(StdStream, JsonArray) { | |||||||
|   ASSERT_EQ("[\"value\"]", os.str()); |   ASSERT_EQ("[\"value\"]", os.str()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| TEST(StdStream, JsonArraySubscript) { | TEST(StdStream_Tests, JsonArraySubscript) { | ||||||
|   std::ostringstream os; |   std::ostringstream os; | ||||||
|   DynamicJsonBuffer jsonBuffer; |   DynamicJsonBuffer jsonBuffer; | ||||||
|   JsonArray& array = jsonBuffer.createArray(); |   JsonArray& array = jsonBuffer.createArray(); | ||||||
| @@ -58,3 +58,21 @@ TEST(StdStream, JsonArraySubscript) { | |||||||
|   os << array[0]; |   os << array[0]; | ||||||
|   ASSERT_EQ("\"value\"", os.str()); |   ASSERT_EQ("\"value\"", os.str()); | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | TEST(StdStream_Tests, ParseArray) { | ||||||
|  |   std::istringstream json("[42]"); | ||||||
|  |   DynamicJsonBuffer jsonBuffer; | ||||||
|  |   JsonArray& arr = jsonBuffer.parseArray(json); | ||||||
|  |   ASSERT_TRUE(arr.success()); | ||||||
|  |   ASSERT_EQ(1, arr.size()); | ||||||
|  |   ASSERT_EQ(42, arr[0]); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | TEST(StdStream_Tests, ParseObject) { | ||||||
|  |   std::istringstream json("{hello:world}"); | ||||||
|  |   DynamicJsonBuffer jsonBuffer; | ||||||
|  |   JsonObject& obj = jsonBuffer.parseObject(json); | ||||||
|  |   ASSERT_TRUE(obj.success()); | ||||||
|  |   ASSERT_EQ(1, obj.size()); | ||||||
|  |   ASSERT_STREQ("world", obj["hello"]); | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								test/TypeTraits_Tests.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								test/TypeTraits_Tests.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | // Copyright Benoit Blanchon 2014-2016 | ||||||
|  | // MIT License | ||||||
|  | // | ||||||
|  | // Arduino JSON library | ||||||
|  | // https://github.com/bblanchon/ArduinoJson | ||||||
|  | // If you like this project, please add a star! | ||||||
|  |  | ||||||
|  | #include <ArduinoJson.h> | ||||||
|  | #include <gtest/gtest.h> | ||||||
|  | #include <sstream> | ||||||
|  |  | ||||||
|  | using namespace ArduinoJson::TypeTraits; | ||||||
|  |  | ||||||
|  | TEST(StdStream, IsBaseOf) { | ||||||
|  |   ASSERT_FALSE((IsBaseOf<std::istream, std::ostringstream>::value)); | ||||||
|  |   ASSERT_TRUE((IsBaseOf<std::istream, std::istringstream>::value)); | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user