Separate string adapter from storage policy

This commit is contained in:
Benoit Blanchon
2021-11-21 15:07:56 +01:00
parent 51937778dd
commit ca24ed48f5
37 changed files with 697 additions and 724 deletions

View File

@@ -115,7 +115,8 @@ struct Converter<T, typename enable_if<is_floating_point<T>::value>::type> {
template <>
struct Converter<const char*> {
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) {
@@ -132,7 +133,8 @@ struct Converter<const char*> {
template <>
struct Converter<String> {
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) {
@@ -151,7 +153,8 @@ inline typename enable_if<IsString<T>::value, bool>::type convertToJson(
const T& src, VariantRef dst) {
VariantData* data = getData(dst);
MemoryPool* pool = getPool(dst);
return variantSetString(data, adaptString(src), pool);
return variantSetString(data, adaptString(src), pool,
getStringStoragePolicy(src));
}
template <>

View File

@@ -9,40 +9,24 @@
namespace ARDUINOJSON_NAMESPACE {
template <typename TAdaptedString>
inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool) {
if (!var)
return false;
return slotSetKey(var, key, pool, typename TAdaptedString::storage_policy());
}
struct SlotKeySetter {
SlotKeySetter(VariantSlot* instance) : _instance(instance) {}
template <typename TAdaptedString>
inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool,
storage_policies::decide_at_runtime) {
if (key.isStatic()) {
return slotSetKey(var, key, pool, storage_policies::store_by_address());
} else {
return slotSetKey(var, key, pool, storage_policies::store_by_copy());
template <typename TStoredString>
void operator()(TStoredString s) {
if (!s)
return;
ARDUINOJSON_ASSERT(_instance != 0);
_instance->setKey(s);
}
}
template <typename TAdaptedString>
inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool*,
storage_policies::store_by_address) {
ARDUINOJSON_ASSERT(var);
var->setKey(LinkedString(key.data(), key.size()));
return true;
}
VariantSlot* _instance;
};
template <typename TAdaptedString>
template <typename TAdaptedString, typename TStoragePolicy>
inline bool slotSetKey(VariantSlot* var, TAdaptedString key, MemoryPool* pool,
storage_policies::store_by_copy) {
CopiedString dup(pool->saveString(key), key.size());
if (!dup)
return false;
ARDUINOJSON_ASSERT(var);
var->setKey(dup);
return true;
TStoragePolicy storage) {
return storage.store(key, pool, SlotKeySetter(var));
}
inline size_t slotSize(const VariantSlot* var) {

View File

@@ -8,7 +8,7 @@
#include <ArduinoJson/Misc/Visitable.hpp>
#include <ArduinoJson/Numbers/arithmeticCompare.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Strings/StringAdapter.hpp>
#include <ArduinoJson/Strings/StringAdapters.hpp>
#include <ArduinoJson/Variant/Visitor.hpp>
namespace ARDUINOJSON_NAMESPACE {
@@ -23,12 +23,12 @@ struct Comparer;
template <typename T>
struct Comparer<T, typename enable_if<IsString<T>::value>::type>
: ComparerBase {
T rhs;
T rhs; // TODO: store adapted string?
explicit Comparer(T value) : rhs(value) {}
CompareResult visitString(const char *lhs, size_t) {
int i = adaptString(rhs).compare(lhs);
CompareResult visitString(const char *lhs, size_t n) {
int i = stringCompare(adaptString(rhs), adaptString(lhs, n));
if (i < 0)
return COMPARE_RESULT_GREATER;
else if (i > 0)

View File

@@ -99,27 +99,7 @@ class VariantData {
return const_cast<VariantData *>(this)->asObject();
}
bool copyFrom(const VariantData &src, MemoryPool *pool) {
switch (src.type()) {
case VALUE_IS_ARRAY:
return toArray().copyFrom(src._content.asCollection, pool);
case VALUE_IS_OBJECT:
return toObject().copyFrom(src._content.asCollection, pool);
case VALUE_IS_OWNED_STRING:
return storeString(
adaptString(const_cast<char *>(src._content.asString.data),
src._content.asString.size),
pool);
case VALUE_IS_OWNED_RAW:
return storeOwnedRaw(
serialized(src._content.asString.data, src._content.asString.size),
pool);
default:
setType(src.type());
_content = src._content;
return true;
}
}
bool copyFrom(const VariantData &src, MemoryPool *pool);
bool isArray() const {
return (_flags & VALUE_IS_ARRAY) != 0;
@@ -242,11 +222,6 @@ class VariantData {
_content.asString.size = s.size();
}
template <typename TAdaptedString>
bool storeString(TAdaptedString value, MemoryPool *pool) {
return storeString(value, pool, typename TAdaptedString::storage_policy());
}
CollectionData &toArray() {
setType(VALUE_IS_ARRAY);
_content.asCollection.clear();
@@ -307,13 +282,14 @@ class VariantData {
return isObject() ? _content.asCollection.getMember(key) : 0;
}
template <typename TAdaptedString>
VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool) {
template <typename TAdaptedString, typename TStoragePolicy>
VariantData *getOrAddMember(TAdaptedString key, MemoryPool *pool,
TStoragePolicy storage_policy) {
if (isNull())
toObject();
if (!isObject())
return 0;
return _content.asCollection.getOrAddMember(key, pool);
return _content.asCollection.getOrAddMember(key, pool, storage_policy);
}
void movePointers(ptrdiff_t stringDistance, ptrdiff_t variantDistance) {
@@ -327,46 +303,36 @@ class VariantData {
return _flags & VALUE_MASK;
}
template <typename TAdaptedString, typename TStoragePolicy>
inline bool storeString(TAdaptedString value, MemoryPool *pool,
TStoragePolicy storage) {
if (value.isNull()) {
setNull();
return true;
}
return storage.store(value, pool, VariantStringSetter(this));
}
private:
void setType(uint8_t t) {
_flags &= OWNED_KEY_BIT;
_flags |= t;
}
template <typename TAdaptedString>
inline bool storeString(TAdaptedString value, MemoryPool *pool,
storage_policies::decide_at_runtime) {
if (value.isStatic())
return storeString(value, pool, storage_policies::store_by_address());
else
return storeString(value, pool, storage_policies::store_by_copy());
}
struct VariantStringSetter {
VariantStringSetter(VariantData *instance) : _instance(instance) {}
template <typename TAdaptedString>
inline bool storeString(TAdaptedString value, MemoryPool *,
storage_policies::store_by_address) {
if (value.isNull())
setNull();
else
setString(LinkedString(value.data(), value.size()));
return true;
}
template <typename TStoredString>
void operator()(TStoredString s) {
if (s)
_instance->setString(s);
else
_instance->setNull();
}
template <typename TAdaptedString>
inline bool storeString(TAdaptedString value, MemoryPool *pool,
storage_policies::store_by_copy) {
if (value.isNull()) {
setNull();
return true;
}
const char *copy = pool->saveString(value);
if (!copy) {
setNull();
return false;
}
setString(CopiedString(copy, value.size()));
return true;
}
VariantData *_instance;
};
};
} // namespace ARDUINOJSON_NAMESPACE

View File

@@ -5,6 +5,7 @@
#pragma once
#include <ArduinoJson/Polyfills/attributes.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Variant/VariantData.hpp>
namespace ARDUINOJSON_NAMESPACE {
@@ -49,12 +50,10 @@ inline void variantSetNull(VariantData *var) {
var->setNull();
}
template <typename TAdaptedString>
template <typename TAdaptedString, typename TStoragePolicy>
inline bool variantSetString(VariantData *var, TAdaptedString value,
MemoryPool *pool) {
if (!var)
return false;
return var->storeString(value, pool);
MemoryPool *pool, TStoragePolicy storage_policy) {
return var != 0 ? var->storeString(value, pool, storage_policy) : 0;
}
inline size_t variantSize(const VariantData *var) {
@@ -87,14 +86,18 @@ inline NO_INLINE VariantData *variantGetOrAddElement(VariantData *var,
template <typename TChar>
NO_INLINE VariantData *variantGetOrAddMember(VariantData *var, TChar *key,
MemoryPool *pool) {
return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0;
return var != 0 ? var->getOrAddMember(adaptString(key), pool,
getStringStoragePolicy(key))
: 0;
}
template <typename TString>
NO_INLINE VariantData *variantGetOrAddMember(VariantData *var,
const TString &key,
MemoryPool *pool) {
return var != 0 ? var->getOrAddMember(adaptString(key), pool) : 0;
return var != 0 ? var->getOrAddMember(adaptString(key), pool,
getStringStoragePolicy(key))
: 0;
}
inline bool variantIsNull(const VariantData *var) {

View File

@@ -81,6 +81,28 @@ inline String VariantData::asString() const {
}
}
inline bool VariantData::copyFrom(const VariantData &src, MemoryPool *pool) {
switch (src.type()) {
case VALUE_IS_ARRAY:
return toArray().copyFrom(src._content.asCollection, pool);
case VALUE_IS_OBJECT:
return toObject().copyFrom(src._content.asCollection, pool);
case VALUE_IS_OWNED_STRING: {
String value = src.asString();
return storeString(adaptString(value), pool,
getStringStoragePolicy(value));
}
case VALUE_IS_OWNED_RAW:
return storeOwnedRaw(
serialized(src._content.asString.data, src._content.asString.size),
pool);
default:
setType(src.type());
_content = src._content;
return true;
}
}
template <typename T>
inline typename enable_if<is_same<T, ArrayRef>::value, ArrayRef>::type
VariantRef::to() const {
@@ -146,4 +168,15 @@ inline VariantConstRef operator|(VariantConstRef preferedValue,
inline bool VariantRef::set(char value) const {
return set<signed char>(value);
}
// TODO: move somewhere else
template <typename TAdaptedString, typename TCallback>
bool CopyStringStoragePolicy::store(TAdaptedString str, MemoryPool *pool,
TCallback callback) {
const char *copy = pool->saveString(str);
CopiedString storedString(copy, str.size());
callback(storedString);
return copy != 0;
}
} // namespace ARDUINOJSON_NAMESPACE

View File

@@ -7,7 +7,6 @@
#include <ArduinoJson/Polyfills/integer.hpp>
#include <ArduinoJson/Polyfills/limits.hpp>
#include <ArduinoJson/Polyfills/type_traits.hpp>
#include <ArduinoJson/Strings/StoragePolicy.hpp>
#include <ArduinoJson/Strings/StoredString.hpp>
#include <ArduinoJson/Variant/VariantContent.hpp>