mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 08:42:39 +01:00 
			
		
		
		
	User can now use a JsonString as a key or a value
This commit is contained in:
		| @@ -28,6 +28,7 @@ HEAD | ||||
| * `JsonDocument` now support the same operations as `JsonVariant`. | ||||
|   Calling `JsonDocument::as<T>()` is not required anymore. | ||||
| * Fixed example `JsonHttpClient.ino` | ||||
| * User can now use a `JsonString` as a key or a value | ||||
|  | ||||
| > ### BREAKING CHANGES | ||||
| >  | ||||
|   | ||||
| @@ -24,13 +24,13 @@ class CollectionData { | ||||
|  | ||||
|   VariantData *add(MemoryPool *pool); | ||||
|  | ||||
|   template <typename TKey> | ||||
|   VariantData *add(TKey key, MemoryPool *pool); | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData *add(TAdaptedString key, MemoryPool *pool); | ||||
|  | ||||
|   void clear(); | ||||
|  | ||||
|   template <typename TKey> | ||||
|   bool containsKey(const TKey &key) const; | ||||
|   template <typename TAdaptedString> | ||||
|   bool containsKey(const TAdaptedString &key) const; | ||||
|  | ||||
|   bool copyFrom(const CollectionData &src, MemoryPool *pool); | ||||
|  | ||||
| @@ -39,8 +39,8 @@ class CollectionData { | ||||
|  | ||||
|   VariantData *get(size_t index) const; | ||||
|  | ||||
|   template <typename TKey> | ||||
|   VariantData *get(TKey key) const; | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData *get(TAdaptedString key) const; | ||||
|  | ||||
|   VariantSlot *head() const { | ||||
|     return _head; | ||||
| @@ -48,8 +48,8 @@ class CollectionData { | ||||
|  | ||||
|   void remove(size_t index); | ||||
|  | ||||
|   template <typename TKey> | ||||
|   void remove(TKey key) { | ||||
|   template <typename TAdaptedString> | ||||
|   void remove(TAdaptedString key) { | ||||
|     remove(getSlot(key)); | ||||
|   } | ||||
|  | ||||
| @@ -62,8 +62,8 @@ class CollectionData { | ||||
|  private: | ||||
|   VariantSlot *getSlot(size_t index) const; | ||||
|  | ||||
|   template <typename TKey> | ||||
|   VariantSlot *getSlot(TKey key) const; | ||||
|   template <typename TAdaptedString> | ||||
|   VariantSlot *getSlot(TAdaptedString key) const; | ||||
|  | ||||
|   VariantSlot *getPreviousSlot(VariantSlot *) const; | ||||
| }; | ||||
|   | ||||
| @@ -29,8 +29,8 @@ inline VariantData* CollectionData::add(MemoryPool* pool) { | ||||
|   return addSlot(pool)->data(); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantData* CollectionData::add(TKey key, MemoryPool* pool) { | ||||
| template <typename TAdaptedString> | ||||
| inline VariantData* CollectionData::add(TAdaptedString key, MemoryPool* pool) { | ||||
|   VariantSlot* slot = addSlot(pool); | ||||
|   if (!slotSetKey(slot, key, pool)) return 0; | ||||
|   return slot->data(); | ||||
| @@ -41,8 +41,8 @@ inline void CollectionData::clear() { | ||||
|   _tail = 0; | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline bool CollectionData::containsKey(const TKey& key) const { | ||||
| template <typename TAdaptedString> | ||||
| inline bool CollectionData::containsKey(const TAdaptedString& key) const { | ||||
|   return getSlot(key) != 0; | ||||
| } | ||||
|  | ||||
| @@ -53,9 +53,9 @@ inline bool CollectionData::copyFrom(const CollectionData& src, | ||||
|     VariantData* var; | ||||
|     if (s->key() != 0) { | ||||
|       if (s->ownsKey()) | ||||
|         var = add(RamStringWrapper(s->key()), pool); | ||||
|         var = add(RamStringAdapter(s->key()), pool); | ||||
|       else | ||||
|         var = add(ConstRamStringWrapper(s->key()), pool); | ||||
|         var = add(ConstRamStringAdapter(s->key()), pool); | ||||
|     } else { | ||||
|       var = add(pool); | ||||
|     } | ||||
| @@ -69,7 +69,7 @@ inline bool CollectionData::equalsObject(const CollectionData& other) const { | ||||
|   size_t count = 0; | ||||
|   for (VariantSlot* slot = _head; slot; slot = slot->next()) { | ||||
|     VariantData* v1 = slot->data(); | ||||
|     VariantData* v2 = other.get(wrapString(slot->key())); | ||||
|     VariantData* v2 = other.get(adaptString(slot->key())); | ||||
|     if (!variantEquals(v1, v2)) return false; | ||||
|     count++; | ||||
|   } | ||||
| @@ -88,8 +88,8 @@ inline bool CollectionData::equalsArray(const CollectionData& other) const { | ||||
|   } | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantSlot* CollectionData::getSlot(TKey key) const { | ||||
| template <typename TAdaptedString> | ||||
| inline VariantSlot* CollectionData::getSlot(TAdaptedString key) const { | ||||
|   VariantSlot* slot = _head; | ||||
|   while (slot) { | ||||
|     if (key.equals(slot->key())) break; | ||||
| @@ -112,8 +112,8 @@ inline VariantSlot* CollectionData::getPreviousSlot(VariantSlot* target) const { | ||||
|   return 0; | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantData* CollectionData::get(TKey key) const { | ||||
| template <typename TAdaptedString> | ||||
| inline VariantData* CollectionData::get(TAdaptedString key) const { | ||||
|   VariantSlot* slot = getSlot(key); | ||||
|   return slot ? slot->data() : 0; | ||||
| } | ||||
|   | ||||
| @@ -23,8 +23,8 @@ TDeserializer<TReader, TWriter> makeDeserializer(MemoryPool &pool, | ||||
|   return TDeserializer<TReader, TWriter>(pool, reader, writer, nestingLimit); | ||||
| } | ||||
|  | ||||
| // DeserializationError deserialize(JsonDocument& doc, TString input); | ||||
| // TString = const std::string&, const String& | ||||
| // deserialize(JsonDocument&, const std::string&); | ||||
| // deserialize(JsonDocument&, const String&); | ||||
| template <template <typename, typename> class TDeserializer, typename TString> | ||||
| typename enable_if<!is_array<TString>::value, DeserializationError>::type | ||||
| deserialize(JsonDocument &doc, const TString &input, | ||||
| @@ -36,8 +36,9 @@ deserialize(JsonDocument &doc, const TString &input, | ||||
|       .parse(doc.data()); | ||||
| } | ||||
| // | ||||
| // DeserializationError deserialize(JsonDocument& doc, TChar* input); | ||||
| // TChar* = char*, const char*, const __FlashStringHelper* | ||||
| // deserialize(JsonDocument&, char*); | ||||
| // deserialize(JsonDocument&, const char*); | ||||
| // deserialize(JsonDocument&, const __FlashStringHelper*); | ||||
| template <template <typename, typename> class TDeserializer, typename TChar> | ||||
| DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
|                                  NestingLimit nestingLimit) { | ||||
| @@ -48,9 +49,9 @@ DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
|       .parse(doc.data()); | ||||
| } | ||||
| // | ||||
| // DeserializationError deserialize(JsonDocument& doc, TChar* input, size_t | ||||
| // inputSize); | ||||
| // TChar* = char*, const char*, const __FlashStringHelper* | ||||
| // deserialize(JsonDocument&, char*, size_t); | ||||
| // deserialize(JsonDocument&, const char*, size_t); | ||||
| // deserialize(JsonDocument&, const __FlashStringHelper*, size_t); | ||||
| template <template <typename, typename> class TDeserializer, typename TChar> | ||||
| DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
|                                  size_t inputSize, NestingLimit nestingLimit) { | ||||
| @@ -61,8 +62,8 @@ DeserializationError deserialize(JsonDocument &doc, TChar *input, | ||||
|       .parse(doc.data()); | ||||
| } | ||||
| // | ||||
| // DeserializationError deserialize(JsonDocument& doc, TStream input); | ||||
| // TStream = std::istream&, Stream& | ||||
| // deserialize(JsonDocument&, std::istream&); | ||||
| // deserialize(JsonDocument&, Stream&); | ||||
| template <template <typename, typename> class TDeserializer, typename TStream> | ||||
| DeserializationError deserialize(JsonDocument &doc, TStream &input, | ||||
|                                  NestingLimit nestingLimit) { | ||||
|   | ||||
| @@ -86,13 +86,18 @@ class JsonDocument : public Visitable { | ||||
|     return add().to<ArrayRef>(); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   ArrayRef createNestedArray(TKey* key) { | ||||
|   // createNestedArray(char*) | ||||
|   // createNestedArray(const char*) | ||||
|   // createNestedArray(const __FlashStringHelper*) | ||||
|   template <typename TChar> | ||||
|   ArrayRef createNestedArray(TChar* key) { | ||||
|     return getOrCreate(key).template to<ArrayRef>(); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   ArrayRef createNestedArray(const TKey& key) { | ||||
|   // createNestedArray(const std::string&) | ||||
|   // createNestedArray(const String&) | ||||
|   template <typename TString> | ||||
|   ArrayRef createNestedArray(const TString& key) { | ||||
|     return getOrCreate(key).template to<ArrayRef>(); | ||||
|   } | ||||
|  | ||||
| @@ -100,48 +105,57 @@ class JsonDocument : public Visitable { | ||||
|     return add().to<ObjectRef>(); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   ObjectRef createNestedObject(TKey* key) { | ||||
|   // createNestedObject(char*) | ||||
|   // createNestedObject(const char*) | ||||
|   // createNestedObject(const __FlashStringHelper*) | ||||
|   template <typename TChar> | ||||
|   ObjectRef createNestedObject(TChar* key) { | ||||
|     return getOrCreate(key).template to<ObjectRef>(); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   ObjectRef createNestedObject(const TKey& key) { | ||||
|   // createNestedObject(const std::string&) | ||||
|   // createNestedObject(const String&) | ||||
|   template <typename TString> | ||||
|   ObjectRef createNestedObject(const TString& key) { | ||||
|     return getOrCreate(key).template to<ObjectRef>(); | ||||
|   } | ||||
|  | ||||
|   // MemberProxy operator[](TKey) | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   // operator[](const std::string&) | ||||
|   // operator[](const String&) | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TKey>::value, | ||||
|                          MemberProxy<JsonDocument&, const TKey&> >::type | ||||
|       operator[](const TKey& key) { | ||||
|     return MemberProxy<JsonDocument&, const TKey&>(*this, key); | ||||
|       typename enable_if<IsString<TString>::value, | ||||
|                          MemberProxy<JsonDocument&, const TString&> >::type | ||||
|       operator[](const TString& key) { | ||||
|     return MemberProxy<JsonDocument&, const TString&>(*this, key); | ||||
|   } | ||||
|  | ||||
|   // MemberProxy operator[](TKey); | ||||
|   // TKey = const char*, const char[N], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey*>::value, | ||||
|                                   MemberProxy<JsonDocument&, TKey*> >::type | ||||
|   operator[](TKey* key) { | ||||
|     return MemberProxy<JsonDocument&, TKey*>(*this, key); | ||||
|   // operator[](char*) | ||||
|   // operator[](const char*) | ||||
|   // operator[](const __FlashStringHelper*) | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE typename enable_if<IsString<TChar*>::value, | ||||
|                                   MemberProxy<JsonDocument&, TChar*> >::type | ||||
|   operator[](TChar* key) { | ||||
|     return MemberProxy<JsonDocument&, TChar*>(*this, key); | ||||
|   } | ||||
|  | ||||
|   // VariantConstRef operator[](TKey) const | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey>::value, VariantConstRef>::type | ||||
|   operator[](const TKey& key) const { | ||||
|   // operator[](const std::string&) const | ||||
|   // operator[](const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TString>::value, VariantConstRef>::type | ||||
|       operator[](const TString& key) const { | ||||
|     return getVariant()[key]; | ||||
|   } | ||||
|  | ||||
|   // VariantConstRef operator[](TKey) const; | ||||
|   // TKey = const char*, const char[N], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey*>::value, VariantConstRef>::type | ||||
|   operator[](TKey* key) const { | ||||
|   // operator[](char*) const | ||||
|   // operator[](const char*) const | ||||
|   // operator[](const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TChar*>::value, VariantConstRef>::type | ||||
|       operator[](TChar* key) const { | ||||
|     return getVariant()[key]; | ||||
|   } | ||||
|  | ||||
| @@ -157,43 +171,51 @@ class JsonDocument : public Visitable { | ||||
|     return VariantRef(&_pool, _data.get(index)); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef get(TKey* key) { | ||||
|     return VariantRef(&_pool, _data.get(wrapString(key))); | ||||
|   // get(char*) const | ||||
|   // get(const char*) const | ||||
|   // get(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef get(TChar* key) { | ||||
|     return VariantRef(&_pool, _data.get(adaptString(key))); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey>::value, VariantRef>::type get( | ||||
|       const TKey& key) { | ||||
|     return VariantRef(&_pool, _data.get(wrapString(key))); | ||||
|   // get(const std::string&) const | ||||
|   // get(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type | ||||
|   get(const TString& key) { | ||||
|     return VariantRef(&_pool, _data.get(adaptString(key))); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TKey* key) { | ||||
|     return VariantRef(&_pool, _data.getOrCreate(wrapString(key), &_pool)); | ||||
|   // getOrCreate(char*) | ||||
|   // getOrCreate(const char*) | ||||
|   // getOrCreate(const __FlashStringHelper*) | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TChar* key) { | ||||
|     return VariantRef(&_pool, _data.getOrCreate(adaptString(key), &_pool)); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TKey& key) { | ||||
|     return VariantRef(&_pool, _data.getOrCreate(wrapString(key), &_pool)); | ||||
|   // getOrCreate(const std::string&) | ||||
|   // getOrCreate(const String&) | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TString& key) { | ||||
|     return VariantRef(&_pool, _data.getOrCreate(adaptString(key), &_pool)); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE VariantRef add() { | ||||
|     return VariantRef(&_pool, _data.add(&_pool)); | ||||
|   } | ||||
|   // | ||||
|   // bool add(TValue); | ||||
|   // TValue = bool, long, int, short, float, double, serialized, VariantRef, | ||||
|   //          std::string, String, ObjectRef | ||||
|   template <typename T> | ||||
|   FORCE_INLINE bool add(const T& value) { | ||||
|  | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE bool add(const TValue& value) { | ||||
|     return add().set(value); | ||||
|   } | ||||
|   // | ||||
|   // bool add(TValue); | ||||
|   // TValue = char*, const char*, const __FlashStringHelper* | ||||
|   template <typename T> | ||||
|   FORCE_INLINE bool add(T* value) { | ||||
|  | ||||
|   // add(char*) const | ||||
|   // add(const char*) const | ||||
|   // add(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE bool add(TChar* value) { | ||||
|     return add().set(value); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../Strings/StringWrappers.hpp" | ||||
| #include "../Strings/StringAdapters.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| @@ -58,7 +58,7 @@ inline SerializedValue<T> serialized(T str) { | ||||
|  | ||||
| template <typename TChar> | ||||
| inline SerializedValue<TChar*> serialized(TChar* p) { | ||||
|   return SerializedValue<TChar*>(p, wrapString(p).size()); | ||||
|   return SerializedValue<TChar*>(p, adaptString(p).size()); | ||||
| } | ||||
|  | ||||
| template <typename TChar> | ||||
|   | ||||
| @@ -15,13 +15,13 @@ | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TObject, typename TString> | ||||
| class MemberProxy : public VariantOperators<MemberProxy<TObject, TString> >, | ||||
| template <typename TObject, typename TStringRef> | ||||
| class MemberProxy : public VariantOperators<MemberProxy<TObject, TStringRef> >, | ||||
|                     public Visitable { | ||||
|   typedef MemberProxy<TObject, TString> this_type; | ||||
|   typedef MemberProxy<TObject, TStringRef> this_type; | ||||
|  | ||||
|  public: | ||||
|   FORCE_INLINE MemberProxy(TObject variant, TString key) | ||||
|   FORCE_INLINE MemberProxy(TObject variant, TStringRef key) | ||||
|       : _object(variant), _key(key) {} | ||||
|  | ||||
|   FORCE_INLINE operator VariantConstRef() const { | ||||
| @@ -33,22 +33,18 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TString> >, | ||||
|     return *this; | ||||
|   } | ||||
|  | ||||
|   // Set the specified value | ||||
|   // | ||||
|   // operator=(const TValue&); | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          std::string, String, ArrayRef, ObjectRef | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE typename enable_if<!is_array<TValue>::value, this_type &>::type | ||||
|   operator=(const TValue &src) { | ||||
|     getOrCreateMember().set(src); | ||||
|     return *this; | ||||
|   } | ||||
|   // | ||||
|   // operator=(TValue); | ||||
|   // TValue = char*, const char*, const __FlashStringHelper* | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE this_type &operator=(TValue *src) { | ||||
|  | ||||
|   // operator=(char*) const | ||||
|   // operator=(const char*) const | ||||
|   // operator=(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE this_type &operator=(TChar *src) { | ||||
|     getOrCreateMember().set(src); | ||||
|     return *this; | ||||
|   } | ||||
| @@ -72,22 +68,17 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TString> >, | ||||
|     return getOrCreateMember().template to<TValue>(); | ||||
|   } | ||||
|  | ||||
|   // Sets the specified value. | ||||
|   // | ||||
|   // bool set(const TValue&); | ||||
|   // TValue = bool, char, long, int, short, float, double, serialized, | ||||
|   // VariantRef, | ||||
|   //          std::string, String, ArrayRef, ObjectRef | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE typename enable_if<!is_array<TValue>::value, bool>::type set( | ||||
|       const TValue &value) { | ||||
|     return getOrCreateMember().set(value); | ||||
|   } | ||||
|   // | ||||
|   // bool set(TValue); | ||||
|   // TValue = char*, const char, const __FlashStringHelper* | ||||
|   template <typename TValue> | ||||
|   FORCE_INLINE bool set(const TValue *value) { | ||||
|  | ||||
|   // set(char*) const | ||||
|   // set(const char*) const | ||||
|   // set(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE bool set(const TChar *value) { | ||||
|     return getOrCreateMember().set(value); | ||||
|   } | ||||
|  | ||||
| @@ -101,23 +92,33 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TString> >, | ||||
|     return getOrCreateMember().add(); | ||||
|   } | ||||
|  | ||||
|   template <typename TNestedKey> | ||||
|   FORCE_INLINE VariantRef get(TNestedKey *key) const { | ||||
|   // get(char*) const | ||||
|   // get(const char*) const | ||||
|   // get(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef get(TChar *key) const { | ||||
|     return getMember().get(key); | ||||
|   } | ||||
|  | ||||
|   template <typename TNestedKey> | ||||
|   FORCE_INLINE VariantRef get(const TNestedKey &key) const { | ||||
|   // get(const std::string&) const | ||||
|   // get(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE VariantRef get(const TString &key) const { | ||||
|     return getMember().get(key); | ||||
|   } | ||||
|  | ||||
|   template <typename TNestedKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TNestedKey *key) const { | ||||
|   // getOrCreate(char*) const | ||||
|   // getOrCreate(const char*) const | ||||
|   // getOrCreate(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TChar *key) const { | ||||
|     return getOrCreateMember().getOrCreate(key); | ||||
|   } | ||||
|  | ||||
|   template <typename TNestedKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TNestedKey &key) const { | ||||
|   // getOrCreate(const std::string&) const | ||||
|   // getOrCreate(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TString &key) const { | ||||
|     return getOrCreateMember().getOrCreate(key); | ||||
|   } | ||||
|  | ||||
| @@ -131,7 +132,7 @@ class MemberProxy : public VariantOperators<MemberProxy<TObject, TString> >, | ||||
|   } | ||||
|  | ||||
|   TObject _object; | ||||
|   TString _key; | ||||
|   TStringRef _key; | ||||
| }; | ||||
|  | ||||
| template <typename TObject> | ||||
|   | ||||
| @@ -16,8 +16,8 @@ void objectAccept(const CollectionData *obj, Visitor &visitor) { | ||||
|     visitor.visitNull(); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline bool objectContainsKey(const CollectionData *obj, TKey key) { | ||||
| template <typename TAdaptedString> | ||||
| inline bool objectContainsKey(const CollectionData *obj, TAdaptedString key) { | ||||
|   return obj && obj->containsKey(key); | ||||
| } | ||||
|  | ||||
| @@ -27,20 +27,20 @@ inline bool objectEquals(const CollectionData *lhs, const CollectionData *rhs) { | ||||
|   return lhs->equalsObject(*rhs); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantData *objectGet(const CollectionData *obj, TKey key) { | ||||
| template <typename TAdaptedString> | ||||
| inline VariantData *objectGet(const CollectionData *obj, TAdaptedString key) { | ||||
|   if (!obj) return 0; | ||||
|   return obj->get(key); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| void objectRemove(CollectionData *obj, TKey key) { | ||||
| template <typename TAdaptedString> | ||||
| void objectRemove(CollectionData *obj, TAdaptedString key) { | ||||
|   if (!obj) return; | ||||
|   obj->remove(key); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantData *objectGetOrCreate(CollectionData *obj, TKey key, | ||||
| template <typename TAdaptedString> | ||||
| inline VariantData *objectGetOrCreate(CollectionData *obj, TAdaptedString key, | ||||
|                                       MemoryPool *pool) { | ||||
|   if (!obj) return 0; | ||||
|  | ||||
|   | ||||
| @@ -17,23 +17,22 @@ inline ArrayRef ObjectShortcuts<TObject>::createNestedArray( | ||||
| } | ||||
|  | ||||
| template <typename TObject> | ||||
| template <typename TString> | ||||
| inline ArrayRef ObjectShortcuts<TObject>::createNestedArray( | ||||
|     TString* key) const { | ||||
| template <typename TChar> | ||||
| inline ArrayRef ObjectShortcuts<TObject>::createNestedArray(TChar* key) const { | ||||
|   return impl()->getOrCreate(key).template to<ArrayRef>(); | ||||
| } | ||||
|  | ||||
| template <typename TObject> | ||||
| template <typename TKey> | ||||
| ObjectRef ObjectShortcuts<TObject>::createNestedObject(const TKey& key) const { | ||||
| template <typename TString> | ||||
| inline ObjectRef ObjectShortcuts<TObject>::createNestedObject( | ||||
|     const TString& key) const { | ||||
|   return impl()->getOrCreate(key).template to<ObjectRef>(); | ||||
| } | ||||
| // | ||||
| // ObjectRef createNestedObject(TKey); | ||||
| // TKey = char*, const char*, char[], const char[], const __FlashStringHelper* | ||||
|  | ||||
| template <typename TObject> | ||||
| template <typename TKey> | ||||
| ObjectRef ObjectShortcuts<TObject>::createNestedObject(TKey* key) const { | ||||
| template <typename TChar> | ||||
| inline ObjectRef ObjectShortcuts<TObject>::createNestedObject( | ||||
|     TChar* key) const { | ||||
|   return impl()->getOrCreate(key).template to<ObjectRef>(); | ||||
| } | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -26,20 +26,19 @@ class ObjectRefBase { | ||||
|     objectAccept(_data, visitor); | ||||
|   } | ||||
|  | ||||
|   // Tells weither the specified key is present and associated with a value. | ||||
|   // | ||||
|   // bool containsKey(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE bool containsKey(const TKey& key) const { | ||||
|     return objectContainsKey(_data, wrapString(key)); | ||||
|   // containsKey(const std::string&) const | ||||
|   // containsKey(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE bool containsKey(const TString& key) const { | ||||
|     return objectContainsKey(_data, adaptString(key)); | ||||
|   } | ||||
|   // | ||||
|   // bool containsKey(TKey); | ||||
|   // TKey = char*, const char*, char[], const char[], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE bool containsKey(TKey* key) const { | ||||
|     return objectContainsKey(_data, wrapString(key)); | ||||
|  | ||||
|   // containsKey(char*) const | ||||
|   // containsKey(const char*) const | ||||
|   // containsKey(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE bool containsKey(TChar* key) const { | ||||
|     return objectContainsKey(_data, adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE bool isNull() const { | ||||
| @@ -83,41 +82,38 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>, | ||||
|     return iterator(); | ||||
|   } | ||||
|  | ||||
|   // Gets the value associated with the specified key. | ||||
|   // | ||||
|   // TValue get<TValue>(TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          std::string, String, ArrayConstRef, ObjectConstRef | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantConstRef get(const TKey& key) const { | ||||
|     return get_impl(wrapString(key)); | ||||
|   } | ||||
|   // | ||||
|   // TValue get<TValue>(TKey) const; | ||||
|   // TKey = char*, const char*, const __FlashStringHelper* | ||||
|   // TValue = bool, char, long, int, short, float, double, | ||||
|   //          std::string, String, ArrayConstRef, ObjectConstRef | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantConstRef get(TKey* key) const { | ||||
|     return get_impl(wrapString(key)); | ||||
|   // get(const std::string&) const | ||||
|   // get(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE VariantConstRef get(const TString& key) const { | ||||
|     return get_impl(adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   // | ||||
|   // VariantConstRef operator[](TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey>::value, VariantConstRef>::type | ||||
|   operator[](const TKey& key) const { | ||||
|     return get_impl(wrapString(key)); | ||||
|   // get(char*) const | ||||
|   // get(const char*) const | ||||
|   // get(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantConstRef get(TChar* key) const { | ||||
|     return get_impl(adaptString(key)); | ||||
|   } | ||||
|   // | ||||
|   // VariantConstRef operator[](TKey) const; | ||||
|   // TKey = const char*, const char[N], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey*>::value, VariantConstRef>::type | ||||
|   operator[](TKey* key) const { | ||||
|     return get_impl(wrapString(key)); | ||||
|  | ||||
|   // operator[](const std::string&) const | ||||
|   // operator[](const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TString>::value, VariantConstRef>::type | ||||
|       operator[](const TString& key) const { | ||||
|     return get_impl(adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   // operator[](char*) const | ||||
|   // operator[](const char*) const | ||||
|   // operator[](const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TChar*>::value, VariantConstRef>::type | ||||
|       operator[](TChar* key) const { | ||||
|     return get_impl(adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE bool operator==(ObjectConstRef rhs) const { | ||||
| @@ -125,8 +121,8 @@ class ObjectConstRef : public ObjectRefBase<const CollectionData>, | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantConstRef get_impl(TKey key) const { | ||||
|   template <typename TAdaptedString> | ||||
|   FORCE_INLINE VariantConstRef get_impl(TAdaptedString key) const { | ||||
|     return VariantConstRef(objectGet(_data, key)); | ||||
|   } | ||||
| }; | ||||
| @@ -170,30 +166,34 @@ class ObjectRef : public ObjectRefBase<CollectionData>, | ||||
|     return _data->copyFrom(*src._data, _pool); | ||||
|   } | ||||
|  | ||||
|   // Gets the value associated with the specified key. | ||||
|   // | ||||
|   // VariantRef get<TValue>(TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef get(const TKey& key) const { | ||||
|     return get_impl(wrapString(key)); | ||||
|   } | ||||
|   // | ||||
|   // VariantRef get<TValue>(TKey) const; | ||||
|   // TKey = char*, const char*, const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef get(TKey* key) const { | ||||
|     return get_impl(wrapString(key)); | ||||
|   // get(const std::string&) const | ||||
|   // get(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE VariantRef get(const TString& key) const { | ||||
|     return get_impl(adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TKey* key) const { | ||||
|     return getOrCreate_impl(wrapString(key)); | ||||
|   // get(char*) const | ||||
|   // get(const char*) const | ||||
|   // get(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef get(TChar* key) const { | ||||
|     return get_impl(adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TKey& key) const { | ||||
|     return getOrCreate_impl(wrapString(key)); | ||||
|   // getOrCreate(const std::string&) const | ||||
|   // getOrCreate(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TString& key) const { | ||||
|     return getOrCreate_impl(adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   // getOrCreate(char*) const | ||||
|   // getOrCreate(const char*) const | ||||
|   // getOrCreate(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TChar* key) const { | ||||
|     return getOrCreate_impl(adaptString(key)); | ||||
|   } | ||||
|  | ||||
|   FORCE_INLINE bool operator==(ObjectRef rhs) const { | ||||
| @@ -205,30 +205,29 @@ class ObjectRef : public ObjectRefBase<CollectionData>, | ||||
|     _data->remove(it.internal()); | ||||
|   } | ||||
|  | ||||
|   // Removes the specified key and the associated value. | ||||
|   // | ||||
|   // void remove(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE void remove(const TKey& key) const { | ||||
|     objectRemove(_data, wrapString(key)); | ||||
|   // remove(const std::string&) const | ||||
|   // remove(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE void remove(const TString& key) const { | ||||
|     objectRemove(_data, adaptString(key)); | ||||
|   } | ||||
|   // | ||||
|   // void remove(TKey); | ||||
|   // TKey = char*, const char*, char[], const char[], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE void remove(TKey* key) const { | ||||
|     objectRemove(_data, wrapString(key)); | ||||
|  | ||||
|   // remove(char*) const | ||||
|   // remove(const char*) const | ||||
|   // remove(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE void remove(TChar* key) const { | ||||
|     objectRemove(_data, adaptString(key)); | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef get_impl(TKey key) const { | ||||
|   template <typename TAdaptedString> | ||||
|   FORCE_INLINE VariantRef get_impl(TAdaptedString key) const { | ||||
|     return VariantRef(_pool, objectGet(_data, key)); | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate_impl(TKey key) const { | ||||
|   template <typename TAdaptedString> | ||||
|   FORCE_INLINE VariantRef getOrCreate_impl(TAdaptedString key) const { | ||||
|     return VariantRef(_pool, objectGetOrCreate(_data, key, _pool)); | ||||
|   } | ||||
|  | ||||
|   | ||||
| @@ -6,52 +6,52 @@ | ||||
|  | ||||
| #include "../Polyfills/attributes.hpp" | ||||
| #include "../Polyfills/type_traits.hpp" | ||||
| #include "../Strings/StringWrappers.hpp" | ||||
| #include "../Strings/StringAdapters.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| template <typename TParent, typename TKey> | ||||
| template <typename TParent, typename TStringRef> | ||||
| class MemberProxy; | ||||
|  | ||||
| template <typename TObject> | ||||
| class ObjectShortcuts { | ||||
|  public: | ||||
|   // MemberProxy operator[](TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   // operator[](const std::string&) const | ||||
|   // operator[](const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TKey>::value, | ||||
|                          MemberProxy<const TObject &, const TKey &> >::type | ||||
|       operator[](const TKey &key) const; | ||||
|   // | ||||
|   // MemberProxy operator[](TKey) const; | ||||
|   // TKey = const char*, const char[N], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey *>::value, | ||||
|                                   MemberProxy<const TObject &, TKey *> >::type | ||||
|   operator[](TKey *key) const; | ||||
|       typename enable_if<IsString<TString>::value, | ||||
|                          MemberProxy<const TObject &, const TString &> >::type | ||||
|       operator[](const TString &key) const; | ||||
|  | ||||
|   // Creates and adds a ArrayRef. | ||||
|   // | ||||
|   // ArrayRef createNestedArray(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE ArrayRef createNestedArray(const TKey &key) const; | ||||
|   // ArrayRef createNestedArray(TKey); | ||||
|   // TKey = char*, const char*, char[], const char[], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE ArrayRef createNestedArray(TKey *key) const; | ||||
|   // operator[](char*) const | ||||
|   // operator[](const char*) const | ||||
|   // operator[](const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE typename enable_if<IsString<TChar *>::value, | ||||
|                                   MemberProxy<const TObject &, TChar *> >::type | ||||
|   operator[](TChar *key) const; | ||||
|  | ||||
|   // Creates and adds a ObjectRef. | ||||
|   // | ||||
|   // ObjectRef createNestedObject(TKey); | ||||
|   // TKey = const std::string&, const String& | ||||
|   template <typename TKey> | ||||
|   ObjectRef createNestedObject(const TKey &key) const; | ||||
|   // | ||||
|   // ObjectRef createNestedObject(TKey); | ||||
|   // TKey = char*, const char*, char[], const char[], const __FlashStringHelper* | ||||
|   template <typename TKey> | ||||
|   ObjectRef createNestedObject(TKey *key) const; | ||||
|   // createNestedArray(const std::string&) const | ||||
|   // createNestedArray(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE ArrayRef createNestedArray(const TString &key) const; | ||||
|  | ||||
|   // createNestedArray(char*) const | ||||
|   // createNestedArray(const char*) const | ||||
|   // createNestedArray(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE ArrayRef createNestedArray(TChar *key) const; | ||||
|  | ||||
|   // createNestedObject(const std::string&) const | ||||
|   // createNestedObject(const String&) const | ||||
|   template <typename TString> | ||||
|   ObjectRef createNestedObject(const TString &key) const; | ||||
|  | ||||
|   // createNestedObject(char*) const | ||||
|   // createNestedObject(const char*) const | ||||
|   // createNestedObject(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   ObjectRef createNestedObject(TChar *key) const; | ||||
|  | ||||
|  private: | ||||
|   const TObject *impl() const { | ||||
|   | ||||
| @@ -13,7 +13,7 @@ class Pair { | ||||
|  public: | ||||
|   Pair(MemoryPool* pool, VariantSlot* slot) { | ||||
|     if (slot) { | ||||
|       _key = slot->key(); | ||||
|       _key = String(slot->key(), !slot->ownsKey()); | ||||
|       _value = VariantRef(pool, slot->data()); | ||||
|     } | ||||
|   } | ||||
| @@ -35,7 +35,7 @@ class PairConst { | ||||
|  public: | ||||
|   PairConst(const VariantSlot* slot) { | ||||
|     if (slot) { | ||||
|       _key = slot->key(); | ||||
|       _key = String(slot->key(), !slot->ownsKey()); | ||||
|       _value = VariantConstRef(slot->data()); | ||||
|     } | ||||
|   } | ||||
|   | ||||
| @@ -21,28 +21,28 @@ class VariantComparisons { | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T *>::value, bool>::type operator==( | ||||
|       T *lhs, TVariant rhs) { | ||||
|     return wrapString(lhs).equals(rhs.template as<const char *>()); | ||||
|     return adaptString(lhs).equals(rhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // std::string == TVariant | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T>::value, bool>::type operator==( | ||||
|       const T &lhs, TVariant rhs) { | ||||
|     return wrapString(lhs).equals(rhs.template as<const char *>()); | ||||
|     return adaptString(lhs).equals(rhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // TVariant == const char* | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T *>::value, bool>::type operator==( | ||||
|       TVariant lhs, T *rhs) { | ||||
|     return wrapString(rhs).equals(lhs.template as<const char *>()); | ||||
|     return adaptString(rhs).equals(lhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // TVariant == std::string | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T>::value, bool>::type operator==( | ||||
|       TVariant lhs, const T &rhs) { | ||||
|     return wrapString(rhs).equals(lhs.template as<const char *>()); | ||||
|     return adaptString(rhs).equals(lhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // bool/int/float == TVariant | ||||
| @@ -63,28 +63,28 @@ class VariantComparisons { | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T *>::value, bool>::type operator!=( | ||||
|       T *lhs, TVariant rhs) { | ||||
|     return !wrapString(lhs).equals(rhs.template as<const char *>()); | ||||
|     return !adaptString(lhs).equals(rhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // std::string != TVariant | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T>::value, bool>::type operator!=( | ||||
|       const T &lhs, TVariant rhs) { | ||||
|     return !wrapString(lhs).equals(rhs.template as<const char *>()); | ||||
|     return !adaptString(lhs).equals(rhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // TVariant != const char* | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T *>::value, bool>::type operator!=( | ||||
|       TVariant lhs, T *rhs) { | ||||
|     return !wrapString(rhs).equals(lhs.template as<const char *>()); | ||||
|     return !adaptString(rhs).equals(lhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // TVariant != std::string | ||||
|   template <typename T> | ||||
|   friend typename enable_if<IsString<T>::value, bool>::type operator!=( | ||||
|       TVariant lhs, const T &rhs) { | ||||
|     return !wrapString(rhs).equals(lhs.template as<const char *>()); | ||||
|     return !adaptString(rhs).equals(lhs.template as<const char *>()); | ||||
|   } | ||||
|  | ||||
|   // bool/int/float != TVariant | ||||
|   | ||||
| @@ -8,9 +8,9 @@ | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| class ArduinoStringWrapper { | ||||
| class ArduinoStringAdapter { | ||||
|  public: | ||||
|   ArduinoStringWrapper(const ::String& str) : _str(&str) {} | ||||
|   ArduinoStringAdapter(const ::String& str) : _str(&str) {} | ||||
| 
 | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     if (isNull()) return NULL; | ||||
| @@ -40,6 +40,10 @@ class ArduinoStringWrapper { | ||||
|     return _str->length(); | ||||
|   } | ||||
| 
 | ||||
|   bool isStatic() const { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|  private: | ||||
|   const ::String* _str; | ||||
| }; | ||||
| @@ -50,8 +54,8 @@ struct IsString< ::String> : true_type {}; | ||||
| template <> | ||||
| struct IsString< ::StringSumHelper> : true_type {}; | ||||
| 
 | ||||
| inline ArduinoStringWrapper wrapString(const ::String& str) { | ||||
|   return ArduinoStringWrapper(str); | ||||
| inline ArduinoStringAdapter adaptString(const ::String& str) { | ||||
|   return ArduinoStringAdapter(str); | ||||
| } | ||||
| 
 | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| @@ -9,9 +9,9 @@ | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| class ConstRamStringWrapper { | ||||
| class ConstRamStringAdapter { | ||||
|  public: | ||||
|   ConstRamStringWrapper(const char* str = 0) : _str(str) {} | ||||
|   ConstRamStringAdapter(const char* str = 0) : _str(str) {} | ||||
| 
 | ||||
|   bool equals(const char* expected) const { | ||||
|     const char* actual = _str; | ||||
| @@ -23,25 +23,29 @@ class ConstRamStringWrapper { | ||||
|     return !_str; | ||||
|   } | ||||
| 
 | ||||
|   // template <typename TMemoryPool>
 | ||||
|   // const char* save(TMemoryPool*) const {
 | ||||
|   //   return _str;
 | ||||
|   // }
 | ||||
|   template <typename TMemoryPool> | ||||
|   char* save(TMemoryPool*) const { | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   size_t size() const { | ||||
|     return strlen(_str); | ||||
|   } | ||||
| 
 | ||||
|   const char* c_str() const { | ||||
|   const char* data() const { | ||||
|     return _str; | ||||
|   } | ||||
| 
 | ||||
|   bool isStatic() const { | ||||
|     return true; | ||||
|   } | ||||
| 
 | ||||
|  protected: | ||||
|   const char* _str; | ||||
| }; | ||||
| 
 | ||||
| inline ConstRamStringWrapper wrapString(const char* str) { | ||||
|   return ConstRamStringWrapper(str); | ||||
| inline ConstRamStringAdapter adaptString(const char* str) { | ||||
|   return ConstRamStringAdapter(str); | ||||
| } | ||||
| 
 | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| @@ -6,9 +6,9 @@ | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| class FlashStringWrapper { | ||||
| class FlashStringAdapter { | ||||
|  public: | ||||
|   FlashStringWrapper(const __FlashStringHelper* str) : _str(str) {} | ||||
|   FlashStringAdapter(const __FlashStringHelper* str) : _str(str) {} | ||||
| 
 | ||||
|   bool equals(const char* expected) const { | ||||
|     const char* actual = reinterpret_cast<const char*>(_str); | ||||
| @@ -28,16 +28,24 @@ class FlashStringWrapper { | ||||
|     return dup; | ||||
|   } | ||||
| 
 | ||||
|   const char* data() const { | ||||
|     return 0; | ||||
|   } | ||||
| 
 | ||||
|   size_t size() const { | ||||
|     return strlen_P(reinterpret_cast<const char*>(_str)); | ||||
|   } | ||||
| 
 | ||||
|   bool isStatic() const { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|  private: | ||||
|   const __FlashStringHelper* _str; | ||||
| }; | ||||
| 
 | ||||
| inline FlashStringWrapper wrapString(const __FlashStringHelper* str) { | ||||
|   return FlashStringWrapper(str); | ||||
| inline FlashStringAdapter adaptString(const __FlashStringHelper* str) { | ||||
|   return FlashStringAdapter(str); | ||||
| } | ||||
| 
 | ||||
| template <> | ||||
| @@ -4,13 +4,13 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "ConstRamStringWrapper.hpp" | ||||
| #include "ConstRamStringAdapter.hpp" | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| class RamStringWrapper : public ConstRamStringWrapper { | ||||
| class RamStringAdapter : public ConstRamStringAdapter { | ||||
|  public: | ||||
|   RamStringWrapper(const char* str) : ConstRamStringWrapper(str) {} | ||||
|   RamStringAdapter(const char* str) : ConstRamStringAdapter(str) {} | ||||
| 
 | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     if (!_str) return NULL; | ||||
| @@ -19,15 +19,19 @@ class RamStringWrapper : public ConstRamStringWrapper { | ||||
|     if (dup) memcpy(dup, _str, n); | ||||
|     return dup; | ||||
|   } | ||||
| 
 | ||||
|   bool isStatic() const { | ||||
|     return false; | ||||
|   } | ||||
| }; | ||||
| 
 | ||||
| template <typename TChar> | ||||
| inline RamStringWrapper wrapString(const TChar* str) { | ||||
|   return RamStringWrapper(reinterpret_cast<const char*>(str)); | ||||
| inline RamStringAdapter adaptString(const TChar* str) { | ||||
|   return RamStringAdapter(reinterpret_cast<const char*>(str)); | ||||
| } | ||||
| 
 | ||||
| inline RamStringWrapper wrapString(char* str) { | ||||
|   return RamStringWrapper(str); | ||||
| inline RamStringAdapter adaptString(char* str) { | ||||
|   return RamStringAdapter(str); | ||||
| } | ||||
| 
 | ||||
| template <typename TChar> | ||||
| @@ -6,9 +6,9 @@ | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| class SizedFlashStringWrapper { | ||||
| class SizedFlashStringAdapter { | ||||
|  public: | ||||
|   SizedFlashStringWrapper(const __FlashStringHelper* str, size_t sz) | ||||
|   SizedFlashStringAdapter(const __FlashStringHelper* str, size_t sz) | ||||
|       : _str(str), _size(sz) {} | ||||
| 
 | ||||
|   bool equals(const char* expected) const { | ||||
| @@ -32,13 +32,17 @@ class SizedFlashStringWrapper { | ||||
|     return strlen_P(reinterpret_cast<const char*>(_str)); | ||||
|   } | ||||
| 
 | ||||
|   bool isStatic() const { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|  private: | ||||
|   const __FlashStringHelper* _str; | ||||
|   size_t _size; | ||||
| }; | ||||
| 
 | ||||
| inline SizedFlashStringWrapper wrapString(const __FlashStringHelper* str, | ||||
|                                           size_t sz) { | ||||
|   return SizedFlashStringWrapper(str, sz); | ||||
| inline SizedFlashStringAdapter adaptString(const __FlashStringHelper* str, | ||||
|                                            size_t sz) { | ||||
|   return SizedFlashStringAdapter(str, sz); | ||||
| } | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| @@ -8,9 +8,9 @@ | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| class SizedRamStringWrapper { | ||||
| class SizedRamStringAdapter { | ||||
|  public: | ||||
|   SizedRamStringWrapper(const char* str, size_t n) : _str(str), _size(n) {} | ||||
|   SizedRamStringAdapter(const char* str, size_t n) : _str(str), _size(n) {} | ||||
| 
 | ||||
|   bool equals(const char* expected) const { | ||||
|     const char* actual = reinterpret_cast<const char*>(_str); | ||||
| @@ -33,14 +33,18 @@ class SizedRamStringWrapper { | ||||
|     return strlen(reinterpret_cast<const char*>(_str)); | ||||
|   } | ||||
| 
 | ||||
|   bool isStatic() const { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|  private: | ||||
|   const char* _str; | ||||
|   size_t _size; | ||||
| }; | ||||
| 
 | ||||
| template <typename TChar> | ||||
| inline SizedRamStringWrapper wrapString(const TChar* str, size_t size) { | ||||
|   return SizedRamStringWrapper(reinterpret_cast<const char*>(str), size); | ||||
| inline SizedRamStringAdapter adaptString(const TChar* str, size_t size) { | ||||
|   return SizedRamStringAdapter(reinterpret_cast<const char*>(str), size); | ||||
| } | ||||
| 
 | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| @@ -8,9 +8,9 @@ | ||||
| 
 | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
| 
 | ||||
| class StlStringWrapper { | ||||
| class StlStringAdapter { | ||||
|  public: | ||||
|   StlStringWrapper(const std::string& str) : _str(&str) {} | ||||
|   StlStringAdapter(const std::string& str) : _str(&str) {} | ||||
| 
 | ||||
|   char* save(MemoryPool* pool) const { | ||||
|     size_t n = _str->length() + 1; | ||||
| @@ -36,6 +36,10 @@ class StlStringWrapper { | ||||
|     return _str->size(); | ||||
|   } | ||||
| 
 | ||||
|   bool isStatic() const { | ||||
|     return false; | ||||
|   } | ||||
| 
 | ||||
|  private: | ||||
|   const std::string* _str; | ||||
| }; | ||||
| @@ -43,8 +47,8 @@ class StlStringWrapper { | ||||
| template <> | ||||
| struct IsString<std::string> : true_type {}; | ||||
| 
 | ||||
| inline StlStringWrapper wrapString(const std::string& str) { | ||||
|   return StlStringWrapper(str); | ||||
| inline StlStringAdapter adaptString(const std::string& str) { | ||||
|   return StlStringAdapter(str); | ||||
| } | ||||
| 
 | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| @@ -4,12 +4,15 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "ConstRamStringAdapter.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| class String { | ||||
|  public: | ||||
|   String() : _data(0) {} | ||||
|   String(const char* slot) : _data(slot) {} | ||||
|   String() : _data(0), _isStatic(true) {} | ||||
|   String(const char* data, bool isStaticData = true) | ||||
|       : _data(data), _isStatic(isStaticData) {} | ||||
|  | ||||
|   const char* c_str() const { | ||||
|     return _data; | ||||
| @@ -19,6 +22,10 @@ class String { | ||||
|     return !_data; | ||||
|   } | ||||
|  | ||||
|   bool isStatic() const { | ||||
|     return _isStatic; | ||||
|   } | ||||
|  | ||||
|   friend bool operator==(String lhs, String rhs) { | ||||
|     if (lhs._data == rhs._data) return true; | ||||
|     if (!lhs._data) return false; | ||||
| @@ -28,5 +35,31 @@ class String { | ||||
|  | ||||
|  private: | ||||
|   const char* _data; | ||||
|   bool _isStatic; | ||||
| }; | ||||
|  | ||||
| class StringAdapter : public RamStringAdapter { | ||||
|  public: | ||||
|   StringAdapter(const String& str) | ||||
|       : RamStringAdapter(str.c_str()), _isStatic(str.isStatic()) {} | ||||
|  | ||||
|   bool isStatic() const { | ||||
|     return _isStatic; | ||||
|   } | ||||
|  | ||||
|   /*  const char* save(MemoryPool* pool) const { | ||||
|       if (_isStatic) return c_str(); | ||||
|       return RamStringAdapter::save(pool); | ||||
|     }*/ | ||||
|  | ||||
|  private: | ||||
|   bool _isStatic; | ||||
| }; | ||||
|  | ||||
| template <> | ||||
| struct IsString<String> : true_type {}; | ||||
|  | ||||
| inline StringAdapter adaptString(const String& str) { | ||||
|   return StringAdapter(str); | ||||
| } | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -18,19 +18,19 @@ template <typename T> | ||||
| struct IsString<T&> : IsString<T> {}; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE
 | ||||
| 
 | ||||
| #include "ConstRamStringWrapper.hpp" | ||||
| #include "RamStringWrapper.hpp" | ||||
| #include "SizedRamStringWrapper.hpp" | ||||
| #include "ConstRamStringAdapter.hpp" | ||||
| #include "RamStringAdapter.hpp" | ||||
| #include "SizedRamStringAdapter.hpp" | ||||
| 
 | ||||
| #if ARDUINOJSON_ENABLE_STD_STRING | ||||
| #include "StlStringWrapper.hpp" | ||||
| #include "StlStringAdapter.hpp" | ||||
| #endif | ||||
| 
 | ||||
| #if ARDUINOJSON_ENABLE_ARDUINO_STRING | ||||
| #include "ArduinoStringWrapper.hpp" | ||||
| #include "ArduinoStringAdapter.hpp" | ||||
| #endif | ||||
| 
 | ||||
| #if ARDUINOJSON_ENABLE_PROGMEM | ||||
| #include "FlashStringWrapper.hpp" | ||||
| #include "SizedFlashStringWrapper.hpp" | ||||
| #include "FlashStringAdapter.hpp" | ||||
| #include "SizedFlashStringAdapter.hpp" | ||||
| #endif | ||||
| @@ -6,24 +6,21 @@ | ||||
|  | ||||
| #include "../Memory/MemoryPool.hpp" | ||||
| #include "../Polyfills/assert.hpp" | ||||
| #include "../Strings/StringWrappers.hpp" | ||||
| #include "../Strings/StringAdapters.hpp" | ||||
| #include "VariantData.hpp" | ||||
|  | ||||
| namespace ARDUINOJSON_NAMESPACE { | ||||
|  | ||||
| template <typename TKey> | ||||
| inline bool slotSetKey(VariantSlot* var, TKey key, MemoryPool* pool) { | ||||
| template <typename TAdaptedString> | ||||
| inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) { | ||||
|   if (!var) return false; | ||||
|   char* dup = key.save(pool); | ||||
|   if (!dup) return false; | ||||
|   var->setOwnedKey(dup); | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| inline bool slotSetKey(VariantSlot* var, ConstRamStringWrapper key, | ||||
|                        MemoryPool*) { | ||||
|   if (!var) return false; | ||||
|   var->setLinkedKey(key.c_str()); | ||||
|   if (key.isStatic()) { | ||||
|     var->setLinkedKey(key.data()); | ||||
|   } else { | ||||
|     char* dup = key.save(pool); | ||||
|     if (!dup) return false; | ||||
|     var->setOwnedKey(dup); | ||||
|   } | ||||
|   return true; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -89,7 +89,7 @@ class VariantData { | ||||
|       case VALUE_IS_OBJECT: | ||||
|         return toObject().copyFrom(src._content.asCollection, pool); | ||||
|       case VALUE_IS_OWNED_STRING: | ||||
|         return setOwnedString(RamStringWrapper(src._content.asString), pool); | ||||
|         return setOwnedString(RamStringAdapter(src._content.asString), pool); | ||||
|       case VALUE_IS_OWNED_RAW: | ||||
|         return setOwnedRaw( | ||||
|             serialized(src._content.asRaw.data, src._content.asRaw.size), pool); | ||||
| @@ -186,7 +186,7 @@ class VariantData { | ||||
|  | ||||
|   template <typename T> | ||||
|   bool setOwnedRaw(SerializedValue<T> value, MemoryPool *pool) { | ||||
|     char *dup = wrapString(value.data(), value.size()).save(pool); | ||||
|     char *dup = adaptString(value.data(), value.size()).save(pool); | ||||
|     if (dup) { | ||||
|       setType(VALUE_IS_OWNED_RAW); | ||||
|       _content.asRaw.data = dup; | ||||
| @@ -289,13 +289,13 @@ class VariantData { | ||||
|     return isArray() ? _content.asCollection.get(index) : 0; | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   VariantData *get(TKey key) const { | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData *get(TAdaptedString key) const { | ||||
|     return isObject() ? _content.asCollection.get(key) : 0; | ||||
|   } | ||||
|  | ||||
|   template <typename TKey> | ||||
|   VariantData *getOrCreate(TKey key, MemoryPool *pool) { | ||||
|   template <typename TAdaptedString> | ||||
|   VariantData *getOrCreate(TAdaptedString key, MemoryPool *pool) { | ||||
|     if (isNull()) toObject(); | ||||
|     if (!isObject()) return 0; | ||||
|     VariantData *var = _content.asCollection.get(key); | ||||
|   | ||||
| @@ -150,16 +150,16 @@ inline NO_INLINE VariantData *variantAdd(VariantData *var, MemoryPool *pool) { | ||||
|   return var != 0 ? var->add(pool) : 0; | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| NO_INLINE VariantData *variantGetOrCreate(VariantData *var, TKey *key, | ||||
| template <typename TChar> | ||||
| NO_INLINE VariantData *variantGetOrCreate(VariantData *var, TChar *key, | ||||
|                                           MemoryPool *pool) { | ||||
|   return var != 0 ? var->getOrCreate(wrapString(key), pool) : 0; | ||||
|   return var != 0 ? var->getOrCreate(adaptString(key), pool) : 0; | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| NO_INLINE VariantData *variantGetOrCreate(VariantData *var, const TKey &key, | ||||
| template <typename TString> | ||||
| NO_INLINE VariantData *variantGetOrCreate(VariantData *var, const TString &key, | ||||
|                                           MemoryPool *pool) { | ||||
|   return var != 0 ? var->getOrCreate(wrapString(key), pool) : 0; | ||||
|   return var != 0 ? var->getOrCreate(adaptString(key), pool) : 0; | ||||
| } | ||||
|  | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -110,24 +110,24 @@ inline VariantRef VariantRef::get(size_t index) const { | ||||
|   return VariantRef(_pool, _data != 0 ? _data->get(index) : 0); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantRef VariantRef::get(TKey *key) const { | ||||
|   return VariantRef(_pool, _data != 0 ? _data->get(wrapString(key)) : 0); | ||||
| template <typename TChar> | ||||
| inline VariantRef VariantRef::get(TChar *key) const { | ||||
|   return VariantRef(_pool, _data != 0 ? _data->get(adaptString(key)) : 0); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline typename enable_if<IsString<TKey>::value, VariantRef>::type | ||||
| VariantRef::get(const TKey &key) const { | ||||
|   return VariantRef(_pool, _data != 0 ? _data->get(wrapString(key)) : 0); | ||||
| template <typename TString> | ||||
| inline typename enable_if<IsString<TString>::value, VariantRef>::type | ||||
| VariantRef::get(const TString &key) const { | ||||
|   return VariantRef(_pool, _data != 0 ? _data->get(adaptString(key)) : 0); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantRef VariantRef::getOrCreate(TKey *key) const { | ||||
| template <typename TChar> | ||||
| inline VariantRef VariantRef::getOrCreate(TChar *key) const { | ||||
|   return VariantRef(_pool, variantGetOrCreate(_data, key, _pool)); | ||||
| } | ||||
|  | ||||
| template <typename TKey> | ||||
| inline VariantRef VariantRef::getOrCreate(const TKey &key) const { | ||||
| template <typename TString> | ||||
| inline VariantRef VariantRef::getOrCreate(const TString &key) const { | ||||
|   return VariantRef(_pool, variantGetOrCreate(_data, key, _pool)); | ||||
| } | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -194,7 +194,7 @@ class VariantRef : public VariantRefBase<VariantData>, | ||||
|   FORCE_INLINE bool set( | ||||
|       const T &value, | ||||
|       typename enable_if<IsString<T>::value>::type * = 0) const { | ||||
|     return variantSetOwnedString(_data, wrapString(value), _pool); | ||||
|     return variantSetOwnedString(_data, adaptString(value), _pool); | ||||
|   } | ||||
|  | ||||
|   // set(char*) | ||||
| @@ -202,7 +202,7 @@ class VariantRef : public VariantRefBase<VariantData>, | ||||
|   template <typename T> | ||||
|   FORCE_INLINE bool set( | ||||
|       T *value, typename enable_if<IsString<T *>::value>::type * = 0) const { | ||||
|     return variantSetOwnedString(_data, wrapString(value), _pool); | ||||
|     return variantSetOwnedString(_data, adaptString(value), _pool); | ||||
|   } | ||||
|  | ||||
|   // set(const char*); | ||||
| @@ -285,20 +285,27 @@ class VariantRef : public VariantRefBase<VariantData>, | ||||
|  | ||||
|   FORCE_INLINE VariantRef get(size_t) const; | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef get(TKey *) const; | ||||
|   // get(const char*) const | ||||
|   // get(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef get(TChar *) const; | ||||
|  | ||||
|   // get(const char*) | ||||
|   // get(const __FlashStringHelper*) | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE typename enable_if<IsString<TKey>::value, VariantRef>::type get( | ||||
|       const TKey &) const; | ||||
|   // get(const std::string&) const | ||||
|   // get(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE typename enable_if<IsString<TString>::value, VariantRef>::type | ||||
|   get(const TString &) const; | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TKey *) const; | ||||
|   // getOrCreate(char*) const | ||||
|   // getOrCreate(const char*) const | ||||
|   // getOrCreate(const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE VariantRef getOrCreate(TChar *) const; | ||||
|  | ||||
|   template <typename TKey> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TKey &) const; | ||||
|   // getOrCreate(const std::string&) const | ||||
|   // getOrCreate(const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE VariantRef getOrCreate(const TString &) const; | ||||
|  | ||||
|  private: | ||||
|   MemoryPool *_pool; | ||||
| @@ -329,24 +336,24 @@ class VariantConstRef : public VariantRefBase<const VariantData>, | ||||
|  | ||||
|   FORCE_INLINE VariantConstRef operator[](size_t index) const; | ||||
|  | ||||
|   // | ||||
|   // const VariantConstRef operator[](TKey) const; | ||||
|   // TKey = const std::string&, const String& | ||||
|   // operator[](const std::string&) const | ||||
|   // operator[](const String&) const | ||||
|   template <typename TString> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TString>::value, VariantConstRef>::type | ||||
|       operator[](const TString &key) const { | ||||
|     return VariantConstRef(objectGet(variantAsObject(_data), wrapString(key))); | ||||
|     return VariantConstRef(objectGet(variantAsObject(_data), adaptString(key))); | ||||
|   } | ||||
|   // | ||||
|   // VariantConstRef operator[](TKey); | ||||
|   // TKey = const char*, const char[N], const __FlashStringHelper* | ||||
|   template <typename TString> | ||||
|  | ||||
|   // operator[](char*) const | ||||
|   // operator[](const char*) const | ||||
|   // operator[](const __FlashStringHelper*) const | ||||
|   template <typename TChar> | ||||
|   FORCE_INLINE | ||||
|       typename enable_if<IsString<TString *>::value, VariantConstRef>::type | ||||
|       operator[](TString *key) const { | ||||
|       typename enable_if<IsString<TChar *>::value, VariantConstRef>::type | ||||
|       operator[](TChar *key) const { | ||||
|     const CollectionData *obj = variantAsObject(_data); | ||||
|     return VariantConstRef(obj ? obj->get(wrapString(key)) : 0); | ||||
|     return VariantConstRef(obj ? obj->get(adaptString(key)) : 0); | ||||
|   } | ||||
| }; | ||||
| }  // namespace ARDUINOJSON_NAMESPACE | ||||
|   | ||||
| @@ -141,6 +141,18 @@ TEST_CASE("JsonObject::operator[]") { | ||||
|     REQUIRE(expectedSize <= doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should duplicate a non-static JsonString key") { | ||||
|     obj[JsonString("hello", false)] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1) + JSON_STRING_SIZE(6); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should not duplicate a static JsonString key") { | ||||
|     obj[JsonString("hello", true)] = "world"; | ||||
|     const size_t expectedSize = JSON_OBJECT_SIZE(1); | ||||
|     REQUIRE(expectedSize == doc.memoryUsage()); | ||||
|   } | ||||
|  | ||||
|   SECTION("should ignore null key") { | ||||
|     // object must have a value to make a call to strcmp() | ||||
|     obj["dummy"] = 42; | ||||
|   | ||||
| @@ -71,6 +71,26 @@ TEST_CASE("JsonVariant and strings") { | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores static JsonString by reference") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(JsonString(str, true)); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
|  | ||||
|   SECTION("stores non-static JsonString by copy") { | ||||
|     char str[16]; | ||||
|  | ||||
|     strcpy(str, "hello"); | ||||
|     variant.set(JsonString(str, false)); | ||||
|     strcpy(str, "world"); | ||||
|  | ||||
|     REQUIRE(variant == "hello"); | ||||
|   } | ||||
| } | ||||
|  | ||||
| TEST_CASE("JsonVariant with not enough memory") { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user