forked from bblanchon/ArduinoJson
Attach copy policy to string adapters
This commit is contained in:
@ -38,15 +38,14 @@ class CollectionData {
|
|||||||
|
|
||||||
// Object only
|
// Object only
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
VariantData* addMember(TAdaptedString key, MemoryPool* pool, TStoragePolicy);
|
VariantData* addMember(TAdaptedString key, MemoryPool* pool);
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
VariantData* getMember(TAdaptedString key) const;
|
VariantData* getMember(TAdaptedString key) const;
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool,
|
VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool);
|
||||||
TStoragePolicy);
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
template <typename TAdaptedString>
|
||||||
void removeMember(TAdaptedString key) {
|
void removeMember(TAdaptedString key) {
|
||||||
|
@ -33,12 +33,11 @@ inline VariantData* CollectionData::addElement(MemoryPool* pool) {
|
|||||||
return slotData(addSlot(pool));
|
return slotData(addSlot(pool));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
inline VariantData* CollectionData::addMember(TAdaptedString key,
|
||||||
MemoryPool* pool,
|
MemoryPool* pool) {
|
||||||
TStoragePolicy storage) {
|
|
||||||
VariantSlot* slot = addSlot(pool);
|
VariantSlot* slot = addSlot(pool);
|
||||||
if (!slotSetKey(slot, key, pool, storage)) {
|
if (!slotSetKey(slot, key, pool)) {
|
||||||
removeSlot(slot);
|
removeSlot(slot);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -62,7 +61,7 @@ inline bool CollectionData::copyFrom(const CollectionData& src,
|
|||||||
VariantData* var;
|
VariantData* var;
|
||||||
if (s->key() != 0) {
|
if (s->key() != 0) {
|
||||||
String key(s->key(), s->ownsKey() ? String::Copied : String::Linked);
|
String key(s->key(), s->ownsKey() ? String::Copied : String::Linked);
|
||||||
var = addMember(adaptString(key), pool, getStringStoragePolicy(key));
|
var = addMember(adaptString(key), pool);
|
||||||
} else {
|
} else {
|
||||||
var = addElement(pool);
|
var = addElement(pool);
|
||||||
}
|
}
|
||||||
@ -110,9 +109,9 @@ inline VariantData* CollectionData::getMember(TAdaptedString key) const {
|
|||||||
return slot ? slot->data() : 0;
|
return slot ? slot->data() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
inline VariantData* CollectionData::getOrAddMember(
|
inline VariantData* CollectionData::getOrAddMember(TAdaptedString key,
|
||||||
TAdaptedString key, MemoryPool* pool, TStoragePolicy storage_policy) {
|
MemoryPool* pool) {
|
||||||
// ignore null key
|
// ignore null key
|
||||||
if (key.isNull())
|
if (key.isNull())
|
||||||
return 0;
|
return 0;
|
||||||
@ -122,7 +121,7 @@ inline VariantData* CollectionData::getOrAddMember(
|
|||||||
if (slot)
|
if (slot)
|
||||||
return slot->data();
|
return slot->data();
|
||||||
|
|
||||||
return addMember(key, pool, storage_policy);
|
return addMember(key, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline VariantData* CollectionData::getElement(size_t index) const {
|
inline VariantData* CollectionData::getElement(size_t index) const {
|
||||||
|
@ -208,4 +208,35 @@ class MemoryPool {
|
|||||||
bool _overflowed;
|
bool _overflowed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename TAdaptedString, typename TCallback>
|
||||||
|
bool storeString(MemoryPool* pool, TAdaptedString str, CopyStringStoragePolicy,
|
||||||
|
TCallback callback) {
|
||||||
|
const char* copy = pool->saveString(str);
|
||||||
|
String storedString(copy, str.size(), String::Copied);
|
||||||
|
callback(storedString);
|
||||||
|
return copy != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString, typename TCallback>
|
||||||
|
bool storeString(MemoryPool*, TAdaptedString str, LinkStringStoragePolicy,
|
||||||
|
TCallback callback) {
|
||||||
|
String storedString(str.data(), str.size(), String::Linked);
|
||||||
|
callback(storedString);
|
||||||
|
return !str.isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString, typename TCallback>
|
||||||
|
bool storeString(MemoryPool* pool, TAdaptedString str,
|
||||||
|
LinkOrCopyStringStoragePolicy policy, TCallback callback) {
|
||||||
|
if (policy.link)
|
||||||
|
return storeString(pool, str, LinkStringStoragePolicy(), callback);
|
||||||
|
else
|
||||||
|
return storeString(pool, str, CopyStringStoragePolicy(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString, typename TCallback>
|
||||||
|
bool storeString(MemoryPool* pool, TAdaptedString str, TCallback callback) {
|
||||||
|
return storeString(pool, str, str.storagePolicy(), callback);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -61,6 +61,10 @@ class FlashString {
|
|||||||
::memcpy_P(p, s._str, n);
|
::memcpy_P(p, s._str, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CopyStringStoragePolicy storagePolicy() {
|
||||||
|
return CopyStringStoragePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* _str;
|
const char* _str;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
|
@ -10,8 +10,21 @@
|
|||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
inline SizedRamString adaptString(const String& s) {
|
class JsonStringAdapter : public SizedRamString {
|
||||||
return SizedRamString(s.c_str(), s.size());
|
public:
|
||||||
|
JsonStringAdapter(const String& s)
|
||||||
|
: SizedRamString(s.c_str(), s.size()), _linked(s.isLinked()) {}
|
||||||
|
|
||||||
|
LinkOrCopyStringStoragePolicy storagePolicy() {
|
||||||
|
return LinkOrCopyStringStoragePolicy(_linked);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _linked;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline JsonStringAdapter adaptString(const String& s) {
|
||||||
|
return JsonStringAdapter(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <ArduinoJson/Polyfills/assert.hpp>
|
#include <ArduinoJson/Polyfills/assert.hpp>
|
||||||
#include <ArduinoJson/Strings/IsString.hpp>
|
#include <ArduinoJson/Strings/IsString.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StoragePolicy.hpp>
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
@ -48,6 +49,10 @@ class ZeroTerminatedRamString {
|
|||||||
return stringCompare(a, b) == 0;
|
return stringCompare(a, b) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CopyStringStoragePolicy storagePolicy() {
|
||||||
|
return CopyStringStoragePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char* _str;
|
const char* _str;
|
||||||
};
|
};
|
||||||
@ -55,7 +60,7 @@ class ZeroTerminatedRamString {
|
|||||||
template <>
|
template <>
|
||||||
struct IsString<char*> : true_type {};
|
struct IsString<char*> : true_type {};
|
||||||
|
|
||||||
inline ZeroTerminatedRamString adaptString(const char* s) {
|
inline ZeroTerminatedRamString adaptString(char* s) {
|
||||||
return ZeroTerminatedRamString(s);
|
return ZeroTerminatedRamString(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,14 +68,27 @@ template <>
|
|||||||
struct IsString<unsigned char*> : true_type {};
|
struct IsString<unsigned char*> : true_type {};
|
||||||
|
|
||||||
inline ZeroTerminatedRamString adaptString(const unsigned char* s) {
|
inline ZeroTerminatedRamString adaptString(const unsigned char* s) {
|
||||||
return adaptString(reinterpret_cast<const char*>(s));
|
return ZeroTerminatedRamString(reinterpret_cast<const char*>(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct IsString<signed char*> : true_type {};
|
struct IsString<signed char*> : true_type {};
|
||||||
|
|
||||||
inline ZeroTerminatedRamString adaptString(const signed char* s) {
|
inline ZeroTerminatedRamString adaptString(const signed char* s) {
|
||||||
return adaptString(reinterpret_cast<const char*>(s));
|
return ZeroTerminatedRamString(reinterpret_cast<const char*>(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
class StaticStringAdapter : public ZeroTerminatedRamString {
|
||||||
|
public:
|
||||||
|
StaticStringAdapter(const char* str) : ZeroTerminatedRamString(str) {}
|
||||||
|
|
||||||
|
LinkStringStoragePolicy storagePolicy() {
|
||||||
|
return LinkStringStoragePolicy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline StaticStringAdapter adaptString(const char* s) {
|
||||||
|
return StaticStringAdapter(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
class SizedRamString {
|
class SizedRamString {
|
||||||
@ -97,6 +115,10 @@ class SizedRamString {
|
|||||||
return _str;
|
return _str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CopyStringStoragePolicy storagePolicy() {
|
||||||
|
return CopyStringStoragePolicy();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const char* _str;
|
const char* _str;
|
||||||
size_t _size;
|
size_t _size;
|
||||||
|
@ -4,53 +4,16 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
|
||||||
#include <ArduinoJson/Strings/String.hpp>
|
|
||||||
|
|
||||||
namespace ARDUINOJSON_NAMESPACE {
|
namespace ARDUINOJSON_NAMESPACE {
|
||||||
|
|
||||||
struct LinkStringStoragePolicy {
|
struct LinkStringStoragePolicy {};
|
||||||
template <typename TAdaptedString, typename TCallback>
|
|
||||||
bool store(TAdaptedString str, MemoryPool*, TCallback callback) {
|
struct CopyStringStoragePolicy {};
|
||||||
String storedString(str.data(), str.size(), String::Linked);
|
|
||||||
callback(storedString);
|
struct LinkOrCopyStringStoragePolicy {
|
||||||
return !str.isNull();
|
LinkOrCopyStringStoragePolicy(bool l) : link(l) {}
|
||||||
}
|
|
||||||
|
bool link;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CopyStringStoragePolicy {
|
|
||||||
template <typename TAdaptedString, typename TCallback>
|
|
||||||
bool store(TAdaptedString str, MemoryPool* pool, TCallback callback);
|
|
||||||
};
|
|
||||||
|
|
||||||
class LinkOrCopyStringStoragePolicy : LinkStringStoragePolicy,
|
|
||||||
CopyStringStoragePolicy {
|
|
||||||
public:
|
|
||||||
LinkOrCopyStringStoragePolicy(bool link) : _link(link) {}
|
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TCallback>
|
|
||||||
bool store(TAdaptedString str, MemoryPool* pool, TCallback callback) {
|
|
||||||
if (_link)
|
|
||||||
return LinkStringStoragePolicy::store(str, pool, callback);
|
|
||||||
else
|
|
||||||
return CopyStringStoragePolicy::store(str, pool, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool _link;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
inline CopyStringStoragePolicy getStringStoragePolicy(const T&) {
|
|
||||||
return CopyStringStoragePolicy();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline LinkStringStoragePolicy getStringStoragePolicy(const char*) {
|
|
||||||
return LinkStringStoragePolicy();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline LinkOrCopyStringStoragePolicy getStringStoragePolicy(const String& s) {
|
|
||||||
return LinkOrCopyStringStoragePolicy(s.isLinked());
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
@ -118,8 +118,7 @@ struct Converter<T, typename enable_if<is_floating_point<T>::value>::type>
|
|||||||
template <>
|
template <>
|
||||||
struct Converter<const char*> : private VariantAttorney {
|
struct Converter<const char*> : private VariantAttorney {
|
||||||
static void toJson(const char* src, VariantRef dst) {
|
static void toJson(const char* src, VariantRef dst) {
|
||||||
variantSetString(getData(dst), adaptString(src), getPool(dst),
|
variantSetString(getData(dst), adaptString(src), getPool(dst));
|
||||||
getStringStoragePolicy(src));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* fromJson(VariantConstRef src) {
|
static const char* fromJson(VariantConstRef src) {
|
||||||
@ -136,8 +135,7 @@ struct Converter<const char*> : private VariantAttorney {
|
|||||||
template <>
|
template <>
|
||||||
struct Converter<String> : private VariantAttorney {
|
struct Converter<String> : private VariantAttorney {
|
||||||
static void toJson(String src, VariantRef dst) {
|
static void toJson(String src, VariantRef dst) {
|
||||||
variantSetString(getData(dst), adaptString(src), getPool(dst),
|
variantSetString(getData(dst), adaptString(src), getPool(dst));
|
||||||
getStringStoragePolicy(src));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String fromJson(VariantConstRef src) {
|
static String fromJson(VariantConstRef src) {
|
||||||
@ -156,8 +154,7 @@ inline typename enable_if<IsString<T>::value, bool>::type convertToJson(
|
|||||||
const T& src, VariantRef dst) {
|
const T& src, VariantRef dst) {
|
||||||
VariantData* data = VariantAttorney::getData(dst);
|
VariantData* data = VariantAttorney::getData(dst);
|
||||||
MemoryPool* pool = VariantAttorney::getPool(dst);
|
MemoryPool* pool = VariantAttorney::getPool(dst);
|
||||||
return variantSetString(data, adaptString(src), pool,
|
return variantSetString(data, adaptString(src), pool);
|
||||||
getStringStoragePolicy(src));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -23,12 +23,11 @@ struct SlotKeySetter {
|
|||||||
VariantSlot* _instance;
|
VariantSlot* _instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool,
|
inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) {
|
||||||
TStoragePolicy storage) {
|
|
||||||
if (!var)
|
if (!var)
|
||||||
return false;
|
return false;
|
||||||
return storage.store(key, pool, SlotKeySetter(var));
|
return storeString(pool, key, SlotKeySetter(var));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t slotSize(const VariantSlot* var) {
|
inline size_t slotSize(const VariantSlot* var) {
|
||||||
|
@ -285,14 +285,13 @@ class VariantData {
|
|||||||
return col ? col->getMember(key) : 0;
|
return col ? col->getMember(key) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool,
|
VariantData* getOrAddMember(TAdaptedString key, MemoryPool* pool) {
|
||||||
TStoragePolicy storage_policy) {
|
|
||||||
if (isNull())
|
if (isNull())
|
||||||
toObject();
|
toObject();
|
||||||
if (!isObject())
|
if (!isObject())
|
||||||
return 0;
|
return 0;
|
||||||
return _content.asCollection.getOrAddMember(key, pool, storage_policy);
|
return _content.asCollection.getOrAddMember(key, pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) {
|
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) {
|
||||||
@ -306,15 +305,14 @@ class VariantData {
|
|||||||
return _flags & VALUE_MASK;
|
return _flags & VALUE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
inline bool storeString(TAdaptedString value, MemoryPool* pool,
|
inline bool setString(TAdaptedString value, MemoryPool* pool) {
|
||||||
TStoragePolicy storage) {
|
|
||||||
if (value.isNull()) {
|
if (value.isNull()) {
|
||||||
setNull();
|
setNull();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return storage.store(value, pool, VariantStringSetter(this));
|
return storeString(pool, value, VariantStringSetter(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -37,10 +37,10 @@ inline void variantSetNull(VariantData* var) {
|
|||||||
var->setNull();
|
var->setNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TAdaptedString, typename TStoragePolicy>
|
template <typename TAdaptedString>
|
||||||
inline bool variantSetString(VariantData* var, TAdaptedString value,
|
inline bool variantSetString(VariantData* var, TAdaptedString value,
|
||||||
MemoryPool* pool, TStoragePolicy storage_policy) {
|
MemoryPool* pool) {
|
||||||
return var != 0 ? var->storeString(value, pool, storage_policy) : 0;
|
return var != 0 ? var->setString(value, pool) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t variantSize(const VariantData* var) {
|
inline size_t variantSize(const VariantData* var) {
|
||||||
@ -88,8 +88,7 @@ VariantData* variantGetOrAddMember(VariantData* var, TChar* key,
|
|||||||
MemoryPool* pool) {
|
MemoryPool* pool) {
|
||||||
if (!var)
|
if (!var)
|
||||||
return 0;
|
return 0;
|
||||||
return var->getOrAddMember(adaptString(key), pool,
|
return var->getOrAddMember(adaptString(key), pool);
|
||||||
getStringStoragePolicy(key));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TString>
|
template <typename TString>
|
||||||
@ -97,8 +96,7 @@ VariantData* variantGetOrAddMember(VariantData* var, const TString& key,
|
|||||||
MemoryPool* pool) {
|
MemoryPool* pool) {
|
||||||
if (!var)
|
if (!var)
|
||||||
return 0;
|
return 0;
|
||||||
return var->getOrAddMember(adaptString(key), pool,
|
return var->getOrAddMember(adaptString(key), pool);
|
||||||
getStringStoragePolicy(key));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool variantIsNull(const VariantData* var) {
|
inline bool variantIsNull(const VariantData* var) {
|
||||||
|
@ -91,8 +91,7 @@ inline bool VariantData::copyFrom(const VariantData& src, MemoryPool* pool) {
|
|||||||
return toObject().copyFrom(src._content.asCollection, pool);
|
return toObject().copyFrom(src._content.asCollection, pool);
|
||||||
case VALUE_IS_OWNED_STRING: {
|
case VALUE_IS_OWNED_STRING: {
|
||||||
String value = src.asString();
|
String value = src.asString();
|
||||||
return storeString(adaptString(value), pool,
|
return setString(adaptString(value), pool);
|
||||||
getStringStoragePolicy(value));
|
|
||||||
}
|
}
|
||||||
case VALUE_IS_OWNED_RAW:
|
case VALUE_IS_OWNED_RAW:
|
||||||
return storeOwnedRaw(
|
return storeOwnedRaw(
|
||||||
@ -154,14 +153,4 @@ inline void convertToJson(const VariantRefBase<TDataSource>& src,
|
|||||||
dst.set(src.template as<VariantConstRef>());
|
dst.set(src.template as<VariantConstRef>());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move somewhere else
|
|
||||||
template <typename TAdaptedString, typename TCallback>
|
|
||||||
bool CopyStringStoragePolicy::store(TAdaptedString str, MemoryPool* pool,
|
|
||||||
TCallback callback) {
|
|
||||||
const char* copy = pool->saveString(str);
|
|
||||||
String storedString(copy, str.size(), String::Copied);
|
|
||||||
callback(storedString);
|
|
||||||
return copy != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ARDUINOJSON_NAMESPACE
|
} // namespace ARDUINOJSON_NAMESPACE
|
||||||
|
Reference in New Issue
Block a user