Replace getData()/getResourceManager() with getImpl()

This commit is contained in:
Benoit Blanchon
2025-07-07 15:53:37 +02:00
parent f62d6f26e0
commit 0b9a8b6d2b
20 changed files with 168 additions and 267 deletions

View File

@@ -50,21 +50,17 @@ class ElementProxy : public VariantRefBase<ElementProxy<TUpstream>>,
: upstream_(src.upstream_), index_(src.index_) {} : upstream_(src.upstream_), index_(src.index_) {}
// clang-format on // clang-format on
ResourceManager* getResourceManager() const { VariantImpl getImpl() const {
return VariantAttorney::getResourceManager(upstream_); auto impl = VariantAttorney::getImpl(upstream_);
return VariantImpl(impl.getElement(index_), impl.getResourceManager());
} }
FORCE_INLINE VariantData* getData() const { VariantImpl getOrCreateImpl() const {
return VariantAttorney::getVariantImpl(upstream_).getElement(index_); auto impl = VariantAttorney::getOrCreateImpl(upstream_);
} auto data = impl.getData();
if (data)
VariantData* getOrCreateData() const { data->getOrCreateArray();
auto data = VariantAttorney::getOrCreateData(upstream_); return VariantImpl(impl.getOrAddElement(index_), impl.getResourceManager());
auto resources = VariantAttorney::getResourceManager(upstream_);
if (!data)
return nullptr;
data->getOrCreateArray();
return VariantImpl(data, resources).getOrAddElement(index_);
} }
TUpstream upstream_; TUpstream upstream_;

View File

@@ -22,10 +22,6 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
// Constructs an unbound reference. // Constructs an unbound reference.
JsonArray() {} JsonArray() {}
// INTERNAL USE ONLY
JsonArray(detail::VariantData* data, detail::ResourceManager* resources)
: impl_(data, resources) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonArray(detail::VariantImpl impl) : impl_(impl) {} JsonArray(detail::VariantImpl impl) : impl_(impl) {}
@@ -199,16 +195,12 @@ class JsonArray : public detail::VariantOperators<JsonArray> {
} }
private: private:
detail::ResourceManager* getResourceManager() const { const detail::VariantImpl& getImpl() const {
return impl_.getResourceManager(); return impl_;
} }
detail::VariantData* getData() const { const detail::VariantImpl& getOrCreateImpl() const {
return impl_.getData(); return impl_;
}
detail::VariantData* getOrCreateData() const {
return impl_.getData();
} }
mutable detail::VariantImpl impl_; mutable detail::VariantImpl impl_;

View File

@@ -36,10 +36,6 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
// Creates an unbound reference. // Creates an unbound reference.
JsonArrayConst() {} JsonArrayConst() {}
// INTERNAL USE ONLY
JsonArrayConst(detail::VariantData* data, detail::ResourceManager* resources)
: impl_(data, resources) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonArrayConst(const detail::VariantImpl& impl) : impl_(impl) {} JsonArrayConst(const detail::VariantImpl& impl) : impl_(impl) {}
@@ -98,8 +94,8 @@ class JsonArrayConst : public detail::VariantOperators<JsonArrayConst> {
} }
private: private:
const detail::VariantData* getData() const { const detail::VariantImpl& getImpl() const {
return impl_.getData(); return impl_;
} }
detail::VariantImpl impl_; detail::VariantImpl impl_;

View File

@@ -44,13 +44,13 @@ template <template <typename> class TDeserializer, typename TDestination,
typename TReader, typename TOptions> typename TReader, typename TOptions>
DeserializationError doDeserialize(TDestination&& dst, TReader reader, DeserializationError doDeserialize(TDestination&& dst, TReader reader,
TOptions options) { TOptions options) {
auto data = VariantAttorney::getOrCreateData(dst); auto impl = VariantAttorney::getOrCreateImpl(dst);
if (!data) if (impl.getData() == nullptr)
return DeserializationError::NoMemory; return DeserializationError::NoMemory;
auto resources = VariantAttorney::getResourceManager(dst); auto resources = impl.getResourceManager();
dst.clear(); dst.clear();
auto err = TDeserializer<TReader>(resources, reader) auto err = TDeserializer<TReader>(resources, reader)
.parse(data, options.filter, options.nestingLimit); .parse(impl.getData(), options.filter, options.nestingLimit);
shrinkJsonDocument(dst); shrinkJsonDocument(dst);
return err; return err;
} }

View File

