mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	| @@ -4,9 +4,11 @@ ArduinoJson: change log | ||||
| v5.0 (currently in beta) | ||||
| ---- | ||||
|  | ||||
| * Added support of `String` class (issue #55, #56, #70, #77) | ||||
| * Added support of `String` class (issues #55, #56, #70, #77) | ||||
| * Added `JsonBuffer::strdup()` to make a copy of a string (issues #10, #57) | ||||
| * Implicitly call `strdup()` for `String` but not for `char*` (issues #84, #87) | ||||
| * Added support of non standard JSON input (issue #44) | ||||
| * Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators | ||||
| * Redesigned `JsonVariant` to leverage converting constructors instead of assignment operators (issue #66) | ||||
| * Switched to new the library layout (requires Arduino 1.0.6 or above) | ||||
|  | ||||
| **BREAKING CHANGES**: | ||||
|   | ||||
| @@ -23,11 +23,6 @@ inline char const* JsonVariantContent::as<char const*>() const { | ||||
|   return asString; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline String JsonVariantContent::as<String>() const { | ||||
|   return asString; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline double JsonVariantContent::as<double>() const { | ||||
|   return asDouble; | ||||
|   | ||||
| @@ -42,16 +42,46 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>, | ||||
|       : Internals::List<JsonVariant>(buffer) {} | ||||
|  | ||||
|   // Gets the value at the specified index | ||||
|   FORCE_INLINE const JsonArraySubscript operator[](size_t index) const; | ||||
|   FORCE_INLINE JsonVariant operator[](size_t index) const; | ||||
|  | ||||
|   // Gets or sets the value at specified index | ||||
|   FORCE_INLINE JsonArraySubscript operator[](size_t index); | ||||
|  | ||||
|   // Adds the specified value at the end of the array. | ||||
|   FORCE_INLINE bool add(const JsonVariant value); | ||||
|   FORCE_INLINE bool add(bool value); | ||||
|   FORCE_INLINE bool add(float value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE bool add(double value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE bool add(signed char value); | ||||
|   FORCE_INLINE bool add(signed long value); | ||||
|   FORCE_INLINE bool add(signed int value); | ||||
|   FORCE_INLINE bool add(signed short value); | ||||
|   FORCE_INLINE bool add(unsigned char value); | ||||
|   FORCE_INLINE bool add(unsigned long value); | ||||
|   FORCE_INLINE bool add(unsigned int value); | ||||
|   FORCE_INLINE bool add(unsigned short value); | ||||
|   FORCE_INLINE bool add(const char *value); | ||||
|   FORCE_INLINE bool add(const String &value); | ||||
|   FORCE_INLINE bool add(JsonArray &array); | ||||
|   FORCE_INLINE bool add(JsonObject &object); | ||||
|   FORCE_INLINE bool add(const JsonVariant &object); | ||||
|  | ||||
|   // Sets the value at specified index. | ||||
|   FORCE_INLINE void set(size_t index, const JsonVariant value); | ||||
|   FORCE_INLINE void set(size_t index, bool value); | ||||
|   FORCE_INLINE void set(size_t index, float value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE void set(size_t index, double value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE void set(size_t index, signed char value); | ||||
|   FORCE_INLINE void set(size_t index, signed long value); | ||||
|   FORCE_INLINE void set(size_t index, signed int value); | ||||
|   FORCE_INLINE void set(size_t index, signed short value); | ||||
|   FORCE_INLINE void set(size_t index, unsigned char value); | ||||
|   FORCE_INLINE void set(size_t index, unsigned long value); | ||||
|   FORCE_INLINE void set(size_t index, unsigned int value); | ||||
|   FORCE_INLINE void set(size_t index, unsigned short value); | ||||
|   FORCE_INLINE void set(size_t index, const char *value); | ||||
|   FORCE_INLINE void set(size_t index, const String &value); | ||||
|   FORCE_INLINE void set(size_t index, JsonArray &array); | ||||
|   FORCE_INLINE void set(size_t index, JsonObject &object); | ||||
|   FORCE_INLINE void set(size_t index, const JsonVariant &object); | ||||
|  | ||||
|   // Gets the value at the specified index. | ||||
|   FORCE_INLINE JsonVariant get(size_t index) const; | ||||
| @@ -86,6 +116,15 @@ class JsonArray : public Internals::JsonPrintable<JsonArray>, | ||||
|  private: | ||||
|   node_type *getNodeAt(size_t index) const; | ||||
|  | ||||
|   template <typename TValue> | ||||
|   void setNodeAt(size_t index, TValue value); | ||||
|  | ||||
|   template <typename TValue> | ||||
|   bool addNode(TValue); | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE void setNodeValue(node_type *, T value); | ||||
|  | ||||
|   // The instance returned by JsonArray::invalid() | ||||
|   static JsonArray _invalid; | ||||
| }; | ||||
|   | ||||
| @@ -15,14 +15,159 @@ inline JsonArraySubscript JsonArray::operator[](size_t index) { | ||||
|   return JsonArraySubscript(*this, index); | ||||
| } | ||||
|  | ||||
| inline const JsonArraySubscript JsonArray::operator[](size_t index) const { | ||||
|   return JsonArraySubscript(*const_cast<JsonArray *>(this), index); | ||||
| inline JsonVariant JsonArray::operator[](size_t index) const { | ||||
|   return get(index); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(const JsonVariant value) { | ||||
| inline bool JsonArray::add(bool value) { return addNode<bool>(value); } | ||||
|  | ||||
| inline bool JsonArray::add(float value, uint8_t decimals) { | ||||
|   return addNode<const JsonVariant &>(JsonVariant(value, decimals)); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(double value, uint8_t decimals) { | ||||
|   return addNode<const JsonVariant &>(JsonVariant(value, decimals)); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(signed char value) { | ||||
|   return addNode<signed char>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(signed long value) { | ||||
|   return addNode<signed long>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(signed int value) { | ||||
|   return addNode<signed int>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(signed short value) { | ||||
|   return addNode<signed short>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(unsigned char value) { | ||||
|   return addNode<unsigned char>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(unsigned long value) { | ||||
|   return addNode<unsigned long>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(unsigned int value) { | ||||
|   return addNode<unsigned int>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(unsigned short value) { | ||||
|   return addNode<unsigned short>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(const char *value) { | ||||
|   return addNode<const char *>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(const String &value) { | ||||
|   return addNode<const String &>(value); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(JsonArray &array) { | ||||
|   return addNode<JsonArray &>(array); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(JsonObject &object) { | ||||
|   return addNode<JsonObject &>(object); | ||||
| } | ||||
|  | ||||
| inline bool JsonArray::add(const JsonVariant &object) { | ||||
|   return addNode<const JsonVariant &>(object); | ||||
| } | ||||
|  | ||||
| template <typename TValue> | ||||
| inline bool JsonArray::addNode(TValue value) { | ||||
|   node_type *node = addNewNode(); | ||||
|   if (node) node->content = value; | ||||
|   return node != NULL; | ||||
|   if (node == NULL) return false; | ||||
|   setNodeValue<TValue>(node, value); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, bool value) { | ||||
|   return setNodeAt<bool>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, float value, uint8_t decimals) { | ||||
|   return setNodeAt<const JsonVariant &>(index, JsonVariant(value, decimals)); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, double value, uint8_t decimals) { | ||||
|   return setNodeAt<const JsonVariant &>(index, JsonVariant(value, decimals)); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, signed char value) { | ||||
|   return setNodeAt<signed char>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, signed long value) { | ||||
|   return setNodeAt<signed long>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, signed int value) { | ||||
|   return setNodeAt<signed int>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, signed short value) { | ||||
|   return setNodeAt<signed short>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, unsigned char value) { | ||||
|   return setNodeAt<unsigned char>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, unsigned long value) { | ||||
|   return setNodeAt<unsigned long>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, unsigned int value) { | ||||
|   return setNodeAt<unsigned int>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, unsigned short value) { | ||||
|   return setNodeAt<unsigned short>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, const char *value) { | ||||
|   return setNodeAt<const char *>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, const String &value) { | ||||
|   return setNodeAt<const String &>(index, value); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, JsonArray &array) { | ||||
|   return setNodeAt<JsonArray &>(index, array); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, JsonObject &object) { | ||||
|   return setNodeAt<JsonObject &>(index, object); | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, const JsonVariant &object) { | ||||
|   return setNodeAt<const JsonVariant &>(index, object); | ||||
| } | ||||
|  | ||||
| template <typename TValue> | ||||
| inline void JsonArray::setNodeAt(size_t index, TValue value) { | ||||
|   node_type *node = getNodeAt(index); | ||||
|   if (node == NULL) return; | ||||
|   setNodeValue<TValue>(node, value); | ||||
| } | ||||
|  | ||||
| template <typename TValue> | ||||
| inline void JsonArray::setNodeValue(node_type *node, TValue value) { | ||||
|   node->content = value; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline void JsonArray::setNodeValue(node_type *node, const String &value) { | ||||
|   node->content = _buffer->strdup(value); | ||||
| } | ||||
|  | ||||
| inline JsonVariant JsonArray::get(size_t index) const { | ||||
| @@ -42,11 +187,6 @@ inline T JsonArray::is(size_t index) const { | ||||
|   return node ? node->content.is<T>() : false; | ||||
| } | ||||
|  | ||||
| inline void JsonArray::set(size_t index, const JsonVariant value) { | ||||
|   node_type *node = getNodeAt(index); | ||||
|   if (node) node->content = value; | ||||
| } | ||||
|  | ||||
| template <typename TImplem> | ||||
| inline const JsonArraySubscript JsonVariantBase<TImplem>::operator[]( | ||||
|     int index) const { | ||||
|   | ||||
| @@ -6,18 +6,15 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonVariantBase.hpp" | ||||
| #include "JsonSubscriptBase.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
| class JsonArraySubscript : public JsonSubscriptBase<JsonArraySubscript> { | ||||
|  public: | ||||
|   FORCE_INLINE JsonArraySubscript(JsonArray& array, size_t index) | ||||
|       : _array(array), _index(index) {} | ||||
|  | ||||
|   FORCE_INLINE JsonArraySubscript& operator=(const JsonVariant& value) { | ||||
|     _array.set(_index, value); | ||||
|     return *this; | ||||
|   } | ||||
|   using JsonSubscriptBase::operator=; | ||||
|  | ||||
|   FORCE_INLINE JsonArraySubscript& operator=(const JsonArraySubscript& other) { | ||||
|     // to prevent Visual Studio warning C4512: assignment operator could not be | ||||
| @@ -40,19 +37,25 @@ class JsonArraySubscript : public JsonVariantBase<JsonArraySubscript> { | ||||
|     return _array.is<T>(_index); | ||||
|   } | ||||
|  | ||||
|   void writeTo(Internals::JsonWriter &writer) const { | ||||
|   void writeTo(Internals::JsonWriter& writer) const { | ||||
|     _array.get(_index).writeTo(writer); | ||||
|   } | ||||
|  | ||||
|   template <typename TValue> | ||||
|   void set(TValue value) { | ||||
|     _array.set(_index, value); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   JsonArray& _array; | ||||
|   const size_t _index; | ||||
| }; | ||||
|  | ||||
| #ifdef ARDUINOJSON_ENABLE_STD_STREAM | ||||
| inline std::ostream& operator<<(std::ostream& os, const JsonArraySubscript& source) { | ||||
| inline std::ostream& operator<<(std::ostream& os, | ||||
|                                 const JsonArraySubscript& source) { | ||||
|   return source.printTo(os); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| } // namespace ArduinoJson | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -8,8 +8,10 @@ | ||||
|  | ||||
| #include <stddef.h>  // for size_t | ||||
| #include <stdint.h>  // for uint8_t | ||||
| #include <string.h> | ||||
|  | ||||
| #include "Arduino/String.hpp" | ||||
| #include "JsonVariant.hpp" | ||||
|  | ||||
| #if defined(__clang__) | ||||
| #pragma clang diagnostic ignored "-Wnon-virtual-dtor" | ||||
| @@ -59,7 +61,7 @@ class JsonBuffer { | ||||
|  | ||||
|   // Same as above with a String class | ||||
|   JsonArray &parseArray(const String &json, uint8_t nesting = DEFAULT_LIMIT) { | ||||
|     return parseArray(const_cast<char *>(json.c_str()), nesting); | ||||
|     return parseArray(strdup(json), nesting); | ||||
|   } | ||||
|  | ||||
|   // Allocates and populate a JsonObject from a JSON string. | ||||
| @@ -75,11 +77,15 @@ class JsonBuffer { | ||||
|   JsonObject &parseObject(char *json, uint8_t nestingLimit = DEFAULT_LIMIT); | ||||
|  | ||||
|   // Same as above with a String class | ||||
|   JsonObject &parseObject(const String &json, | ||||
|                           uint8_t nestingLimit = DEFAULT_LIMIT) { | ||||
|     return parseObject(const_cast<char *>(json.c_str()), nestingLimit); | ||||
|   JsonObject &parseObject(const String &json, uint8_t nesting = DEFAULT_LIMIT) { | ||||
|     return parseObject(strdup(json), nesting); | ||||
|   } | ||||
|  | ||||
|   // Duplicate a string | ||||
|   char *strdup(const char *src) { return strdup(src, strlen(src)); } | ||||
|   char *strdup(const String &src) { return strdup(src.c_str(), src.length()); } | ||||
|   char *strdup(const char *, size_t); | ||||
|  | ||||
|   // Allocates n bytes in the JsonBuffer. | ||||
|   // Return a pointer to the allocated memory or NULL if allocation fails. | ||||
|   virtual void *alloc(size_t size) = 0; | ||||
|   | ||||
| @@ -23,7 +23,6 @@ namespace ArduinoJson { | ||||
| // Forward declarations | ||||
| class JsonArray; | ||||
| class JsonBuffer; | ||||
| class JsonObjectSubscript; | ||||
|  | ||||
| // A dictionary of JsonVariant indexed by string (char*) | ||||
| // | ||||
| @@ -43,13 +42,45 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|       : Internals::List<JsonPair>(buffer) {} | ||||
|  | ||||
|   // Gets or sets the value associated with the specified key. | ||||
|   FORCE_INLINE JsonObjectSubscript operator[](JsonObjectKey key); | ||||
|   FORCE_INLINE JsonObjectSubscript<const char*> operator[](const char* key); | ||||
|   FORCE_INLINE JsonObjectSubscript<const String&> operator[](const String& key); | ||||
|  | ||||
|   // Gets the value associated with the specified key. | ||||
|   FORCE_INLINE const JsonObjectSubscript operator[](JsonObjectKey key) const; | ||||
|   FORCE_INLINE JsonVariant operator[](JsonObjectKey key) const; | ||||
|  | ||||
|   // Sets the specified key with the specified value. | ||||
|   FORCE_INLINE bool set(JsonObjectKey key, JsonVariant value); | ||||
|   FORCE_INLINE bool set(const char* key, bool value); | ||||
|   FORCE_INLINE bool set(const char* key, float value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE bool set(const char* key, double value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE bool set(const char* key, signed char value); | ||||
|   FORCE_INLINE bool set(const char* key, signed long value); | ||||
|   FORCE_INLINE bool set(const char* key, signed int value); | ||||
|   FORCE_INLINE bool set(const char* key, signed short value); | ||||
|   FORCE_INLINE bool set(const char* key, unsigned char value); | ||||
|   FORCE_INLINE bool set(const char* key, unsigned long value); | ||||
|   FORCE_INLINE bool set(const char* key, unsigned int value); | ||||
|   FORCE_INLINE bool set(const char* key, unsigned short value); | ||||
|   FORCE_INLINE bool set(const char* key, const char* value); | ||||
|   FORCE_INLINE bool set(const char* key, const String& value); | ||||
|   FORCE_INLINE bool set(const char* key, JsonArray& array); | ||||
|   FORCE_INLINE bool set(const char* key, JsonObject& object); | ||||
|   FORCE_INLINE bool set(const char* key, const JsonVariant& value); | ||||
|   FORCE_INLINE bool set(const String& key, bool value); | ||||
|   FORCE_INLINE bool set(const String& key, float value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE bool set(const String& key, double value, uint8_t decimals = 2); | ||||
|   FORCE_INLINE bool set(const String& key, signed char value); | ||||
|   FORCE_INLINE bool set(const String& key, signed long value); | ||||
|   FORCE_INLINE bool set(const String& key, signed int value); | ||||
|   FORCE_INLINE bool set(const String& key, signed short value); | ||||
|   FORCE_INLINE bool set(const String& key, unsigned char value); | ||||
|   FORCE_INLINE bool set(const String& key, unsigned long value); | ||||
|   FORCE_INLINE bool set(const String& key, unsigned int value); | ||||
|   FORCE_INLINE bool set(const String& key, unsigned short value); | ||||
|   FORCE_INLINE bool set(const String& key, const char* value); | ||||
|   FORCE_INLINE bool set(const String& key, const String& value); | ||||
|   FORCE_INLINE bool set(const String& key, JsonArray& array); | ||||
|   FORCE_INLINE bool set(const String& key, JsonObject& object); | ||||
|   FORCE_INLINE bool set(const String& key, const JsonVariant& value); | ||||
|  | ||||
|   // Gets the value associated with the specified key. | ||||
|   FORCE_INLINE JsonVariant get(JsonObjectKey) const; | ||||
| @@ -64,11 +95,13 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|  | ||||
|   // Creates and adds a JsonArray. | ||||
|   // This is a shortcut for JsonBuffer::createArray() and JsonObject::add(). | ||||
|   JsonArray& createNestedArray(JsonObjectKey key); | ||||
|   FORCE_INLINE JsonArray& createNestedArray(const char* key); | ||||
|   FORCE_INLINE JsonArray& createNestedArray(const String& key); | ||||
|  | ||||
|   // Creates and adds a JsonObject. | ||||
|   // This is a shortcut for JsonBuffer::createObject() and JsonObject::add(). | ||||
|   JsonObject& createNestedObject(JsonObjectKey key); | ||||
|   FORCE_INLINE JsonObject& createNestedObject(const char* key); | ||||
|   FORCE_INLINE JsonObject& createNestedObject(const String& key); | ||||
|  | ||||
|   // Tells weither the specified key is present and associated with a value. | ||||
|   FORCE_INLINE bool containsKey(JsonObjectKey key) const; | ||||
| @@ -90,6 +123,21 @@ class JsonObject : public Internals::JsonPrintable<JsonObject>, | ||||
|  | ||||
|   node_type* getOrCreateNodeAt(JsonObjectKey key); | ||||
|  | ||||
|   template <typename TKey, typename TValue> | ||||
|   FORCE_INLINE bool setNodeAt(TKey key, TValue value); | ||||
|  | ||||
|   template <typename TKey> | ||||
|   JsonArray& createArrayAt(TKey key); | ||||
|  | ||||
|   template <typename TKey> | ||||
|   JsonObject& createObjectAt(TKey key); | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE void setNodeKey(node_type*, T key); | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE void setNodeValue(node_type*, T value); | ||||
|  | ||||
|   // The instance returned by JsonObject::invalid() | ||||
|   static JsonObject _invalid; | ||||
| }; | ||||
|   | ||||
| @@ -28,41 +28,183 @@ inline bool JsonObject::is(JsonObjectKey key) const { | ||||
|   return node ? node->content.value.is<T>() : false; | ||||
| } | ||||
|  | ||||
| inline JsonObjectSubscript JsonObject::operator[](JsonObjectKey key) { | ||||
|   return JsonObjectSubscript(*this, key); | ||||
| inline JsonObjectSubscript<const char *> JsonObject::operator[]( | ||||
|     const char *key) { | ||||
|   return JsonObjectSubscript<const char *>(*this, key); | ||||
| } | ||||
|  | ||||
| inline const JsonObjectSubscript JsonObject::operator[]( | ||||
|     JsonObjectKey key) const { | ||||
|   return JsonObjectSubscript(*const_cast<JsonObject *>(this), key); | ||||
| inline JsonObjectSubscript<const String &> JsonObject::operator[]( | ||||
|     const String &key) { | ||||
|   return JsonObjectSubscript<const String &>(*this, key); | ||||
| } | ||||
|  | ||||
| inline JsonVariant JsonObject::operator[](JsonObjectKey key) const { | ||||
|   return get(key); | ||||
| } | ||||
|  | ||||
| inline bool JsonObject::containsKey(JsonObjectKey key) const { | ||||
|   return getNodeAt(key) != NULL; | ||||
| } | ||||
|  | ||||
| inline JsonArray &JsonObject::createNestedArray(const char *key) { | ||||
|   return createArrayAt<const char *>(key); | ||||
| } | ||||
|  | ||||
| inline JsonArray &JsonObject::createNestedArray(const String &key) { | ||||
|   return createArrayAt<const String &>(key); | ||||
| } | ||||
|  | ||||
| inline JsonObject &JsonObject::createNestedObject(const char *key) { | ||||
|   return createObjectAt<const char *>(key); | ||||
| } | ||||
|  | ||||
| inline JsonObject &JsonObject::createNestedObject(const String &key) { | ||||
|   return createObjectAt<const String &>(key); | ||||
| } | ||||
|  | ||||
| inline void JsonObject::remove(JsonObjectKey key) { | ||||
|   removeNode(getNodeAt(key)); | ||||
| } | ||||
|  | ||||
| inline bool JsonObject::set(JsonObjectKey key, const JsonVariant value) { | ||||
| inline bool JsonObject::set(const char *key, bool value) { | ||||
|   return setNodeAt<const char *, bool>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, float value, uint8_t decimals) { | ||||
|   return setNodeAt<const char *, const JsonVariant &>( | ||||
|       key, JsonVariant(value, decimals)); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, double value, uint8_t decimals) { | ||||
|   return setNodeAt<const char *, const JsonVariant &>( | ||||
|       key, JsonVariant(value, decimals)); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, signed char value) { | ||||
|   return setNodeAt<const char *, signed char>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, signed long value) { | ||||
|   return setNodeAt<const char *, signed long>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, signed int value) { | ||||
|   return setNodeAt<const char *, signed int>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, signed short value) { | ||||
|   return setNodeAt<const char *, signed short>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, unsigned char value) { | ||||
|   return setNodeAt<const char *, unsigned char>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, unsigned long value) { | ||||
|   return setNodeAt<const char *, unsigned long>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, unsigned int value) { | ||||
|   return setNodeAt<const char *, unsigned int>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, unsigned short value) { | ||||
|   return setNodeAt<const char *, unsigned short>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, const char *value) { | ||||
|   return setNodeAt<const char *, const char *>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, const String &value) { | ||||
|   return setNodeAt<const char *, const String &>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, JsonArray &array) { | ||||
|   return setNodeAt<const char *, JsonArray &>(key, array); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, JsonObject &object) { | ||||
|   return setNodeAt<const char *, JsonObject &>(key, object); | ||||
| } | ||||
| inline bool JsonObject::set(const char *key, const JsonVariant &value) { | ||||
|   return setNodeAt<const char *, const JsonVariant &>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, bool value) { | ||||
|   return setNodeAt<const String &, bool>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, float value, uint8_t decimals) { | ||||
|   return setNodeAt<const String &, const JsonVariant &>( | ||||
|       key, JsonVariant(value, decimals)); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, double value, uint8_t decimals) { | ||||
|   return setNodeAt<const String &, const JsonVariant &>( | ||||
|       key, JsonVariant(value, decimals)); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, signed char value) { | ||||
|   return setNodeAt<const String &, signed char>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, signed long value) { | ||||
|   return setNodeAt<const String &, signed long>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, signed int value) { | ||||
|   return setNodeAt<const String &, signed int>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, signed short value) { | ||||
|   return setNodeAt<const String &, signed short>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, unsigned char value) { | ||||
|   return setNodeAt<const String &, unsigned char>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, unsigned long value) { | ||||
|   return setNodeAt<const String &, unsigned long>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, unsigned int value) { | ||||
|   return setNodeAt<const String &, unsigned int>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, unsigned short value) { | ||||
|   return setNodeAt<const String &, unsigned short>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, const char *value) { | ||||
|   return setNodeAt<const String &, const char *>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, const String &value) { | ||||
|   return setNodeAt<const String &, const String &>(key, value); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, JsonArray &array) { | ||||
|   return setNodeAt<const String &, JsonArray &>(key, array); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, JsonObject &object) { | ||||
|   return setNodeAt<const String &, JsonObject &>(key, object); | ||||
| } | ||||
| inline bool JsonObject::set(const String &key, const JsonVariant &value) { | ||||
|   return setNodeAt<const String &, const JsonVariant &>(key, value); | ||||
| } | ||||
|  | ||||
| template <typename TKey, typename TValue> | ||||
| inline bool JsonObject::setNodeAt(TKey key, TValue value) { | ||||
|   node_type *node = getOrCreateNodeAt(key); | ||||
|   if (!node) return false; | ||||
|  | ||||
|   node->content.key = key; | ||||
|   node->content.value = value; | ||||
|   setNodeKey<TKey>(node, key); | ||||
|   setNodeValue<TValue>(node, value); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline void JsonObject::setNodeKey(node_type *node, const char *key) { | ||||
|   node->content.key = key; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline void JsonObject::setNodeKey(node_type *node, const String &key) { | ||||
|   node->content.key = _buffer->strdup(key); | ||||
| } | ||||
|  | ||||
| template <typename TValue> | ||||
| inline void JsonObject::setNodeValue(node_type *node, TValue value) { | ||||
|   node->content.value = value; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline void JsonObject::setNodeValue(node_type *node, const String &value) { | ||||
|   node->content.value = _buffer->strdup(value); | ||||
| } | ||||
|  | ||||
| template <typename TImplem> | ||||
| inline const JsonObjectSubscript JsonVariantBase<TImplem>::operator[]( | ||||
|     const char *key) const { | ||||
| inline const JsonObjectSubscript<const char *> JsonVariantBase<TImplem>:: | ||||
| operator[](const char *key) const { | ||||
|   return asObject()[key]; | ||||
| } | ||||
|  | ||||
| template <typename TImplem> | ||||
| inline const JsonObjectSubscript JsonVariantBase<TImplem>::operator[]( | ||||
|     const String &key) const { | ||||
| inline const JsonObjectSubscript<const String &> JsonVariantBase<TImplem>:: | ||||
| operator[](const String &key) const { | ||||
|   return asObject()[key]; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -6,52 +6,64 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonVariantBase.hpp" | ||||
| #include "JsonSubscriptBase.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
| class JsonObjectSubscript : public JsonVariantBase<JsonObjectSubscript> { | ||||
|  | ||||
| template <typename TKey> | ||||
| class JsonObjectSubscript | ||||
|     : public JsonSubscriptBase<JsonObjectSubscript<TKey> > { | ||||
|  public: | ||||
|   FORCE_INLINE JsonObjectSubscript(JsonObject& object, JsonObjectKey key) | ||||
|   FORCE_INLINE JsonObjectSubscript(JsonObject& object, TKey key) | ||||
|       : _object(object), _key(key) {} | ||||
|  | ||||
|   FORCE_INLINE JsonObjectSubscript& operator=(const JsonVariant& value) { | ||||
|     _object.set(_key, value); | ||||
|     return *this; | ||||
|   } | ||||
|   using JsonSubscriptBase<JsonObjectSubscript<TKey> >::operator=; | ||||
|  | ||||
|   FORCE_INLINE JsonObjectSubscript& operator=( | ||||
|       const JsonObjectSubscript& other) { | ||||
|   FORCE_INLINE JsonObjectSubscript<TKey>& operator=( | ||||
|       const JsonObjectSubscript<TKey>& other) { | ||||
|     // to prevent Visual Studio warning C4512: assignment operator could not be | ||||
|     // generated | ||||
|     _object.set(_key, other._object.get(other._key)); | ||||
|     return *this; | ||||
|     return set(other.get()); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE bool success() const { return _object.containsKey(_key); } | ||||
|  | ||||
|   FORCE_INLINE operator JsonVariant() const { return _object.get(_key); } | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE T as() const { | ||||
|     return _object.get<T>(_key); | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE TValue as() const { | ||||
|     return _object.get<TValue>(_key); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   FORCE_INLINE T is() const { | ||||
|     return _object.is<T>(_key); | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE TValue is() const { | ||||
|     return _object.is<TValue>(_key); | ||||
|   } | ||||
|  | ||||
|   void writeTo(Internals::JsonWriter &writer) const { | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE bool set(TValue value) { | ||||
|     return _object.set(_key, value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE JsonVariant get() { return _object.get(_key); } | ||||
|  | ||||
|   void writeTo(Internals::JsonWriter& writer) const { | ||||
|     _object.get(_key).writeTo(writer); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   JsonObject& _object; | ||||
|   JsonObjectKey _key; | ||||
|   TKey _key; | ||||
| }; | ||||
|  | ||||
| #ifdef ARDUINOJSON_ENABLE_STD_STREAM | ||||
| inline std::ostream& operator<<(std::ostream& os, const JsonObjectSubscript& source) { | ||||
| inline std::ostream& operator<<( | ||||
|     std::ostream& os, const JsonObjectSubscript<const String&>& source) { | ||||
|   return source.printTo(os); | ||||
| } | ||||
|  | ||||
| inline std::ostream& operator<<( | ||||
|     std::ostream& os, const JsonObjectSubscript<const char*>& source) { | ||||
|   return source.printTo(os); | ||||
| } | ||||
| #endif | ||||
|   | ||||
							
								
								
									
										82
									
								
								include/ArduinoJson/JsonSubscriptBase.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								include/ArduinoJson/JsonSubscriptBase.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| // Copyright Benoit Blanchon 2014-2015 | ||||
| // MIT License | ||||
| // | ||||
| // Arduino JSON library | ||||
| // https://github.com/bblanchon/ArduinoJson | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "JsonVariantBase.hpp" | ||||
|  | ||||
| namespace ArduinoJson { | ||||
|  | ||||
| template <typename TImpl> | ||||
| class JsonSubscriptBase : public JsonVariantBase<TImpl> { | ||||
|  public: | ||||
|   FORCE_INLINE TImpl& operator=(bool value) { return assign<bool>(value); } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(float value) { return assign<float>(value); } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(double value) { return assign<double>(value); } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(signed char value) { | ||||
|     return assign<signed char>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(signed long value) { | ||||
|     return assign<signed long>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(signed int value) { | ||||
|     return assign<signed int>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(signed short value) { | ||||
|     return assign<signed short>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(unsigned char value) { | ||||
|     return assign<unsigned char>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(unsigned long value) { | ||||
|     return assign<unsigned long>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(unsigned int value) { | ||||
|     return assign<unsigned int>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(unsigned short value) { | ||||
|     return assign<unsigned short>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(const char* value) { | ||||
|     return assign<const char*>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(const String& value) { | ||||
|     return assign<const String&>(value); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(JsonArray& array) { | ||||
|     return assign<JsonArray&>(array); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(JsonObject& object) { | ||||
|     return assign<JsonObject&>(object); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE TImpl& operator=(JsonVariant value) { | ||||
|     return assign<JsonVariant>(value); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE TImpl& assign(TValue value) { | ||||
|     TImpl* impl = static_cast<TImpl*>(this); | ||||
|     impl->template set<TValue>(value); | ||||
|     return *impl; | ||||
|   } | ||||
| }; | ||||
| } | ||||
| @@ -9,7 +9,6 @@ | ||||
| #include <stddef.h> | ||||
| #include <stdint.h>  // for uint8_t | ||||
|  | ||||
| #include "Arduino/String.hpp" | ||||
| #include "Internals/JsonPrintable.hpp" | ||||
| #include "Internals/JsonVariantContent.hpp" | ||||
| #include "Internals/JsonVariantType.hpp" | ||||
| @@ -55,7 +54,6 @@ class JsonVariant : public JsonVariantBase<JsonVariant> { | ||||
|  | ||||
|   // Create a JsonVariant containing a string. | ||||
|   FORCE_INLINE JsonVariant(const char *value); | ||||
|   FORCE_INLINE JsonVariant(const String &value); | ||||
|  | ||||
|   // Create a JsonVariant containing a reference to an array. | ||||
|   FORCE_INLINE JsonVariant(JsonArray &array); | ||||
|   | ||||
| @@ -20,11 +20,6 @@ inline JsonVariant::JsonVariant(const char *value) { | ||||
|   _content.asString = value; | ||||
| } | ||||
|  | ||||
| inline JsonVariant::JsonVariant(const String &value) { | ||||
|   _type = Internals::JSON_STRING; | ||||
|   _content.asString = value.c_str(); | ||||
| } | ||||
|  | ||||
| inline JsonVariant::JsonVariant(double value, uint8_t decimals) { | ||||
|   _type = static_cast<Internals::JsonVariantType>( | ||||
|       Internals::JSON_DOUBLE_0_DECIMALS + decimals); | ||||
| @@ -112,11 +107,6 @@ inline bool JsonVariant::is<char const *>() const { | ||||
|   return _type == Internals::JSON_STRING; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline bool JsonVariant::is<String>() const { | ||||
|   return _type == Internals::JSON_STRING; | ||||
| } | ||||
|  | ||||
| template <> | ||||
| inline bool JsonVariant::is<double>() const { | ||||
|   return _type >= Internals::JSON_DOUBLE_0_DECIMALS; | ||||
| @@ -188,9 +178,9 @@ inline bool JsonVariant::is<unsigned short>() const { | ||||
| } | ||||
|  | ||||
| #ifdef ARDUINOJSON_ENABLE_STD_STREAM | ||||
| inline std::ostream& operator<<(std::ostream& os, const JsonVariant& source) { | ||||
| inline std::ostream &operator<<(std::ostream &os, const JsonVariant &source) { | ||||
|   return source.printTo(os); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| } // namespace ArduinoJson | ||||
| }  // namespace ArduinoJson | ||||
|   | ||||
| @@ -13,6 +13,7 @@ namespace ArduinoJson { | ||||
|  | ||||
| // Forward declarations. | ||||
| class JsonArraySubscript; | ||||
| template <typename TKey> | ||||
| class JsonObjectSubscript; | ||||
|  | ||||
| template <typename TImpl> | ||||
| @@ -76,8 +77,10 @@ class JsonVariantBase : public Internals::JsonPrintable<TImpl> { | ||||
|   // Returns the value associated with the specified key if the variant is | ||||
|   // an object. | ||||
|   // Return JsonVariant::invalid() if the variant is not an object. | ||||
|   FORCE_INLINE const JsonObjectSubscript operator[](const char *key) const; | ||||
|   FORCE_INLINE const JsonObjectSubscript operator[](const String &key) const; | ||||
|   FORCE_INLINE const JsonObjectSubscript<const char *> operator[]( | ||||
|       const char *key) const; | ||||
|   FORCE_INLINE const JsonObjectSubscript<const String &> operator[]( | ||||
|       const String &key) const; | ||||
|  | ||||
|   // Serialize the variant to a JsonWriter | ||||
|   void writeTo(Internals::JsonWriter &writer) const; | ||||
|   | ||||
| @@ -49,7 +49,7 @@ size_t DynamicJsonBuffer::size() const { | ||||
| } | ||||
|  | ||||
| void* DynamicJsonBuffer::alloc(size_t bytes) { | ||||
|   if (!canAllocInHead(bytes)) addNewBlock(); | ||||
|   while (!canAllocInHead(bytes)) addNewBlock(); | ||||
|   return allocInHead(bytes); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -32,3 +32,10 @@ JsonObject &JsonBuffer::parseObject(char *json, uint8_t nestingLimit) { | ||||
|   JsonParser parser(this, json, nestingLimit); | ||||
|   return parser.parseObject(); | ||||
| } | ||||
|  | ||||
| char *JsonBuffer::strdup(const char *source, size_t length) { | ||||
|   size_t size = length + 1; | ||||
|   char *dest = static_cast<char *>(alloc(size)); | ||||
|   if (dest != NULL) memcpy(dest, source, size); | ||||
|   return dest; | ||||
| } | ||||
|   | ||||
| @@ -25,19 +25,25 @@ JsonObject::node_type *JsonObject::getOrCreateNodeAt(JsonObjectKey key) { | ||||
|   return newNode; | ||||
| } | ||||
|  | ||||
| JsonArray &JsonObject::createNestedArray(JsonObjectKey key) { | ||||
| template <typename TKey> | ||||
| JsonArray &JsonObject::createArrayAt(TKey key) { | ||||
|   if (!_buffer) return JsonArray::invalid(); | ||||
|   JsonArray &array = _buffer->createArray(); | ||||
|   set(key, array); | ||||
|   setNodeAt<TKey, const JsonVariant &>(key, array); | ||||
|   return array; | ||||
| } | ||||
| template JsonArray &JsonObject::createArrayAt<const char *>(const char *); | ||||
| template JsonArray &JsonObject::createArrayAt<const String &>(const String &); | ||||
|  | ||||
| JsonObject &JsonObject::createNestedObject(JsonObjectKey key) { | ||||
| template <typename TKey> | ||||
| JsonObject &JsonObject::createObjectAt(TKey key) { | ||||
|   if (!_buffer) return JsonObject::invalid(); | ||||
|   JsonObject &object = _buffer->createObject(); | ||||
|   set(key, object); | ||||
|   return object; | ||||
|   JsonObject &array = _buffer->createObject(); | ||||
|   setNodeAt<TKey, const JsonVariant &>(key, array); | ||||
|   return array; | ||||
| } | ||||
| template JsonObject &JsonObject::createObjectAt<const char *>(const char *); | ||||
| template JsonObject &JsonObject::createObjectAt<const String &>(const String &); | ||||
|  | ||||
| JsonObject::node_type *JsonObject::getNodeAt(JsonObjectKey key) const { | ||||
|   for (node_type *node = _firstNode; node; node = node->next) { | ||||
|   | ||||
| @@ -7,103 +7,160 @@ | ||||
| #include <gtest/gtest.h> | ||||
| #include <ArduinoJson.h> | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonBuffer_ParseArray) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
|   String json("[1,2]"); | ||||
|   JsonArray &array = jsonBuffer.parseArray(json); | ||||
| class ArduinoStringTests : public ::testing::Test { | ||||
|  protected: | ||||
|   static void eraseString(String &str) { | ||||
|     char *p = const_cast<char *>(str.c_str()); | ||||
|     while (*p) *p++ = '*'; | ||||
|   } | ||||
|  | ||||
|   DynamicJsonBuffer _jsonBuffer; | ||||
| }; | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonBuffer_ParseArray) { | ||||
|   String json("[\"hello\"]"); | ||||
|   JsonArray &array = _jsonBuffer.parseArray(json); | ||||
|   eraseString(json); | ||||
|   ASSERT_TRUE(array.success()); | ||||
|   ASSERT_STREQ("hello", array[0]); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonBuffer_ParseObject) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
|   String json("{\"a\":1,\"b\":2}"); | ||||
|   JsonObject &object = jsonBuffer.parseObject(json); | ||||
| TEST_F(ArduinoStringTests, JsonBuffer_ParseObject) { | ||||
|   String json("{\"hello\":\"world\"}"); | ||||
|   JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   eraseString(json); | ||||
|   ASSERT_TRUE(object.success()); | ||||
|   ASSERT_STREQ("world", object["hello"]); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonVariant) { | ||||
|   String input = "Hello world!"; | ||||
|   JsonVariant variant(input); | ||||
|   ASSERT_TRUE(variant.is<String>()); | ||||
|   String output = variant.as<String>(); | ||||
|   ASSERT_EQ(input, output); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_Subscript) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_Subscript) { | ||||
|   char json[] = "{\"key\":\"value\"}"; | ||||
|   JsonObject &object = jsonBuffer.parseObject(json); | ||||
|   JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   ASSERT_STREQ("value", object[String("key")]); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_ConstSubscript) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_ConstSubscript) { | ||||
|   char json[] = "{\"key\":\"value\"}"; | ||||
|   const JsonObject &object = jsonBuffer.parseObject(json); | ||||
|   const JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   ASSERT_STREQ("value", object[String("key")]); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_Set) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
|   JsonObject &object = jsonBuffer.createObject(); | ||||
|   String key = "key"; | ||||
|   object.set(key, "value"); | ||||
|   ASSERT_STREQ("value", object["key"]); | ||||
| TEST_F(ArduinoStringTests, JsonObject_SetKey) { | ||||
|   JsonObject &object = _jsonBuffer.createObject(); | ||||
|   String key("hello"); | ||||
|   object.set(key, "world"); | ||||
|   eraseString(key); | ||||
|   ASSERT_STREQ("world", object["hello"]); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_Get) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_SetValue) { | ||||
|   JsonObject &object = _jsonBuffer.createObject(); | ||||
|   String value("world"); | ||||
|   object.set("hello", value); | ||||
|   eraseString(value); | ||||
|   ASSERT_STREQ("world", object["hello"]); | ||||
| } | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonObject_SetKeyValue) { | ||||
|   JsonObject &object = _jsonBuffer.createObject(); | ||||
|   String key("hello"); | ||||
|   String value("world"); | ||||
|   object.set(key, value); | ||||
|   eraseString(key); | ||||
|   eraseString(value); | ||||
|   ASSERT_STREQ("world", object["hello"]); | ||||
| } | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonObject_Get) { | ||||
|   char json[] = "{\"key\":\"value\"}"; | ||||
|   const JsonObject &object = jsonBuffer.parseObject(json); | ||||
|   const JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   ASSERT_STREQ("value", object.get(String("key"))); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_GetT) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_GetT) { | ||||
|   char json[] = "{\"key\":\"value\"}"; | ||||
|   const JsonObject &object = jsonBuffer.parseObject(json); | ||||
|   const JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   ASSERT_STREQ("value", object.get<const char *>(String("key"))); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_IsT) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_IsT) { | ||||
|   char json[] = "{\"key\":\"value\"}"; | ||||
|   const JsonObject &object = jsonBuffer.parseObject(json); | ||||
|   const JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   ASSERT_TRUE(object.is<const char *>(String("key"))); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_CreateNestedObject) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_CreateNestedObject) { | ||||
|   String key = "key"; | ||||
|   char json[64]; | ||||
|   JsonObject &object = jsonBuffer.createObject(); | ||||
|   JsonObject &object = _jsonBuffer.createObject(); | ||||
|   object.createNestedObject(key); | ||||
|   eraseString(key); | ||||
|   object.printTo(json, sizeof(json)); | ||||
|   ASSERT_STREQ("{\"key\":{}}", json); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_CreateNestedArray) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_CreateNestedArray) { | ||||
|   String key = "key"; | ||||
|   char json[64]; | ||||
|   JsonObject &object = jsonBuffer.createObject(); | ||||
|   JsonObject &object = _jsonBuffer.createObject(); | ||||
|   object.createNestedArray(key); | ||||
|   eraseString(key); | ||||
|   object.printTo(json, sizeof(json)); | ||||
|   ASSERT_STREQ("{\"key\":[]}", json); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_ContainsKey) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_ContainsKey) { | ||||
|   char json[] = "{\"key\":\"value\"}"; | ||||
|   const JsonObject &object = jsonBuffer.parseObject(json); | ||||
|   const JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   ASSERT_TRUE(object.containsKey(String("key"))); | ||||
| } | ||||
|  | ||||
| TEST(ArduinoStringTests, JsonObject_Remove) { | ||||
|   DynamicJsonBuffer jsonBuffer; | ||||
| TEST_F(ArduinoStringTests, JsonObject_Remove) { | ||||
|   char json[] = "{\"key\":\"value\"}"; | ||||
|   JsonObject &object = jsonBuffer.parseObject(json); | ||||
|   JsonObject &object = _jsonBuffer.parseObject(json); | ||||
|   ASSERT_EQ(1, object.size()); | ||||
|   object.remove(String("key")); | ||||
|   ASSERT_EQ(0, object.size()); | ||||
| } | ||||
| } | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonObjectSubscript_SetKey) { | ||||
|   JsonObject &object = _jsonBuffer.createObject(); | ||||
|   String key("hello"); | ||||
|   object[key] = "world"; | ||||
|   eraseString(key); | ||||
|   ASSERT_STREQ("world", object["hello"]); | ||||
| } | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonObjectSubscript_SetValue) { | ||||
|   JsonObject &object = _jsonBuffer.createObject(); | ||||
|   String value("world"); | ||||
|   object["hello"] = value; | ||||
|   eraseString(value); | ||||
|   ASSERT_STREQ("world", object["hello"]); | ||||
| } | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonArray_Add) { | ||||
|   JsonArray &array = _jsonBuffer.createArray(); | ||||
|   String value("hello"); | ||||
|   array.add(value); | ||||
|   eraseString(value); | ||||
|   ASSERT_STREQ("hello", array[0]); | ||||
| } | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonArray_Set) { | ||||
|   JsonArray &array = _jsonBuffer.createArray(); | ||||
|   String value("world"); | ||||
|   array.add("hello"); | ||||
|   array.set(0, value); | ||||
|   eraseString(value); | ||||
|   ASSERT_STREQ("world", array[0]); | ||||
| } | ||||
|  | ||||
| TEST_F(ArduinoStringTests, JsonArraySubscript) { | ||||
|   JsonArray &array = _jsonBuffer.createArray(); | ||||
|   String value("world"); | ||||
|   array.add("hello"); | ||||
|   array[0] = value; | ||||
|   eraseString(value); | ||||
|   ASSERT_STREQ("world", array[0]); | ||||
| } | ||||
|   | ||||
| @@ -59,7 +59,7 @@ TEST_F(JsonObject_Container_Tests, | ||||
|  | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreIntegers) { | ||||
|   _object["hello"] = 123; | ||||
|   _object["world"] = 456; | ||||
|   _object.set("world", 456); | ||||
|  | ||||
|   EXPECT_EQ(123, _object["hello"].as<int>()); | ||||
|   EXPECT_EQ(456, _object["world"].as<int>()); | ||||
| @@ -67,7 +67,7 @@ TEST_F(JsonObject_Container_Tests, CanStoreIntegers) { | ||||
|  | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreDoubles) { | ||||
|   _object["hello"] = 123.45; | ||||
|   _object["world"] = 456.78; | ||||
|   _object.set("world", 456.78); | ||||
|  | ||||
|   EXPECT_EQ(123.45, _object["hello"].as<double>()); | ||||
|   EXPECT_EQ(456.78, _object["world"].as<double>()); | ||||
| @@ -75,7 +75,7 @@ TEST_F(JsonObject_Container_Tests, CanStoreDoubles) { | ||||
|  | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreBooleans) { | ||||
|   _object["hello"] = true; | ||||
|   _object["world"] = false; | ||||
|   _object.set("world", false); | ||||
|  | ||||
|   EXPECT_TRUE(_object["hello"].as<bool>()); | ||||
|   EXPECT_FALSE(_object["world"].as<bool>()); | ||||
| @@ -83,32 +83,32 @@ TEST_F(JsonObject_Container_Tests, CanStoreBooleans) { | ||||
|  | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreStrings) { | ||||
|   _object["hello"] = "h3110"; | ||||
|   _object["world"] = "w0r1d"; | ||||
|   _object.set("world", "w0r1d"); | ||||
|  | ||||
|   EXPECT_STREQ("h3110", _object["hello"].as<const char*>()); | ||||
|   EXPECT_STREQ("w0r1d", _object["world"].as<const char*>()); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreInnerArrays) { | ||||
|   JsonArray& innerarray1 = _jsonBuffer.createArray(); | ||||
|   JsonArray& innerarray2 = _jsonBuffer.createArray(); | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreArrays) { | ||||
|   JsonArray& array1 = _jsonBuffer.createArray(); | ||||
|   JsonArray& array2 = _jsonBuffer.createArray(); | ||||
|  | ||||
|   _object["hello"] = innerarray1; | ||||
|   _object["world"] = innerarray2; | ||||
|   _object["hello"] = array1; | ||||
|   _object.set("world", array2); | ||||
|  | ||||
|   EXPECT_EQ(&innerarray1, &_object["hello"].asArray()); | ||||
|   EXPECT_EQ(&innerarray2, &_object["world"].asArray()); | ||||
|   EXPECT_EQ(&array1, &_object["hello"].asArray()); | ||||
|   EXPECT_EQ(&array2, &_object["world"].asArray()); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreInnerObjects) { | ||||
|   JsonObject& innerObject1 = _jsonBuffer.createObject(); | ||||
|   JsonObject& innerObject2 = _jsonBuffer.createObject(); | ||||
| TEST_F(JsonObject_Container_Tests, CanStoreObjects) { | ||||
|   JsonObject& object1 = _jsonBuffer.createObject(); | ||||
|   JsonObject& object2 = _jsonBuffer.createObject(); | ||||
|  | ||||
|   _object["hello"] = innerObject1; | ||||
|   _object["world"] = innerObject2; | ||||
|   _object["hello"] = object1; | ||||
|   _object.set("world", object2); | ||||
|  | ||||
|   EXPECT_EQ(&innerObject1, &_object["hello"].asObject()); | ||||
|   EXPECT_EQ(&innerObject2, &_object["world"].asObject()); | ||||
|   EXPECT_EQ(&object1, &_object["hello"].asObject()); | ||||
|   EXPECT_EQ(&object2, &_object["world"].asObject()); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_Container_Tests, ContainsKeyReturnsFalseForNonExistingKey) { | ||||
|   | ||||
| @@ -11,131 +11,105 @@ using namespace ArduinoJson::Internals; | ||||
|  | ||||
| class JsonObject_PrintTo_Tests : public testing::Test { | ||||
|  public: | ||||
|   JsonObject_PrintTo_Tests() : object(json.createObject()) {} | ||||
|   JsonObject_PrintTo_Tests() : _object(_jsonBuffer.createObject()) {} | ||||
|  | ||||
|  protected: | ||||
|   void outputMustBe(const char *expected) { | ||||
|     char actual[256]; | ||||
|     size_t actualLen = object.printTo(actual, sizeof(actual)); | ||||
|     size_t measuredLen = object.measureLength(); | ||||
|     size_t actualLen = _object.printTo(actual, sizeof(actual)); | ||||
|     size_t measuredLen = _object.measureLength(); | ||||
|  | ||||
|     EXPECT_STREQ(expected, actual); | ||||
|     EXPECT_EQ(strlen(expected), actualLen); | ||||
|     EXPECT_EQ(strlen(expected), measuredLen); | ||||
|   } | ||||
|  | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(2)> json; | ||||
|   JsonObject &object; | ||||
|   DynamicJsonBuffer _jsonBuffer; | ||||
|   JsonObject &_object; | ||||
| }; | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, EmptyObject) { outputMustBe("{}"); } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneString) { | ||||
|   object["key"] = "value"; | ||||
|  | ||||
|   outputMustBe("{\"key\":\"value\"}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, TwoStrings) { | ||||
|   object["key1"] = "value1"; | ||||
|   object["key2"] = "value2"; | ||||
|   _object["key1"] = "value1"; | ||||
|   _object.set("key2", "value2"); | ||||
|  | ||||
|   outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, RemoveFirst) { | ||||
|   object["key1"] = "value1"; | ||||
|   object["key2"] = "value2"; | ||||
|   object.remove("key1"); | ||||
|   _object["key1"] = "value1"; | ||||
|   _object["key2"] = "value2"; | ||||
|   _object.remove("key1"); | ||||
|  | ||||
|   outputMustBe("{\"key2\":\"value2\"}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, RemoveLast) { | ||||
|   object["key1"] = "value1"; | ||||
|   object["key2"] = "value2"; | ||||
|   object.remove("key2"); | ||||
|   _object["key1"] = "value1"; | ||||
|   _object["key2"] = "value2"; | ||||
|   _object.remove("key2"); | ||||
|  | ||||
|   outputMustBe("{\"key1\":\"value1\"}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, RemoveUnexistingKey) { | ||||
|   object["key1"] = "value1"; | ||||
|   object["key2"] = "value2"; | ||||
|   object.remove("key3"); | ||||
|   _object["key1"] = "value1"; | ||||
|   _object["key2"] = "value2"; | ||||
|   _object.remove("key3"); | ||||
|  | ||||
|   outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, ReplaceExistingKey) { | ||||
|   object["key"] = "value1"; | ||||
|   object["key"] = "value2"; | ||||
|   _object["key"] = "value1"; | ||||
|   _object["key"] = "value2"; | ||||
|  | ||||
|   outputMustBe("{\"key\":\"value2\"}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneStringOverCapacity) { | ||||
|   object["key1"] = "value1"; | ||||
|   object["key2"] = "value2"; | ||||
|   object["key3"] = "value3"; | ||||
|  | ||||
|   outputMustBe("{\"key1\":\"value1\",\"key2\":\"value2\"}"); | ||||
| TEST_F(JsonObject_PrintTo_Tests, TwoIntegers) { | ||||
|   _object["a"] = 1; | ||||
|   _object.set("b", 2); | ||||
|   outputMustBe("{\"a\":1,\"b\":2}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneInteger) { | ||||
|   object["key"] = 1; | ||||
|   outputMustBe("{\"key\":1}"); | ||||
| TEST_F(JsonObject_PrintTo_Tests, TwoDoublesFourDigits) { | ||||
|   _object["a"] = double_with_n_digits(3.14159265358979323846, 4); | ||||
|   _object.set("b", 2.71828182845904523536, 4); | ||||
|   outputMustBe("{\"a\":3.1416,\"b\":2.7183}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneDoubleFourDigits) { | ||||
|   object["key"] = double_with_n_digits(3.14159265358979323846, 4); | ||||
|   outputMustBe("{\"key\":3.1416}"); | ||||
| TEST_F(JsonObject_PrintTo_Tests, TwoDoubleDefaultDigits) { | ||||
|   _object["a"] = 3.14159265358979323846; | ||||
|   _object.set("b", 2.71828182845904523536); | ||||
|   outputMustBe("{\"a\":3.14,\"b\":2.72}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneDoubleDefaultDigits) { | ||||
|   object["key"] = 3.14159265358979323846; | ||||
|   outputMustBe("{\"key\":3.14}"); | ||||
| TEST_F(JsonObject_PrintTo_Tests, TwoNull) { | ||||
|   _object["a"] = static_cast<char *>(0); | ||||
|   _object.set("b", static_cast<char *>(0)); | ||||
|   outputMustBe("{\"a\":null,\"b\":null}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneNull) { | ||||
|   object["key"] = static_cast<char *>(0); | ||||
|   outputMustBe("{\"key\":null}"); | ||||
| TEST_F(JsonObject_PrintTo_Tests, TwoBooleans) { | ||||
|   _object["a"] = true; | ||||
|   _object.set("b", false); | ||||
|   outputMustBe("{\"a\":true,\"b\":false}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneTrue) { | ||||
|   object["key"] = true; | ||||
|   outputMustBe("{\"key\":true}"); | ||||
| TEST_F(JsonObject_PrintTo_Tests, ThreeNestedArrays) { | ||||
|   _object.createNestedArray("a"); | ||||
|   _object["b"] = _jsonBuffer.createArray(); | ||||
|   _object.set("c", _jsonBuffer.createArray()); | ||||
|  | ||||
|   outputMustBe("{\"a\":[],\"b\":[],\"c\":[]}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneFalse) { | ||||
|   object["key"] = false; | ||||
|   outputMustBe("{\"key\":false}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedArrayViaProxy) { | ||||
|   JsonArray &nestedArray = json.createArray(); | ||||
|  | ||||
|   object["key"] = nestedArray; | ||||
|  | ||||
|   outputMustBe("{\"key\":[]}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedObjectViaProxy) { | ||||
|   JsonObject &nestedArray = json.createObject(); | ||||
|  | ||||
|   object["key"] = nestedArray; | ||||
|  | ||||
|   outputMustBe("{\"key\":{}}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedObject) { | ||||
|   object.createNestedObject("key"); | ||||
|  | ||||
|   outputMustBe("{\"key\":{}}"); | ||||
| } | ||||
|  | ||||
| TEST_F(JsonObject_PrintTo_Tests, OneEmptyNestedArray) { | ||||
|   object.createNestedArray("key"); | ||||
|  | ||||
|   outputMustBe("{\"key\":[]}"); | ||||
| TEST_F(JsonObject_PrintTo_Tests, ThreeNestedObjects) { | ||||
|   _object.createNestedObject("a"); | ||||
|   _object["b"] = _jsonBuffer.createObject(); | ||||
|   _object.set("c", _jsonBuffer.createObject()); | ||||
|  | ||||
|   outputMustBe("{\"a\":{},\"b\":{},\"c\":{}}"); | ||||
| } | ||||
|   | ||||
| @@ -8,44 +8,49 @@ | ||||
| #include <ArduinoJson.h> | ||||
|  | ||||
| TEST(StaticJsonBuffer_CreateObject_Tests, GrowsWithObject) { | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(3)> json; | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(3)> buffer; | ||||
|  | ||||
|   JsonObject &obj = json.createObject(); | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(0), json.size()); | ||||
|   JsonObject &obj = buffer.createObject(); | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(0), buffer.size()); | ||||
|  | ||||
|   obj["hello"]; | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(0), json.size()); | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(0), buffer.size()); | ||||
|  | ||||
|   obj["hello"] = 1; | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(1), json.size()); | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(1), buffer.size()); | ||||
|  | ||||
|   obj["world"] = 2; | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size()); | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(2), buffer.size()); | ||||
|  | ||||
|   obj["world"] = 3;  // <- same key, should not grow | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(2), json.size()); | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(2), buffer.size()); | ||||
| } | ||||
|  | ||||
| TEST(StaticJsonBuffer_CreateObject_Tests, SucceedWhenBigEnough) { | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(0)> json; | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(0)> buffer; | ||||
|  | ||||
|   JsonObject &object = json.createObject(); | ||||
|   JsonObject &object = buffer.createObject(); | ||||
|   ASSERT_TRUE(object.success()); | ||||
| } | ||||
|  | ||||
| TEST(StaticJsonBuffer_CreateObject_Tests, FailsWhenTooSmall) { | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> json; | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(0) - 1> buffer; | ||||
|  | ||||
|   JsonObject &object = json.createObject(); | ||||
|   JsonObject &object = buffer.createObject(); | ||||
|   ASSERT_FALSE(object.success()); | ||||
| } | ||||
|  | ||||
| TEST(StaticJsonBuffer_CreateObject_Tests, ObjectDoesntGrowWhenFull) { | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(1)> json; | ||||
|   StaticJsonBuffer<JSON_OBJECT_SIZE(1)> buffer; | ||||
|  | ||||
|   JsonObject &obj = json.createObject(); | ||||
|   JsonObject &obj = buffer.createObject(); | ||||
|   obj["hello"] = 1; | ||||
|   obj["world"] = 2; | ||||
|  | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(1), json.size()); | ||||
|   ASSERT_EQ(JSON_OBJECT_SIZE(1), buffer.size()); | ||||
|   ASSERT_EQ(1, obj.size()); | ||||
|  | ||||
|   char json[64]; | ||||
|   obj.printTo(json, sizeof(json)); | ||||
|   ASSERT_STREQ("{\"hello\":1}", json); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user