mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Changed the rules of string duplication (fixes #658)
This commit is contained in:
		
							
								
								
									
										16
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,6 +1,22 @@ | ||||
| ArduinoJson: change log | ||||
| ======================= | ||||
|  | ||||
| HEAD | ||||
| ---- | ||||
|  | ||||
| * Changed the rules of string duplication (issue #658) | ||||
|  | ||||
| > ### New rules for string duplication | ||||
| > | ||||
| > | type         | duplication | | ||||
| > |:-------------|:------------| | ||||
| > | const char*  | no          | | ||||
| > | char*        | ~~no~~ yes  | | ||||
| > | String       | yes         | | ||||
| > | std::string  | yes         | | ||||
| > | ||||
| > These new rules make `JsonBuffer::strdup()` useless. | ||||
|  | ||||
| v5.12.0 | ||||
| ------- | ||||
|  | ||||
|   | ||||
							
								
								
									
										34
									
								
								src/ArduinoJson/Data/ValueSaver.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/ArduinoJson/Data/ValueSaver.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../JsonBuffer.hpp" | ||||
| #include "../JsonVariant.hpp" | ||||
| #include "../StringTraits/StringTraits.hpp" | ||||
| #include "../TypeTraits/EnableIf.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| template <typename Source, typename Enable = void> | ||||
| struct ValueSaver { | ||||
|   template <typename Destination> | ||||
|   static bool save(JsonBuffer*, Destination& destination, Source source) { | ||||
|     destination = source; | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename Source> | ||||
| struct ValueSaver<Source, typename TypeTraits::EnableIf< | ||||
|                               TypeTraits::IsString<Source>::value>::type> { | ||||
|   template <typename Destination> | ||||
|   static bool save(JsonBuffer* buffer, Destination& destination, | ||||
|                    Source source) { | ||||
|     return StringTraits<Source>::save(source, destination, buffer); | ||||
|   } | ||||
| }; | ||||
| } | ||||
| } | ||||
| @@ -1,48 +0,0 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../JsonBuffer.hpp" | ||||
| #include "../JsonVariant.hpp" | ||||
| #include "../StringTraits/StringTraits.hpp" | ||||
| #include "../TypeTraits/EnableIf.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| namespace Internals { | ||||
|  | ||||
| template <typename TSourceRef, typename Enable = void> | ||||
| struct ValueSetter { | ||||
|   template <typename TDestination> | ||||
|   static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) { | ||||
|     destination = source; | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TSourceRef> | ||||
| struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<StringTraits< | ||||
|                                    TSourceRef>::should_duplicate>::type> { | ||||
|   template <typename TDestination> | ||||
|   static bool set(JsonBuffer* buffer, TDestination& destination, | ||||
|                   TSourceRef source) { | ||||
|     const char* copy = buffer->strdup(source); | ||||
|     if (!copy) return false; | ||||
|     destination = copy; | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| template <typename TSourceRef> | ||||
| struct ValueSetter<TSourceRef, typename TypeTraits::EnableIf<!StringTraits< | ||||
|                                    TSourceRef>::should_duplicate>::type> { | ||||
|   template <typename TDestination> | ||||
|   static bool set(JsonBuffer*, TDestination& destination, TSourceRef source) { | ||||
|     // unsigned char* -> char* | ||||
|     destination = reinterpret_cast<const char*>(source); | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
| } | ||||
| } | ||||
| @@ -7,7 +7,7 @@ | ||||
| #include "Data/JsonBufferAllocated.hpp" | ||||
| #include "Data/List.hpp" | ||||
| #include "Data/ReferenceType.hpp" | ||||
| #include "Data/ValueSetter.hpp" | ||||
| #include "Data/ValueSaver.hpp" | ||||
| #include "JsonVariant.hpp" | ||||
| #include "Serialization/JsonPrintable.hpp" | ||||
| #include "StringTraits/StringTraits.hpp" | ||||
| @@ -56,19 +56,17 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>, | ||||
|   // | ||||
|   // bool add(TValue); | ||||
|   // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename T> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type add( | ||||
|       const T &value) { | ||||
|   bool add(const T &value) { | ||||
|     return add_impl<const T &>(value); | ||||
|   } | ||||
|   // | ||||
|   // bool add(TValue); | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = char*, const char*, const FlashStringHelper* | ||||
|   template <typename T> | ||||
|   bool add(const T *value) { | ||||
|     return add_impl<const T *>(value); | ||||
|   bool add(T *value) { | ||||
|     return add_impl<T *>(value); | ||||
|   } | ||||
|   // | ||||
|   // bool add(TValue value, uint8_t decimals); | ||||
| @@ -81,21 +79,19 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>, | ||||
|  | ||||
|   // Sets the value at specified index. | ||||
|   // | ||||
|   // bool add(size_t index, TValue); | ||||
|   // bool add(size_t index, const TValue&); | ||||
|   // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename T> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<T>::value, bool>::type set( | ||||
|       size_t index, const T &value) { | ||||
|   bool set(size_t index, const T &value) { | ||||
|     return set_impl<const T &>(index, value); | ||||
|   } | ||||
|   // | ||||
|   // bool add(size_t index, TValue); | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = char*, const char*, const FlashStringHelper* | ||||
|   template <typename T> | ||||
|   bool set(size_t index, const T *value) { | ||||
|     return set_impl<const T *>(index, value); | ||||
|   bool set(size_t index, T *value) { | ||||
|     return set_impl<T *>(index, value); | ||||
|   } | ||||
|   // | ||||
|   // bool set(size_t index, TValue value, uint8_t decimals); | ||||
| @@ -208,14 +204,14 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>, | ||||
|   bool set_impl(size_t index, TValueRef value) { | ||||
|     iterator it = begin() += index; | ||||
|     if (it == end()) return false; | ||||
|     return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value); | ||||
|     return Internals::ValueSaver<TValueRef>::save(_buffer, *it, value); | ||||
|   } | ||||
|  | ||||
|   template <typename TValueRef> | ||||
|   bool add_impl(TValueRef value) { | ||||
|     iterator it = Internals::List<JsonVariant>::add(); | ||||
|     if (it == end()) return false; | ||||
|     return Internals::ValueSetter<TValueRef>::set(_buffer, *it, value); | ||||
|     return Internals::ValueSaver<TValueRef>::save(_buffer, *it, value); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -25,10 +25,9 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
|  | ||||
|   // Replaces the value | ||||
|   // | ||||
|   // operator=(TValue) | ||||
|   // operator=(const TValue&) | ||||
|   // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename T> | ||||
|   FORCE_INLINE JsonArraySubscript& operator=(const T& src) { | ||||
|     _array.set(_index, src); | ||||
| @@ -36,9 +35,9 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
|   } | ||||
|   // | ||||
|   // operator=(TValue) | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = char*, const char*, const FlashStringHelper* | ||||
|   template <typename T> | ||||
|   FORCE_INLINE JsonArraySubscript& operator=(const T* src) { | ||||
|   FORCE_INLINE JsonArraySubscript& operator=(T* src) { | ||||
|     _array.set(_index, src); | ||||
|     return *this; | ||||
|   } | ||||
| @@ -59,19 +58,18 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
|  | ||||
|   // Replaces the value | ||||
|   // | ||||
|   // bool set(TValue) | ||||
|   // bool set(const TValue&) | ||||
|   // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE bool set(const TValue& value) { | ||||
|     return _array.set(_index, value); | ||||
|   } | ||||
|   // | ||||
|   // bool set(TValue) | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = char*, const char*, const FlashStringHelper* | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE bool set(const TValue* value) { | ||||
|   FORCE_INLINE bool set(TValue* value) { | ||||
|     return _array.set(_index, value); | ||||
|   } | ||||
|   // | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| #include "Data/JsonBufferAllocated.hpp" | ||||
| #include "Data/List.hpp" | ||||
| #include "Data/ReferenceType.hpp" | ||||
| #include "Data/ValueSetter.hpp" | ||||
| #include "Data/ValueSaver.hpp" | ||||
| #include "JsonPair.hpp" | ||||
| #include "Serialization/JsonPrintable.hpp" | ||||
| #include "StringTraits/StringTraits.hpp" | ||||
| @@ -50,17 +50,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // JsonObjectSubscript operator[](TKey) | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value, | ||||
|                                 JsonObjectSubscript<const TString&> >::type | ||||
|   operator[](const TString& key) { | ||||
|   JsonObjectSubscript<const TString&> operator[](const TString& key) { | ||||
|     return JsonObjectSubscript<const TString&>(*this, key); | ||||
|   } | ||||
|   // | ||||
|   // JsonObjectSubscript operator[](TKey) | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, char[], const char[N], const FlashStringHelper* | ||||
|   template <typename TString> | ||||
|   JsonObjectSubscript<const TString*> operator[](const TString* key) { | ||||
|     return JsonObjectSubscript<const TString*>(*this, key); | ||||
|   JsonObjectSubscript<TString*> operator[](TString* key) { | ||||
|     return JsonObjectSubscript<TString*>(*this, key); | ||||
|   } | ||||
|  | ||||
|   // Gets the value associated with the specified key. | ||||
| @@ -68,10 +66,8 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // const JsonObjectSubscript operator[](TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TString> | ||||
|   typename TypeTraits::EnableIf< | ||||
|       !TypeTraits::IsArray<TString>::value, | ||||
|       const JsonObjectSubscript<const TString&> >::type | ||||
|   operator[](const TString& key) const { | ||||
|   const JsonObjectSubscript<const TString&> operator[]( | ||||
|       const TString& key) const { | ||||
|     return JsonObjectSubscript<const TString&>(*const_cast<JsonObject*>(this), | ||||
|                                                key); | ||||
|   } | ||||
| @@ -79,10 +75,8 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // const JsonObjectSubscript operator[](TKey) const; | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   template <typename TString> | ||||
|   const JsonObjectSubscript<const TString*> operator[]( | ||||
|       const TString* key) const { | ||||
|     return JsonObjectSubscript<const TString*>(*const_cast<JsonObject*>(this), | ||||
|                                                key); | ||||
|   const JsonObjectSubscript<TString*> operator[](TString* key) const { | ||||
|     return JsonObjectSubscript<TString*>(*const_cast<JsonObject*>(this), key); | ||||
|   } | ||||
|  | ||||
|   // Sets the specified key with the specified value. | ||||
| @@ -90,43 +84,35 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // bool set(TKey, TValue); | ||||
|   // TKey = const std::string&, const String& | ||||
|   // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue, typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value && | ||||
|                                     !TypeTraits::IsArray<TValue>::value, | ||||
|                                 bool>::type | ||||
|   set(const TString& key, const TValue& value) { | ||||
|   bool set(const TString& key, const TValue& value) { | ||||
|     return set_impl<const TString&, const TValue&>(key, value); | ||||
|   } | ||||
|   // | ||||
|   // bool set(TKey, TValue); | ||||
|   // TKey = const std::string&, const String& | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = char*, const char*, const FlashStringHelper* | ||||
|   template <typename TValue, typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value, | ||||
|                                 bool>::type | ||||
|   set(const TString& key, const TValue* value) { | ||||
|     return set_impl<const TString&, const TValue*>(key, value); | ||||
|   bool set(const TString& key, TValue* value) { | ||||
|     return set_impl<const TString&, TValue*>(key, value); | ||||
|   } | ||||
|   // | ||||
|   // bool set(TKey, TValue); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // bool set(TKey, const TValue&); | ||||
|   // TKey = char*, const char*, const FlashStringHelper* | ||||
|   // TValue = bool, long, int, short, float, double, RawJson, JsonVariant, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue, typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value, bool>::type | ||||
|   set(const TString* key, const TValue& value) { | ||||
|     return set_impl<const TString*, const TValue&>(key, value); | ||||
|   bool set(TString* key, const TValue& value) { | ||||
|     return set_impl<TString*, const TValue&>(key, value); | ||||
|   } | ||||
|   // | ||||
|   // bool set(TKey, TValue); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, const FlashStringHelper* | ||||
|   // TValue = char*, const char*, const FlashStringHelper* | ||||
|   template <typename TValue, typename TString> | ||||
|   bool set(const TString* key, const TValue* value) { | ||||
|     return set_impl<const TString*, const TValue*>(key, value); | ||||
|   bool set(TString* key, TValue* value) { | ||||
|     return set_impl<TString*, TValue*>(key, value); | ||||
|   } | ||||
|   // | ||||
|   // bool set(TKey, TValue, uint8_t decimals); | ||||
| @@ -134,8 +120,7 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // TValue = float, double | ||||
|   template <typename TValue, typename TString> | ||||
|   DEPRECATED("Second argument is not supported anymore") | ||||
|   typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value && | ||||
|                                     !TypeTraits::IsArray<TString>::value, | ||||
|   typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value, | ||||
|                                 bool>::type | ||||
|       set(const TString& key, TValue value, uint8_t) { | ||||
|     return set_impl<const TString&, const JsonVariant&>(key, | ||||
| @@ -143,41 +128,35 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   } | ||||
|   // | ||||
|   // bool set(TKey, TValue, uint8_t decimals); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, const FlashStringHelper* | ||||
|   // TValue = float, double | ||||
|   template <typename TValue, typename TString> | ||||
|   DEPRECATED("Second argument is not supported anymore") | ||||
|   typename TypeTraits::EnableIf<TypeTraits::IsFloatingPoint<TValue>::value, | ||||
|                                 bool>::type | ||||
|       set(const TString* key, TValue value, uint8_t) { | ||||
|     return set_impl<const TString*, const JsonVariant&>(key, | ||||
|                                                         JsonVariant(value)); | ||||
|       set(TString* key, TValue value, uint8_t) { | ||||
|     return set_impl<TString*, const JsonVariant&>(key, JsonVariant(value)); | ||||
|   } | ||||
|  | ||||
|   // Gets the value associated with the specified key. | ||||
|   // | ||||
|   // TValue get<TValue>(TKey); | ||||
|   // TValue get<TValue>(TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue, typename TString> | ||||
|   typename TypeTraits::EnableIf< | ||||
|       !TypeTraits::IsArray<TString>::value, | ||||
|       typename Internals::JsonVariantAs<TValue>::type>::type | ||||
|   get(const TString& key) const { | ||||
|   typename Internals::JsonVariantAs<TValue>::type get( | ||||
|       const TString& key) const { | ||||
|     return get_impl<const TString&, TValue>(key); | ||||
|   } | ||||
|   // | ||||
|   // TValue get<TValue>(TKey); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue get<TValue>(TKey) const; | ||||
|   // TKey = char*, const char*, const FlashStringHelper* | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue, typename TString> | ||||
|   typename Internals::JsonVariantAs<TValue>::type get( | ||||
|       const TString* key) const { | ||||
|     return get_impl<const TString*, TValue>(key); | ||||
|   typename Internals::JsonVariantAs<TValue>::type get(TString* key) const { | ||||
|     return get_impl<TString*, TValue>(key); | ||||
|   } | ||||
|  | ||||
|   // Checks the type of the value associated with the specified key. | ||||
| @@ -186,23 +165,19 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // bool is<TValue>(TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue, typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value, | ||||
|                                 bool>::type | ||||
|   is(const TString& key) const { | ||||
|   bool is(const TString& key) const { | ||||
|     return is_impl<const TString&, TValue>(key); | ||||
|   } | ||||
|   // | ||||
|   // bool is<TValue>(TKey) const; | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, const FlashStringHelper* | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue, typename TString> | ||||
|   bool is(const TString* key) const { | ||||
|     return is_impl<const TString*, TValue>(key); | ||||
|   bool is(TString* key) const { | ||||
|     return is_impl<TString*, TValue>(key); | ||||
|   } | ||||
|  | ||||
|   // Creates and adds a JsonArray. | ||||
| @@ -210,16 +185,14 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // JsonArray& createNestedArray(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value, | ||||
|                                 JsonArray&>::type | ||||
|   createNestedArray(const TString& key) { | ||||
|   JsonArray& createNestedArray(const TString& key) { | ||||
|     return createNestedArray_impl<const TString&>(key); | ||||
|   } | ||||
|   // JsonArray& createNestedArray(TKey); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, char[], const char[], const FlashStringHelper* | ||||
|   template <typename TString> | ||||
|   JsonArray& createNestedArray(const TString* key) { | ||||
|     return createNestedArray_impl<const TString*>(key); | ||||
|   JsonArray& createNestedArray(TString* key) { | ||||
|     return createNestedArray_impl<TString*>(key); | ||||
|   } | ||||
|  | ||||
|   // Creates and adds a JsonObject. | ||||
| @@ -227,17 +200,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // JsonObject& createNestedObject(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value, | ||||
|                                 JsonObject&>::type | ||||
|   createNestedObject(const TString& key) { | ||||
|   JsonObject& createNestedObject(const TString& key) { | ||||
|     return createNestedObject_impl<const TString&>(key); | ||||
|   } | ||||
|   // | ||||
|   // JsonObject& createNestedObject(TKey); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, char[], const char[], const FlashStringHelper* | ||||
|   template <typename TString> | ||||
|   JsonObject& createNestedObject(const TString* key) { | ||||
|     return createNestedObject_impl<const TString*>(key); | ||||
|   JsonObject& createNestedObject(TString* key) { | ||||
|     return createNestedObject_impl<TString*>(key); | ||||
|   } | ||||
|  | ||||
|   // Tells weither the specified key is present and associated with a value. | ||||
| @@ -245,17 +216,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // bool containsKey(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value, | ||||
|                                 bool>::type | ||||
|   containsKey(const TString& key) const { | ||||
|   bool containsKey(const TString& key) const { | ||||
|     return findKey<const TString&>(key) != end(); | ||||
|   } | ||||
|   // | ||||
|   // bool containsKey(TKey); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, char[], const char[], const FlashStringHelper* | ||||
|   template <typename TString> | ||||
|   bool containsKey(const TString* key) const { | ||||
|     return findKey<const TString*>(key) != end(); | ||||
|   bool containsKey(TString* key) const { | ||||
|     return findKey<TString*>(key) != end(); | ||||
|   } | ||||
|  | ||||
|   // Removes the specified key and the associated value. | ||||
| @@ -263,17 +232,15 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|   // void remove(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TString> | ||||
|   typename TypeTraits::EnableIf<!TypeTraits::IsArray<TString>::value, | ||||
|                                 void>::type | ||||
|   remove(const TString& key) { | ||||
|   void remove(const TString& key) { | ||||
|     remove(findKey<const TString&>(key)); | ||||
|   } | ||||
|   // | ||||
|   // void remove(TKey); | ||||
|   // TKey = const char*, const char[N], const FlashStringHelper* | ||||
|   // TKey = char*, const char*, char[], const char[], const FlashStringHelper* | ||||
|   template <typename TString> | ||||
|   void remove(const TString* key) { | ||||
|     remove(findKey<const TString*>(key)); | ||||
|   void remove(TString* key) { | ||||
|     remove(findKey<TString*>(key)); | ||||
|   } | ||||
|   // | ||||
|   // void remove(iterator) | ||||
| @@ -318,10 +285,10 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|       if (it == end()) return false; | ||||
|  | ||||
|       bool key_ok = | ||||
|           Internals::ValueSetter<TStringRef>::set(_buffer, it->key, key); | ||||
|           Internals::ValueSaver<TStringRef>::save(_buffer, it->key, key); | ||||
|       if (!key_ok) return false; | ||||
|     } | ||||
|     return Internals::ValueSetter<TValueRef>::set(_buffer, it->value, value); | ||||
|     return Internals::ValueSaver<TValueRef>::save(_buffer, it->value, value); | ||||
|   } | ||||
|  | ||||
|   template <typename TStringRef, typename TValue> | ||||
|   | ||||
| @@ -31,10 +31,9 @@ class JsonObjectSubscript | ||||
|  | ||||
|   // Set the specified value | ||||
|   // | ||||
|   // operator=(TValue); | ||||
|   // operator=(const TValue&); | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE | ||||
|       typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value, | ||||
| @@ -45,7 +44,7 @@ class JsonObjectSubscript | ||||
|   } | ||||
|   // | ||||
|   // operator=(TValue); | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = char*, const char*, const FlashStringHelper* | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE this_type& operator=(const TValue* src) { | ||||
|     _object.set(_key, src); | ||||
| @@ -68,10 +67,9 @@ class JsonObjectSubscript | ||||
|  | ||||
|   // Sets the specified value. | ||||
|   // | ||||
|   // bool set(TValue); | ||||
|   // bool set(const TValue&); | ||||
|   // TValue = bool, char, long, int, short, float, double, RawJson, JsonVariant, | ||||
|   //          const std::string&, const String&, | ||||
|   //          const JsonArray&, const JsonObject& | ||||
|   //          std::string, String, JsonArray, JsonObject | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE | ||||
|       typename TypeTraits::EnableIf<!TypeTraits::IsArray<TValue>::value, | ||||
| @@ -81,7 +79,7 @@ class JsonObjectSubscript | ||||
|   } | ||||
|   // | ||||
|   // bool set(TValue); | ||||
|   // TValue = const char*, const char[N], const FlashStringHelper* | ||||
|   // TValue = char*, const char, const FlashStringHelper* | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE bool set(const TValue* value) { | ||||
|     return _object.set(_key, value); | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
|  | ||||
| #ifdef _MSC_VER  // Visual Studio | ||||
|  | ||||
| #define FORCE_INLINE __forceinline | ||||
| #define FORCE_INLINE  // __forceinline causes C4714 when returning std::string | ||||
| #define NO_INLINE __declspec(noinline) | ||||
| #define DEPRECATED(msg) __declspec(deprecated(msg)) | ||||
|  | ||||
|   | ||||
| @@ -33,6 +33,7 @@ struct CharPointerTraits { | ||||
|     return strcmp(reinterpret_cast<const char*>(str), expected) == 0; | ||||
|   } | ||||
|  | ||||
|   // TODO: remove | ||||
|   template <typename Buffer> | ||||
|   static char* duplicate(const TChar* str, Buffer* buffer) { | ||||
|     if (!str) return NULL; | ||||
| @@ -44,12 +45,46 @@ struct CharPointerTraits { | ||||
|  | ||||
|   static const bool has_append = false; | ||||
|   static const bool has_equals = true; | ||||
|   static const bool should_duplicate = false; | ||||
| }; | ||||
|  | ||||
| // const char*, const unsigned char*, const signed char* | ||||
| template <typename TChar> | ||||
| struct StringTraits<TChar*, typename TypeTraits::EnableIf< | ||||
|                                 TypeTraits::IsChar<TChar>::value>::type> | ||||
|     : CharPointerTraits<TChar> {}; | ||||
|                                 TypeTraits::IsChar<TChar>::value && | ||||
|                                 TypeTraits::IsConst<TChar>::value>::type> | ||||
|     : CharPointerTraits<TChar> { | ||||
|   // Just save the pointer | ||||
|   template <typename Buffer, typename Destination> | ||||
|   static typename TypeTraits::EnableIf<TypeTraits::IsConst<TChar>::value, | ||||
|                                        bool>::type | ||||
|   save(const TChar* source, Destination& dest, Buffer*) { | ||||
|     dest = reinterpret_cast<const char*>(source); | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
|  | ||||
| // char*, unsigned char*, signed char* | ||||
| template <typename TChar> | ||||
| struct StringTraits<TChar*, typename TypeTraits::EnableIf< | ||||
|                                 TypeTraits::IsChar<TChar>::value && | ||||
|                                 !TypeTraits::IsConst<TChar>::value>::type> | ||||
|     : CharPointerTraits<TChar> { | ||||
|   // Make a copy of the string | ||||
|   template <typename Buffer, typename Destination> | ||||
|   static typename TypeTraits::EnableIf<!TypeTraits::IsConst<TChar>::value, | ||||
|                                        bool>::type | ||||
|   save(const TChar* source, Destination& dest, Buffer* buffer) { | ||||
|     if (source) { | ||||
|       size_t size = strlen(reinterpret_cast<const char*>(source)) + 1; | ||||
|       void* dup = buffer->alloc(size); | ||||
|       if (!dup) return false; | ||||
|       memcpy(dup, source, size); | ||||
|       dest = reinterpret_cast<const char*>(dup); | ||||
|     } else { | ||||
|       dest = reinterpret_cast<const char*>(source); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
| }; | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -34,6 +34,7 @@ struct StringTraits<const __FlashStringHelper*, void> { | ||||
|     return strcmp_P(expected, (const char*)str) == 0; | ||||
|   } | ||||
|  | ||||
|   // TODO: remove | ||||
|   template <typename Buffer> | ||||
|   static char* duplicate(const __FlashStringHelper* str, Buffer* buffer) { | ||||
|     if (!str) return NULL; | ||||
| @@ -43,9 +44,22 @@ struct StringTraits<const __FlashStringHelper*, void> { | ||||
|     return static_cast<char*>(dup); | ||||
|   } | ||||
|  | ||||
|   template <typename Buffer, typename Destination> | ||||
|   static bool save(const __FlashStringHelper* source, Destination& dest, | ||||
|                    Buffer* buffer) { | ||||
|     if (source) { | ||||
|       size_t size = strlen_P((const char*)source) + 1; | ||||
|       void* dup = buffer->alloc(size); | ||||
|       if (dup != NULL) memcpy_P(dup, (const char*)source, size); | ||||
|       dest = reinterpret_cast<const char*>(dup); | ||||
|     } else { | ||||
|       dest = reinterpret_cast<const char*>(source); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   static const bool has_append = false; | ||||
|   static const bool has_equals = true; | ||||
|   static const bool should_duplicate = true; | ||||
| }; | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -19,6 +19,7 @@ namespace Internals { | ||||
|  | ||||
| template <typename TString> | ||||
| struct StdStringTraits { | ||||
|   // TODO: remove | ||||
|   template <typename Buffer> | ||||
|   static char* duplicate(const TString& str, Buffer* buffer) { | ||||
|     if (!str.c_str()) return NULL;  // <- Arduino string can return NULL | ||||
| @@ -28,6 +29,21 @@ struct StdStringTraits { | ||||
|     return static_cast<char*>(dup); | ||||
|   } | ||||
|  | ||||
|   template <typename Buffer, typename Destination> | ||||
|   static bool save(const TString& str, Destination& dest, Buffer* buffer) { | ||||
|     // Arduino's String::c_str() can return NULL | ||||
|     if (str.c_str()) { | ||||
|       size_t size = str.length() + 1; | ||||
|       void* dup = buffer->alloc(size); | ||||
|       if (!dup) return false; | ||||
|       memcpy(dup, str.c_str(), size); | ||||
|       dest = reinterpret_cast<const char*>(dup); | ||||
|     } else { | ||||
|       dest = str.c_str(); | ||||
|     } | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   struct Reader : CharPointerTraits<char>::Reader { | ||||
|     Reader(const TString& str) : CharPointerTraits<char>::Reader(str.c_str()) {} | ||||
|   }; | ||||
| @@ -46,7 +62,6 @@ struct StdStringTraits { | ||||
|  | ||||
|   static const bool has_append = true; | ||||
|   static const bool has_equals = true; | ||||
|   static const bool should_duplicate = true; | ||||
| }; | ||||
|  | ||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STRING | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| #include "../TypeTraits/EnableIf.hpp" | ||||
| #include "../TypeTraits/IsBaseOf.hpp" | ||||
| #include "../TypeTraits/IsChar.hpp" | ||||
| #include "../TypeTraits/IsConst.hpp" | ||||
| #include "../TypeTraits/RemoveReference.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|   | ||||
| @@ -13,6 +13,7 @@ add_executable(JsonArrayTests | ||||
| 	printTo.cpp | ||||
| 	remove.cpp | ||||
| 	set.cpp | ||||
| 	size.cpp | ||||
| 	subscript.cpp | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -9,11 +9,6 @@ TEST_CASE("JsonArray::add()") { | ||||
|   DynamicJsonBuffer _jsonBuffer; | ||||
|   JsonArray& _array = _jsonBuffer.createArray(); | ||||
|  | ||||
|   SECTION("SizeIncreased_WhenValuesAreAdded") { | ||||
|     _array.add("hello"); | ||||
|     REQUIRE(1U == _array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _array.add(123); | ||||
|     REQUIRE(123 == _array[0].as<int>()); | ||||
| @@ -38,7 +33,7 @@ TEST_CASE("JsonArray::add()") { | ||||
|   SECTION("const char*") { | ||||
|     const char* str = "hello"; | ||||
|     _array.add(str); | ||||
|     REQUIRE(str == _array[0].as<const char*>()); | ||||
|     REQUIRE(str == _array[0].as<std::string>()); | ||||
|     REQUIRE(_array[0].is<const char*>()); | ||||
|     REQUIRE_FALSE(_array[0].is<int>()); | ||||
|   } | ||||
| @@ -82,4 +77,22 @@ TEST_CASE("JsonArray::add()") { | ||||
|  | ||||
|     REQUIRE(str == _array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array.add("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate  char*") { | ||||
|     _array.add(const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array.add(std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -12,11 +12,6 @@ TEST_CASE("JsonArray::set()") { | ||||
|   JsonArray& _array = _jsonBuffer.createArray(); | ||||
|   _array.add(0); | ||||
|  | ||||
|   SECTION("SizeIsUnchanged") { | ||||
|     _array.set(0, "hello"); | ||||
|     REQUIRE(1U == _array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _array.set(0, 123); | ||||
|     REQUIRE(123 == _array[0].as<int>()); | ||||
| @@ -82,4 +77,22 @@ TEST_CASE("JsonArray::set()") { | ||||
|  | ||||
|     REQUIRE_THAT(_array[0].as<char*>(), Equals("hello")); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array.set(0, "world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array.set(0, const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array.set(0, std::string("world")); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										35
									
								
								test/JsonArray/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								test/JsonArray/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
|  | ||||
| TEST_CASE("JsonArray::size()") { | ||||
|   DynamicJsonBuffer _jsonBuffer; | ||||
|   JsonArray& _array = _jsonBuffer.createArray(); | ||||
|  | ||||
|   SECTION("increases after add()") { | ||||
|     _array.add("hello"); | ||||
|     REQUIRE(1U == _array.size()); | ||||
|  | ||||
|     _array.add("world"); | ||||
|     REQUIRE(2U == _array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("remains the same after set()") { | ||||
|     _array.add("hello"); | ||||
|     REQUIRE(1U == _array.size()); | ||||
|  | ||||
|     _array.set(0, "hello"); | ||||
|     REQUIRE(1U == _array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("remains the same after assigment") { | ||||
|     _array.add("hello"); | ||||
|     REQUIRE(1U == _array.size()); | ||||
|  | ||||
|     _array[0] = "hello"; | ||||
|     REQUIRE(1U == _array.size()); | ||||
|   } | ||||
| } | ||||
| @@ -11,11 +11,6 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|   JsonArray& _array = _jsonBuffer.createArray(); | ||||
|   _array.add(0); | ||||
|  | ||||
|   SECTION("SizeIsUnchanged") { | ||||
|     _array[0] = "hello"; | ||||
|     REQUIRE(1U == _array.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _array[0] = 123; | ||||
|     REQUIRE(123 == _array[0].as<int>()); | ||||
| @@ -103,4 +98,22 @@ TEST_CASE("JsonArray::operator[]") { | ||||
|  | ||||
|     REQUIRE(str == _array[0]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _array[0] = "world"; | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1); | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char*") { | ||||
|     _array[0] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string") { | ||||
|     _array[0] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_ARRAY_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -12,6 +12,7 @@ add_executable(JsonObjectTests | ||||
| 	printTo.cpp | ||||
| 	remove.cpp | ||||
| 	set.cpp | ||||
| 	size.cpp | ||||
| 	subscript.cpp | ||||
| ) | ||||
|  | ||||
|   | ||||
| @@ -10,17 +10,6 @@ TEST_CASE("JsonObject::set()") { | ||||
|   DynamicJsonBuffer jb; | ||||
|   JsonObject& _object = jb.createObject(); | ||||
|  | ||||
|   SECTION("SizeIncreased_WhenValuesAreAdded") { | ||||
|     _object.set("hello", 42); | ||||
|     REQUIRE(1 == _object.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("SizeUntouched_WhenSameValueIsAdded") { | ||||
|     _object["hello"] = 1; | ||||
|     _object["hello"] = 2; | ||||
|     REQUIRE(1 == _object.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _object.set("hello", 123); | ||||
|  | ||||
| @@ -91,17 +80,59 @@ TEST_CASE("JsonObject::set()") { | ||||
|     REQUIRE(42 == _object["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("ShouldReturnTrue_WhenAllocationSucceeds") { | ||||
|   SECTION("returns true when allocation succeeds") { | ||||
|     StaticJsonBuffer<JSON_OBJECT_SIZE(1) + 15> jsonBuffer; | ||||
|     JsonObject& obj = jsonBuffer.createObject(); | ||||
|  | ||||
|     REQUIRE(true == obj.set(std::string("hello"), std::string("world"))); | ||||
|   } | ||||
|  | ||||
|   SECTION("ShouldReturnFalse_WhenAllocationFails") { | ||||
|   SECTION("returns false when allocation fails") { | ||||
|     StaticJsonBuffer<JSON_OBJECT_SIZE(1) + 10> jsonBuffer; | ||||
|     JsonObject& obj = jsonBuffer.createObject(); | ||||
|  | ||||
|     REQUIRE(false == obj.set(std::string("hello"), std::string("world"))); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _object.set("hello", "world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1); | ||||
|     REQUIRE(expectedSize == jb.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* value") { | ||||
|     _object.set("hello", const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == jb.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key") { | ||||
|     _object.set(const_cast<char*>("hello"), "world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == jb.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key&value") { | ||||
|     _object.set(const_cast<char*>("hello"), const_cast<char*>("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= jb.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string value") { | ||||
|     _object.set("hello", std::string("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == jb.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key") { | ||||
|     _object.set(std::string("hello"), "world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == jb.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key&value") { | ||||
|     _object.set(std::string("hello"), std::string("world")); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= jb.size()); | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										23
									
								
								test/JsonObject/size.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								test/JsonObject/size.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| // ArduinoJson - arduinojson.org | ||||
| // Copyright Benoit Blanchon 2014-2018 | ||||
| // MIT License | ||||
|  | ||||
| #include <ArduinoJson.h> | ||||
| #include <catch.hpp> | ||||
| #include <string> | ||||
|  | ||||
| TEST_CASE("JsonObject::size()") { | ||||
|   DynamicJsonBuffer jb; | ||||
|   JsonObject& _object = jb.createObject(); | ||||
|  | ||||
|   SECTION("increases when values are added") { | ||||
|     _object.set("hello", 42); | ||||
|     REQUIRE(1 == _object.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("doesn't increase when the smae key is added twice") { | ||||
|     _object["hello"] = 1; | ||||
|     _object["hello"] = 2; | ||||
|     REQUIRE(1 == _object.size()); | ||||
|   } | ||||
| } | ||||
| @@ -9,17 +9,6 @@ TEST_CASE("JsonObject::operator[]") { | ||||
|   DynamicJsonBuffer _jsonBuffer; | ||||
|   JsonObject& _object = _jsonBuffer.createObject(); | ||||
|  | ||||
|   SECTION("SizeIncreased_WhenValuesAreAdded") { | ||||
|     _object["hello"] = 1; | ||||
|     REQUIRE(1 == _object.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("SizeUntouched_WhenSameValueIsAdded") { | ||||
|     _object["hello"] = 1; | ||||
|     _object["hello"] = 2; | ||||
|     REQUIRE(1 == _object.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("int") { | ||||
|     _object["hello"] = 123; | ||||
|  | ||||
| @@ -113,9 +102,51 @@ TEST_CASE("JsonObject::operator[]") { | ||||
|     REQUIRE(42 == _object["a"]); | ||||
|   } | ||||
|  | ||||
|   SECTION("KeyAsCharArray") {  // issue #423 | ||||
|   SECTION("char key[]") {  // issue #423 | ||||
|     char key[] = "hello"; | ||||
|     _object[key] = 42; | ||||
|     REQUIRE(42 == _object[key]); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate const char*") { | ||||
|     _object["hello"] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1); | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* value") { | ||||
|     _object["hello"] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key") { | ||||
|     _object[const_cast<char*>("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate char* key&value") { | ||||
|     _object[const_cast<char*>("hello")] = const_cast<char*>("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string value") { | ||||
|     _object["hello"] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key") { | ||||
|     _object[std::string("hello")] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 6; | ||||
|     REQUIRE(expectedSize == _jsonBuffer.size()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate std::string key&value") { | ||||
|     _object[std::string("hello")] = std::string("world"); | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + 12; | ||||
|     REQUIRE(expectedSize <= _jsonBuffer.size()); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -36,4 +36,9 @@ TEST_CASE("TypeTraits") { | ||||
|     REQUIRE((IsString<std::string>::value)); | ||||
|     REQUIRE_FALSE((IsString<double>::value)); | ||||
|   } | ||||
|  | ||||
|   SECTION("IsConst") { | ||||
|     REQUIRE_FALSE((IsConst<char>::value)); | ||||
|     REQUIRE((IsConst<const char>::value)); | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user