@@ -120,13 +120,13 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Returns the depth (nesting level) of the array. // Returns the depth (nesting level) of the array.
// https://arduinojson.org/v7/api/jsondocument/nesting/ // https://arduinojson.org/v7/api/jsondocument/nesting/
size_t nesting() const { size_t nesting() const {
return getVariantImpl().nesting(); return getImpl().nesting();
} }
// Returns the number of elements in the root array or object. // Returns the number of elements in the root array or object.
// https://arduinojson.org/v7/api/jsondocument/size/ // https://arduinojson.org/v7/api/jsondocument/size/
size_t size() const { size_t size() const {
return getVariantImpl().size(); return getImpl().size();
} }
// Copies the specified document. // Copies the specified document.
@@ -165,7 +165,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TChar> template <typename TChar>
ARDUINOJSON_DEPRECATED("use doc[\"key\"].is<T>() instead") ARDUINOJSON_DEPRECATED("use doc[\"key\"].is<T>() instead")
bool containsKey(TChar* key) const { bool containsKey(TChar* key) const {
return getVariantImpl().getMember(detail::adaptString(key)) != 0; return getImpl().getMember(detail::adaptString(key)) != 0;
} }
// DEPRECATED: use obj[key].is<T>() instead // DEPRECATED: use obj[key].is<T>() instead
@@ -174,7 +174,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
detail::enable_if_t<detail::IsString<TString>::value, int> = 0> detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
ARDUINOJSON_DEPRECATED("use doc[key].is<T>() instead") ARDUINOJSON_DEPRECATED("use doc[key].is<T>() instead")
bool containsKey(const TString& key) const { bool containsKey(const TString& key) const {
return getVariantImpl().getMember(detail::adaptString(key)) != 0; return getImpl().getMember(detail::adaptString(key)) != 0;
} }
// DEPRECATED: use obj[key].is<T>() instead // DEPRECATED: use obj[key].is<T>() instead
@@ -211,8 +211,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TString, template <typename TString,
detail::enable_if_t<detail::IsString<TString>::value, int> = 0> detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
JsonVariantConst operator[](const TString& key) const { JsonVariantConst operator[](const TString& key) const {
return JsonVariantConst( return JsonVariantConst(getImpl().getMember(detail::adaptString(key)),
getVariantImpl().getMember(detail::adaptString(key)), &resources_); &resources_);
} }
// Gets a root object's member. // Gets a root object's member.
@@ -222,8 +222,8 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
!detail::is_const<TChar>::value, !detail::is_const<TChar>::value,
int> = 0> int> = 0>
JsonVariantConst operator[](TChar* key) const { JsonVariantConst operator[](TChar* key) const {
return JsonVariantConst( return JsonVariantConst(getImpl().getMember(detail::adaptString(key)),
getVariantImpl().getMember(detail::adaptString(key)), &resources_); &resources_);
} }
// Gets or sets a root array's element. // Gets or sets a root array's element.
@@ -237,7 +237,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
// Gets a root array's member. // Gets a root array's member.
// https://arduinojson.org/v7/api/jsondocument/subscript/ // https://arduinojson.org/v7/api/jsondocument/subscript/
JsonVariantConst operator[](size_t index) const { JsonVariantConst operator[](size_t index) const {
return JsonVariantConst(getVariantImpl().getElement(index), &resources_); return JsonVariantConst(getImpl().getElement(index), &resources_);
} }
// Gets or sets a root object's member. // Gets or sets a root object's member.
@@ -290,7 +290,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename T, template <typename T,
detail::enable_if_t<detail::is_integral<T>::value, int> = 0> detail::enable_if_t<detail::is_integral<T>::value, int> = 0>
void remove(T index) { void remove(T index) {
getVariantImpl().removeElement(size_t(index)); getImpl().removeElement(size_t(index));
} }
// Removes a member of the root object. // Removes a member of the root object.
@@ -300,7 +300,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
!detail::is_const<TChar>::value, !detail::is_const<TChar>::value,
int> = 0> int> = 0>
void remove(TChar* key) { void remove(TChar* key) {
getVariantImpl().removeMember(detail::adaptString(key)); getImpl().removeMember(detail::adaptString(key));
} }
// Removes a member of the root object. // Removes a member of the root object.
@@ -308,7 +308,7 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
template <typename TString, template <typename TString,
detail::enable_if_t<detail::IsString<TString>::value, int> = 0> detail::enable_if_t<detail::IsString<TString>::value, int> = 0>
void remove(const TString& key) { void remove(const TString& key) {
getVariantImpl().removeMember(detail::adaptString(key)); getImpl().removeMember(detail::adaptString(key));
} }
// Removes a member of the root object or an element of the root array. // Removes a member of the root object or an element of the root array.
@@ -388,18 +388,18 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
} }
private: private:
detail::VariantImpl getVariantImpl() const { detail::VariantImpl getImpl() const {
return detail::VariantImpl(&data_, &resources_); return {&data_, &resources_};
}
detail::VariantImpl getOrCreateImpl() {
return {&data_, &resources_};
} }
detail::VariantImpl getOrCreateArray() { detail::VariantImpl getOrCreateArray() {
return detail::VariantImpl(data_.getOrCreateArray(), &resources_); return detail::VariantImpl(data_.getOrCreateArray(), &resources_);
} }
detail::VariantImpl getOrCreateObject() {
return detail::VariantImpl(data_.getOrCreateObject(), &resources_);
}
JsonVariant getVariant() { JsonVariant getVariant() {
return JsonVariant(&data_, &resources_); return JsonVariant(&data_, &resources_);
} }
@@ -408,22 +408,6 @@ class JsonDocument : public detail::VariantOperators<const JsonDocument&> {
return JsonVariantConst(&data_, &resources_); return JsonVariantConst(&data_, &resources_);
} }
detail::ResourceManager* getResourceManager() {
return &resources_;
}
detail::VariantData* getData() {
return &data_;
}
const detail::VariantData* getData() const {
return &data_;
}
detail::VariantData* getOrCreateData() {
return &data_;
}
mutable detail::ResourceManager resources_; mutable detail::ResourceManager resources_;
mutable detail::VariantData data_; mutable detail::VariantData data_;
}; };

