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