View File

@@ -25,11 +25,12 @@ class MsgPackBinary {
template <> template <>
struct Converter<MsgPackBinary> : private detail::VariantAttorney { struct Converter<MsgPackBinary> : private detail::VariantAttorney {
static void toJson(MsgPackBinary src, JsonVariant dst) { static void toJson(MsgPackBinary src, JsonVariant dst) {
auto data = VariantAttorney::getData(dst); auto impl = getImpl(dst);
auto data = impl.getData();
if (!data) if (!data)
return; return;
auto resources = getResourceManager(dst); auto resources = impl.getResourceManager();
detail::VariantImpl(data, resources).clear(); impl.clear();
if (src.data()) { if (src.data()) {
size_t headerSize = src.size() >= 0x10000 ? 5 size_t headerSize = src.size() >= 0x10000 ? 5
: src.size() >= 0x100 ? 3 : src.size() >= 0x100 ? 3
@@ -66,7 +67,7 @@ struct Converter<MsgPackBinary> : private detail::VariantAttorney {
} }
static MsgPackBinary fromJson(JsonVariantConst src) { static MsgPackBinary fromJson(JsonVariantConst src) {
auto variant = VariantAttorney::getVariantImpl(src); auto variant = getImpl(src);
auto rawstr = variant.asRawString(); auto rawstr = variant.asRawString();
auto p = reinterpret_cast<const uint8_t*>(rawstr.c_str()); auto p = reinterpret_cast<const uint8_t*>(rawstr.c_str());
auto n = rawstr.size(); auto n = rawstr.size();

View File

@@ -31,11 +31,12 @@ class MsgPackExtension {
template <> template <>
struct Converter<MsgPackExtension> : private detail::VariantAttorney { struct Converter<MsgPackExtension> : private detail::VariantAttorney {
static void toJson(MsgPackExtension src, JsonVariant dst) { static void toJson(MsgPackExtension src, JsonVariant dst) {
auto data = getData(dst); auto impl = getImpl(dst);
auto data = impl.getData();
auto resources = impl.getResourceManager();
if (!data) if (!data)
return; return;
auto resources = getResourceManager(dst); impl.clear();
detail::VariantImpl(data, resources).clear();
if (src.data()) { if (src.data()) {
uint8_t format, sizeBytes; uint8_t format, sizeBytes;
if (src.size() >= 0x10000) { if (src.size() >= 0x10000) {
@@ -80,7 +81,7 @@ struct Converter<MsgPackExtension> : private detail::VariantAttorney {
} }
static MsgPackExtension fromJson(JsonVariantConst src) { static MsgPackExtension fromJson(JsonVariantConst src) {
auto variant = VariantAttorney::getVariantImpl(src); auto variant = detail::VariantAttorney::getImpl(src);
auto rawstr = variant.asRawString(); auto rawstr = variant.asRawString();
if (rawstr.size() == 0) if (rawstr.size() == 0)
return {}; return {};

View File

@@ -22,10 +22,6 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
// Creates an unbound reference. // Creates an unbound reference.
JsonObject() {} JsonObject() {}
// INTERNAL USE ONLY
JsonObject(detail::VariantData* data, detail::ResourceManager* resource)
: impl_(data, resource) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonObject(detail::VariantImpl impl) : impl_(impl) {} JsonObject(detail::VariantImpl impl) : impl_(impl) {}
@@ -222,16 +218,12 @@ class JsonObject : public detail::VariantOperators<JsonObject> {
} }
private: private:
detail::ResourceManager* getResourceManager() const { const detail::VariantImpl& getImpl() const {
return impl_.getResourceManager(); return impl_;
} }
detail::VariantData* getData() const { const detail::VariantImpl& getOrCreateImpl() const {
return impl_.getData(); return impl_;
}
detail::VariantData* getOrCreateData() const {
return impl_.getData();
} }
mutable detail::VariantImpl impl_; mutable detail::VariantImpl impl_;

View File

@@ -21,10 +21,6 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
// Creates an unbound reference. // Creates an unbound reference.
JsonObjectConst() {} JsonObjectConst() {}
// INTERNAL USE ONLY
JsonObjectConst(detail::VariantData* data, detail::ResourceManager* resources)
: impl_(data, resources) {}
// INTERNAL USE ONLY // INTERNAL USE ONLY
JsonObjectConst(const detail::VariantImpl& impl) : impl_(impl) {} JsonObjectConst(const detail::VariantImpl& impl) : impl_(impl) {}
@@ -132,8 +128,8 @@ class JsonObjectConst : public detail::VariantOperators<JsonObjectConst> {
} }
private: private:
const detail::VariantData* getData() const { const detail::VariantImpl& getImpl() const {
return impl_.getData(); return impl_;
} }
detail::VariantImpl impl_; detail::VariantImpl impl_;

View File

@@ -51,21 +51,17 @@ class MemberProxy
: upstream_(src.upstream_), key_(src.key_) {} : upstream_(src.upstream_), key_(src.key_) {}
// clang-format on // clang-format on
ResourceManager* getResourceManager() const { VariantImpl getImpl() const {
return VariantAttorney::getResourceManager(upstream_); auto impl = VariantAttorney::getImpl(upstream_);
return VariantImpl(impl.getMember(key_), impl.getResourceManager());
} }
VariantData* getData() const { VariantImpl getOrCreateImpl() const {
return VariantAttorney::getVariantImpl(upstream_).getMember(key_); auto impl = VariantAttorney::getOrCreateImpl(upstream_);
} auto data = impl.getData();
if (data)
VariantData* getOrCreateData() const { data->getOrCreateObject();
auto data = VariantAttorney::getOrCreateData(upstream_); return VariantImpl(impl.getOrAddMember(key_), impl.getResourceManager());
auto resources = VariantAttorney::getResourceManager(upstream_);
if (!data)
return nullptr;
data->getOrCreateObject();
return VariantImpl(data, resources).getOrAddMember(key_);
} }
private: private:

View File

@@ -11,10 +11,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <template <typename> class TSerializer> template <template <typename> class TSerializer>
size_t measure(ArduinoJson::JsonVariantConst source) { size_t measure(ArduinoJson::JsonVariantConst source) {
DummyWriter dp; DummyWriter dp;
auto data = VariantAttorney::getData(source); auto impl = VariantAttorney::getImpl(source);
auto resources = VariantAttorney::getResourceManager(source); TSerializer<DummyWriter> serializer(dp, impl.getResourceManager());
TSerializer<DummyWriter> serializer(dp, resources); return impl.accept(serializer);
return VariantImpl(data, resources).accept(serializer);
} }
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -10,10 +10,9 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
template <template <typename> class TSerializer, typename TWriter> template <template <typename> class TSerializer, typename TWriter>
size_t doSerialize(ArduinoJson::JsonVariantConst source, TWriter writer) { size_t doSerialize(ArduinoJson::JsonVariantConst source, TWriter writer) {
auto data = VariantAttorney::getData(source); auto impl = VariantAttorney::getImpl(source);
auto resources = VariantAttorney::getResourceManager(source); TSerializer<TWriter> serializer(writer, impl.getResourceManager());
TSerializer<TWriter> serializer(writer, resources); return impl.accept(serializer);
return VariantImpl(data, resources).accept(serializer);
} }
template <template <typename> class TSerializer, typename TDestination> template <template <typename> class TSerializer, typename TDestination>

View File

@@ -60,18 +60,18 @@ struct Converter<T, detail::enable_if_t<detail::is_integral<T>::value &&
: private detail::VariantAttorney { : private detail::VariantAttorney {
static bool toJson(T src, JsonVariant dst) { static bool toJson(T src, JsonVariant dst) {
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T); ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
auto variant = getVariantImpl(dst); auto variant = getImpl(dst);
variant.clear(); variant.clear();
return variant.setInteger(src); return variant.setInteger(src);
} }
static T fromJson(JsonVariantConst src) { static T fromJson(JsonVariantConst src) {
ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T); ARDUINOJSON_ASSERT_INTEGER_TYPE_IS_SUPPORTED(T);
return getVariantImpl(src).template asIntegral<T>(); return getImpl(src).template asIntegral<T>();
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
return getVariantImpl(src).template isInteger<T>(); return getImpl(src).template isInteger<T>();
} }
}; };
@@ -83,29 +83,28 @@ struct Converter<T, detail::enable_if_t<detail::is_enum<T>::value>>
} }
static T fromJson(JsonVariantConst src) { static T fromJson(JsonVariantConst src) {
return static_cast<T>(getVariantImpl(src).template asIntegral<int>()); return static_cast<T>(getImpl(src).template asIntegral<int>());
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
return getVariantImpl(src).template isInteger<int>(); return getImpl(src).template isInteger<int>();
} }
}; };
template <> template <>
struct Converter<bool> : private detail::VariantAttorney { struct Converter<bool> : private detail::VariantAttorney {
static bool toJson(bool src, JsonVariant dst) { static bool toJson(bool src, JsonVariant dst) {
auto variant = getVariantImpl(dst); auto impl = getImpl(dst);
variant.clear(); impl.clear();
return variant.setBoolean(src); return impl.setBoolean(src);
} }
static bool fromJson(JsonVariantConst src) { static bool fromJson(JsonVariantConst src) {
return getVariantImpl(src).asBoolean(); return getImpl(src).asBoolean();
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); return getImpl(src).type() == detail::VariantType::Boolean;
return data && data->type == detail::VariantType::Boolean;
} }
}; };
@@ -113,61 +112,58 @@ template <typename T>
struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>> struct Converter<T, detail::enable_if_t<detail::is_floating_point<T>::value>>
: private detail::VariantAttorney { : private detail::VariantAttorney {
static bool toJson(T src, JsonVariant dst) { static bool toJson(T src, JsonVariant dst) {
auto variant = getVariantImpl(dst); auto impl = getImpl(dst);
variant.clear(); impl.clear();
return variant.setFloat(src); return impl.setFloat(src);
} }
static T fromJson(JsonVariantConst src) { static T fromJson(JsonVariantConst src) {
return getVariantImpl(src).template asFloat<T>(); return getImpl(src).template asFloat<T>();
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); return getImpl(src).isFloat();
return data && data->isFloat();
} }
}; };
template <> template <>
struct Converter<const char*> : private detail::VariantAttorney { struct Converter<const char*> : private detail::VariantAttorney {
static void toJson(const char* src, JsonVariant dst) { static void toJson(const char* src, JsonVariant dst) {
auto variant = getVariantImpl(dst); auto impl = getImpl(dst);
variant.clear(); impl.clear();
variant.setString(detail::adaptString(src)); impl.setString(detail::adaptString(src));
} }
static const char* fromJson(JsonVariantConst src) { static const char* fromJson(JsonVariantConst src) {
return getVariantImpl(src).asString().c_str(); return getImpl(src).asString().c_str();
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); return getImpl(src).isString();
return data && data->isString();
} }
}; };
template <> template <>
struct Converter<JsonString> : private detail::VariantAttorney { struct Converter<JsonString> : private detail::VariantAttorney {
static void toJson(JsonString src, JsonVariant dst) { static void toJson(JsonString src, JsonVariant dst) {
auto variant = getVariantImpl(dst); auto impl = getImpl(dst);
variant.clear(); impl.clear();
variant.setString(detail::adaptString(src)); impl.setString(detail::adaptString(src));
} }
static JsonString fromJson(JsonVariantConst src) { static JsonString fromJson(JsonVariantConst src) {
return getVariantImpl(src).asString(); return getImpl(src).asString();
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); return getImpl(src).isString();
return data && data->isString();
} }
}; };
template <typename T> template <typename T>
inline detail::enable_if_t<detail::IsString<T>::value> convertToJson( inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
const T& src, JsonVariant dst) { const T& src, JsonVariant dst) {
auto variant = detail::VariantAttorney::getVariantImpl(dst); auto variant = detail::VariantAttorney::getImpl(dst);
variant.clear(); variant.clear();
variant.setString(detail::adaptString(src)); variant.setString(detail::adaptString(src));
} }
@@ -178,7 +174,7 @@ inline detail::enable_if_t<detail::IsString<T>::value> convertToJson(
template <typename T> template <typename T>
struct Converter<SerializedValue<T>> : private detail::VariantAttorney { struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
static void toJson(SerializedValue<T> src, JsonVariant dst) { static void toJson(SerializedValue<T> src, JsonVariant dst) {
auto variant = getVariantImpl(dst); auto variant = getImpl(dst);
variant.clear(); variant.clear();
variant.setRawString(src); variant.setRawString(src);
} }
@@ -187,14 +183,13 @@ struct Converter<SerializedValue<T>> : private detail::VariantAttorney {
template <> template <>
struct Converter<detail::nullptr_t> : private detail::VariantAttorney { struct Converter<detail::nullptr_t> : private detail::VariantAttorney {
static void toJson(detail::nullptr_t, JsonVariant dst) { static void toJson(detail::nullptr_t, JsonVariant dst) {
getVariantImpl(dst).clear(); getImpl(dst).clear();
} }
static detail::nullptr_t fromJson(JsonVariantConst) { static detail::nullptr_t fromJson(JsonVariantConst) {
return nullptr; return nullptr;
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); return getImpl(src).isNull();
return data == 0 || data->type == detail::VariantType::Null;
} }
}; };
@@ -236,16 +231,15 @@ class StringBuilderPrint : public Print {
} // namespace detail } // namespace detail
inline void convertToJson(const ::Printable& src, JsonVariant dst) { inline void convertToJson(const ::Printable& src, JsonVariant dst) {
auto resources = detail::VariantAttorney::getResourceManager(dst); auto impl = detail::VariantAttorney::getImpl(dst);
auto data = detail::VariantAttorney::getData(dst); if (!impl.getData())
if (!resources || !data)
return; return;
detail::VariantImpl(data, resources).clear(); impl.clear();
detail::StringBuilderPrint print(resources); detail::StringBuilderPrint print(impl.getResourceManager());
src.printTo(print); src.printTo(print);
if (print.overflowed()) if (print.overflowed())
return; return;
print.save(data); print.save(impl.getData());
} }
#endif #endif
@@ -306,12 +300,11 @@ struct Converter<JsonArrayConst> : private detail::VariantAttorney {
} }
static JsonArrayConst fromJson(JsonVariantConst src) { static JsonArrayConst fromJson(JsonVariantConst src) {
return JsonArrayConst(getData(src), getResourceManager(src)); return JsonArrayConst(getImpl(src));
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); return getImpl(src).type() == detail::VariantType::Array;
return data && data->type == detail::VariantType::Array;
} }
}; };
@@ -325,12 +318,11 @@ struct Converter<JsonArray> : private detail::VariantAttorney {
} }
static JsonArray fromJson(JsonVariant src) { static JsonArray fromJson(JsonVariant src) {
return JsonArray(getData(src), getResourceManager(src)); return JsonArray(getImpl(src));
} }
static bool checkJson(JsonVariant src) { static bool checkJson(JsonVariant src) {
auto data = getData(src); return getImpl(src).type() == detail::VariantType::Array;
return data && data->type == detail::VariantType::Array;
} }
}; };
@@ -344,12 +336,11 @@ struct Converter<JsonObjectConst> : private detail::VariantAttorney {
} }
static JsonObjectConst fromJson(JsonVariantConst src) { static JsonObjectConst fromJson(JsonVariantConst src) {
return JsonObjectConst(getData(src), getResourceManager(src)); return JsonObjectConst(getImpl(src));
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); return getImpl(src).type() == detail::VariantType::Object;
return data && data->type == detail::VariantType::Object;
} }
}; };
@@ -363,12 +354,11 @@ struct Converter<JsonObject> : private detail::VariantAttorney {
} }
static JsonObject fromJson(JsonVariant src) { static JsonObject fromJson(JsonVariant src) {
return JsonObject(getData(src), getResourceManager(src)); return JsonObject(getImpl(src));
} }
static bool checkJson(JsonVariant src) { static bool checkJson(JsonVariant src) {
auto data = getData(src); return getImpl(src).type() == detail::VariantType::Object;
return data && data->type == detail::VariantType::Object;
} }
}; };

View File

@@ -26,16 +26,12 @@ class JsonVariant : public detail::VariantRefBase<JsonVariant>,
JsonVariant(detail::VariantImpl impl) : impl_(impl) {} JsonVariant(detail::VariantImpl impl) : impl_(impl) {}
private: private:
detail::ResourceManager* getResourceManager() const { const detail::VariantImpl& getImpl() const {
return impl_.getResourceManager(); return impl_;
} }
detail::VariantData* getData() const { const detail::VariantImpl& getOrCreateImpl() const {
return impl_.getData(); return impl_;
}
detail::VariantData* getOrCreateData() const {
return impl_.getData();
} }
mutable detail::VariantImpl impl_; mutable detail::VariantImpl impl_;
@@ -56,7 +52,7 @@ struct Converter<JsonVariant> : private detail::VariantAttorney {
} }
static bool checkJson(JsonVariant src) { static bool checkJson(JsonVariant src) {
auto data = getData(src); auto data = getImpl(src).getData();
return !!data; return !!data;
} }
}; };
@@ -68,11 +64,11 @@ struct Converter<JsonVariantConst> : private detail::VariantAttorney {
} }
static JsonVariantConst fromJson(JsonVariantConst src) { static JsonVariantConst fromJson(JsonVariantConst src) {
return JsonVariantConst(getData(src), getResourceManager(src)); return JsonVariantConst(getImpl(src));
} }
static bool checkJson(JsonVariantConst src) { static bool checkJson(JsonVariantConst src) {
auto data = getData(src); auto data = getImpl(src).getData();
return !!data; return !!data;
} }
}; };

View File

@@ -179,12 +179,8 @@ class JsonVariantConst : public detail::VariantTag,
} }
protected: protected:
detail::VariantData* getData() const { const detail::VariantImpl& getImpl() const {
return impl_.getData(); return impl_;
}
detail::ResourceManager* getResourceManager() const {
return impl_.getResourceManager();
} }
private: private:

View File

@@ -48,10 +48,9 @@ class VisitorAdapter {
template <typename TVisitor> template <typename TVisitor>
typename TVisitor::result_type accept(JsonVariantConst variant, typename TVisitor::result_type accept(JsonVariantConst variant,
TVisitor& visit) { TVisitor& visit) {
auto data = VariantAttorney::getData(variant); auto impl = VariantAttorney::getImpl(variant);
auto resources = VariantAttorney::getResourceManager(variant);
VisitorAdapter<TVisitor> adapter(visit); VisitorAdapter<TVisitor> adapter(visit);
return VariantImpl(data, resources).accept(adapter); return impl.accept(adapter);
} }
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -16,24 +16,13 @@ ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
class VariantAttorney { class VariantAttorney {
public: public:
template <typename TClient> template <typename TClient>
static auto getResourceManager(TClient& client) static VariantImpl getImpl(TClient& client) {
-> decltype(client.getResourceManager()) { return client.getImpl();
return client.getResourceManager();
} }
template <typename TClient> template <typename TClient>
static auto getData(TClient& client) -> decltype(client.getData()) { static VariantImpl getOrCreateImpl(TClient& client) {
return client.getData(); return client.getOrCreateImpl();
}
template <typename TClient>
static VariantImpl getVariantImpl(TClient& client) {
return VariantImpl(client.getData(), client.getResourceManager());
}
template <typename TClient>
static VariantData* getOrCreateData(TClient& client) {
return client.getOrCreateData();
} }
}; };

View File

@@ -199,7 +199,7 @@ struct Comparer<
T, enable_if_t<is_convertible<T, ArduinoJson::JsonVariantConst>::value>> T, enable_if_t<is_convertible<T, ArduinoJson::JsonVariantConst>::value>>
: VariantComparer { : VariantComparer {
explicit Comparer(const T& value) explicit Comparer(const T& value)
: VariantComparer(static_cast<JsonVariantConst>(value)) {} : VariantComparer(JsonVariantConst(VariantAttorney::getImpl(value))) {}
}; };
template <typename T> template <typename T>

View File

@@ -29,18 +29,18 @@ class VariantRefBase : public VariantTag {
// Sets the value to null. // Sets the value to null.
// https://arduinojson.org/v7/api/jsonvariant/clear/ // https://arduinojson.org/v7/api/jsonvariant/clear/
void clear() const { void clear() const {
getOrCreateVariantImpl().clear(); getOrCreateImpl().clear();
} }
// Returns true if the value is null or the reference is unbound. // Returns true if the value is null or the reference is unbound.
// https://arduinojson.org/v7/api/jsonvariant/isnull/ // https://arduinojson.org/v7/api/jsonvariant/isnull/
bool isNull() const { bool isNull() const {
return getVariantImpl().isNull(); return getImpl().isNull();
} }
// Returns true if the reference is unbound. // Returns true if the reference is unbound.
bool isUnbound() const { bool isUnbound() const {
return !getData(); return !getImpl().getData();
} }
// Casts the value to the specified type. // Casts the value to the specified type.
@@ -93,13 +93,13 @@ class VariantRefBase : public VariantTag {
// Returns the size of the array or object. // Returns the size of the array or object.
// https://arduinojson.org/v7/api/jsonvariant/size/ // https://arduinojson.org/v7/api/jsonvariant/size/
size_t size() const { size_t size() const {
return getVariantImpl().size(); return getImpl().size();
} }
// Returns the depth (nesting level) of the value. // Returns the depth (nesting level) of the value.
// https://arduinojson.org/v7/api/jsonvariant/nesting/ // https://arduinojson.org/v7/api/jsonvariant/nesting/
size_t nesting() const { size_t nesting() const {
return getVariantImpl().nesting(); return getImpl().nesting();
} }
// Appends a new (empty) element to the array. // Appends a new (empty) element to the array.
@@ -120,34 +120,34 @@ class VariantRefBase : public VariantTag {
// https://arduinojson.org/v7/api/jsonvariant/add/ // https://arduinojson.org/v7/api/jsonvariant/add/
template <typename T> template <typename T>
bool add(const T& value) const { bool add(const T& value) const {
return getOrCreateOrCreateArray().addValue(value); return getOrCreateArray().addValue(value);
} }
// Appends a value to the array. // Appends a value to the array.
// https://arduinojson.org/v7/api/jsonvariant/add/ // https://arduinojson.org/v7/api/jsonvariant/add/
template <typename T, enable_if_t<!is_const<T>::value, int> = 0> template <typename T, enable_if_t<!is_const<T>::value, int> = 0>
bool add(T* value) const { bool add(T* value) const {
return getOrCreateOrCreateArray().addValue(value); return getOrCreateArray().addValue(value);
} }
// Removes an element of the array. // Removes an element of the array.
// https://arduinojson.org/v7/api/jsonvariant/remove/ // https://arduinojson.org/v7/api/jsonvariant/remove/
void remove(size_t index) const { void remove(size_t index) const {
getVariantImpl().removeElement(index); getImpl().removeElement(index);
} }
// Removes a member of the object. // Removes a member of the object.
// https://arduinojson.org/v7/api/jsonvariant/remove/ // https://arduinojson.org/v7/api/jsonvariant/remove/
template <typename TChar, enable_if_t<IsString<TChar*>::value, int> = 0> template <typename TChar, enable_if_t<IsString<TChar*>::value, int> = 0>
void remove(TChar* key) const { void remove(TChar* key) const {
getVariantImpl().removeMember(adaptString(key)); getImpl().removeMember(adaptString(key));
} }
// Removes a member of the object. // Removes a member of the object.
// https://arduinojson.org/v7/api/jsonvariant/remove/ // https://arduinojson.org/v7/api/jsonvariant/remove/
template <typename TString, enable_if_t<IsString<TString>::value, int> = 0> template <typename TString, enable_if_t<IsString<TString>::value, int> = 0>
void remove(const TString& key) const { void remove(const TString& key) const {
getVariantImpl().removeMember(adaptString(key)); getImpl().removeMember(adaptString(key));
} }
// Removes a member of the object or an element of the array. // Removes a member of the object or an element of the array.
@@ -259,42 +259,26 @@ class VariantRefBase : public VariantTag {
return static_cast<const TDerived&>(*this); return static_cast<const TDerived&>(*this);
} }
ResourceManager* getResourceManager() const { VariantImpl getImpl() const {
return VariantAttorney::getResourceManager(derived()); return VariantAttorney::getImpl(derived());
} }
VariantData* getData() const { VariantImpl getOrCreateImpl() const {
return VariantAttorney::getData(derived()); return VariantAttorney::getOrCreateImpl(derived());
} }
VariantData* getOrCreateData() const { VariantImpl getOrCreateArray() const {
return VariantAttorney::getOrCreateData(derived()); auto impl = getOrCreateImpl();
} auto data = impl.getData();
if (data)
VariantImpl getVariantImpl() const { data->getOrCreateArray();
return VariantImpl(getData(), getResourceManager()); return impl;
}
VariantImpl getOrCreateVariantImpl() const {
return VariantImpl(getOrCreateData(), getResourceManager());
}
VariantImpl getOrCreateOrCreateArray() const {
auto data = getOrCreateData();
return VariantImpl(data ? data->getOrCreateArray() : nullptr,
getResourceManager());
}
VariantImpl getOrCreateOrCreateObject() const {
auto data = getOrCreateData();
return VariantImpl(data ? data->getOrCreateObject() : nullptr,
getResourceManager());
} }
FORCE_INLINE ArduinoJson::JsonVariant getVariant() const; FORCE_INLINE ArduinoJson::JsonVariant getVariant() const;
FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const { FORCE_INLINE ArduinoJson::JsonVariantConst getVariantConst() const {
return ArduinoJson::JsonVariantConst(getData(), getResourceManager()); return ArduinoJson::JsonVariantConst(getImpl());
} }
template <typename T> template <typename T>
@@ -322,8 +306,6 @@ class VariantRefBase : public VariantTag {
template <typename TConverter, typename T> template <typename TConverter, typename T>
bool doSet(const T& value, true_type) const; bool doSet(const T& value, true_type) const;
ArduinoJson::JsonVariant getOrCreateVariant() const;
}; };
ARDUINOJSON_END_PRIVATE_NAMESPACE ARDUINOJSON_END_PRIVATE_NAMESPACE

View File

@@ -69,20 +69,20 @@ inline void convertToJson(const VariantRefBase<TDerived>& src,
template <typename TDerived> template <typename TDerived>
template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>> template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
inline T VariantRefBase<TDerived>::add() const { inline T VariantRefBase<TDerived>::add() const {
return JsonVariant(getOrCreateOrCreateArray().addElement(), auto impl = getOrCreateArray();
getResourceManager()); return JsonVariant(impl.addElement(), impl.getResourceManager());
} }
template <typename TDerived> template <typename TDerived>
template <typename TString, enable_if_t<IsString<TString>::value, int>> template <typename TString, enable_if_t<IsString<TString>::value, int>>
inline bool VariantRefBase<TDerived>::containsKey(const TString& key) const { inline bool VariantRefBase<TDerived>::containsKey(const TString& key) const {
return getVariantImpl().getMember(adaptString(key)) != 0; return getImpl().getMember(adaptString(key)) != 0;
} }
template <typename TDerived> template <typename TDerived>
template <typename TChar, enable_if_t<IsString<TChar*>::value, int>> template <typename TChar, enable_if_t<IsString<TChar*>::value, int>>
inline bool VariantRefBase<TDerived>::containsKey(TChar* key) const { inline bool VariantRefBase<TDerived>::containsKey(TChar* key) const {
return getVariantImpl().getMember(adaptString(key)) != 0; return getImpl().getMember(adaptString(key)) != 0;
} }
template <typename TDerived> template <typename TDerived>
@@ -93,12 +93,7 @@ inline bool VariantRefBase<TDerived>::containsKey(const TVariant& key) const {
template <typename TDerived> template <typename TDerived>
inline JsonVariant VariantRefBase<TDerived>::getVariant() const { inline JsonVariant VariantRefBase<TDerived>::getVariant() const {
return JsonVariant(getData(), getResourceManager()); return JsonVariant(getImpl());
}
template <typename TDerived>
inline JsonVariant VariantRefBase<TDerived>::getOrCreateVariant() const {
return JsonVariant(getOrCreateData(), getResourceManager());
} }
template <typename TDerived> template <typename TDerived>
@@ -133,43 +128,45 @@ VariantRefBase<TDerived>::operator[](const TString& key) const {
template <typename TDerived> template <typename TDerived>
template <typename TConverter, typename T> template <typename TConverter, typename T>
inline bool VariantRefBase<TDerived>::doSet(const T& value, false_type) const { inline bool VariantRefBase<TDerived>::doSet(const T& value, false_type) const {
TConverter::toJson(value, getOrCreateVariant()); auto impl = getOrCreateImpl();
auto resources = getResourceManager(); TConverter::toJson(value, JsonVariant(impl));
auto resources = impl.getResourceManager();
return resources && !resources->overflowed(); return resources && !resources->overflowed();
} }
template <typename TDerived> template <typename TDerived>
template <typename TConverter, typename T> template <typename TConverter, typename T>
inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const { inline bool VariantRefBase<TDerived>::doSet(const T& value, true_type) const {
return TConverter::toJson(value, getOrCreateVariant()); auto impl = getOrCreateImpl();
return TConverter::toJson(value, JsonVariant(impl));
} }
template <typename TDerived> template <typename TDerived>
template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>> template <typename T, enable_if_t<is_same<T, JsonArray>::value, int>>
inline JsonArray VariantRefBase<TDerived>::to() const { inline JsonArray VariantRefBase<TDerived>::to() const {
auto data = getOrCreateData(); auto impl = getOrCreateImpl();
if (!data) if (!impl.getData())
return JsonArray(); return JsonArray();
auto resources = getResourceManager(); impl.clear();
VariantImpl(data, resources).clear(); impl.getData()->toArray();
return JsonArray(data->toArray(), resources); return JsonArray(impl);
} }
template <typename TDerived> template <typename TDerived>
template <typename T, enable_if_t<is_same<T, JsonObject>::value, int>> template <typename T, enable_if_t<is_same<T, JsonObject>::value, int>>
JsonObject VariantRefBase<TDerived>::to() const { JsonObject VariantRefBase<TDerived>::to() const {
auto data = getOrCreateData(); auto impl = getOrCreateImpl();
if (!data) if (!impl.getData())
return JsonObject(); return JsonObject();
auto resources = getResourceManager(); impl.clear();
VariantImpl(data, resources).clear(); impl.getData()->toObject();
return JsonObject(data->toObject(), resources); return JsonObject(impl);
} }
template <typename TDerived> template <typename TDerived>
template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>> template <typename T, enable_if_t<is_same<T, JsonVariant>::value, int>>
JsonVariant VariantRefBase<TDerived>::to() const { JsonVariant VariantRefBase<TDerived>::to() const {
detail::VariantImpl impl(getOrCreateData(), getResourceManager()); auto impl = getOrCreateImpl();
impl.clear(); impl.clear();
return JsonVariant(impl); return JsonVariant(impl);
} }