mirror of
https://github.com/bblanchon/ArduinoJson.git
synced 2025-06-28 19:01:01 +02:00
Compare commits
10 Commits
variant-im
...
7.5
Author | SHA1 | Date | |
---|---|---|---|
5bc6a3077a | |||
31a729d35c | |||
48dec78781 | |||
8cc190b7bf | |||
b1a58f3c0c | |||
fe6de3a82b | |||
e27439f3cd | |||
7e093ffc25 | |||
8e3286aac8 | |||
c07744dc0d |
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -179,19 +179,19 @@ jobs:
|
|||||||
|
|
||||||
conf_test_windows:
|
conf_test_windows:
|
||||||
name: Test configuration on Windows
|
name: Test configuration on Windows
|
||||||
runs-on: windows-2019
|
runs-on: windows-2022
|
||||||
needs: [gcc, clang]
|
needs: [gcc, clang]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: 32-bit
|
- name: 32-bit
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars32.bat"
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars32.bat"
|
||||||
cl /Isrc extras/conf_test/x86.cpp
|
cl /Isrc extras/conf_test/x86.cpp
|
||||||
shell: cmd
|
shell: cmd
|
||||||
- name: 64-bit
|
- name: 64-bit
|
||||||
run: |
|
run: |
|
||||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
|
||||||
cl /Isrc extras/conf_test/x64.cpp
|
cl /Isrc extras/conf_test/x64.cpp
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
#include "ArduinoJson/Variant/ConverterImpl.hpp"
|
||||||
#include "ArduinoJson/Variant/JsonVariantCopier.hpp"
|
#include "ArduinoJson/Variant/JsonVariantCopier.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
#include "ArduinoJson/Variant/VariantCompare.hpp"
|
||||||
#include "ArduinoJson/Variant/VariantImpl.hpp"
|
|
||||||
#include "ArduinoJson/Variant/VariantRefBaseImpl.hpp"
|
#include "ArduinoJson/Variant/VariantRefBaseImpl.hpp"
|
||||||
|
|
||||||
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
#include "ArduinoJson/Json/JsonDeserializer.hpp"
|
||||||
|
@ -308,8 +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) {
|
||||||
detail::VariantImpl(getData(), getResourceManager())
|
getVariantImpl().removeMember(detail::adaptString(key));
|
||||||
.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.
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Collection/CollectionData.hpp>
|
|
||||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||||
#include <ArduinoJson/Polyfills/alias_cast.hpp>
|
#include <ArduinoJson/Polyfills/alias_cast.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||||
|
#include <ArduinoJson/Strings/JsonString.hpp>
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
@ -56,9 +56,7 @@ class MemberProxy
|
|||||||
}
|
}
|
||||||
|
|
||||||
VariantData* getData() const {
|
VariantData* getData() const {
|
||||||
VariantImpl variant(VariantAttorney::getData(upstream_),
|
return VariantAttorney::getVariantImpl(upstream_).getMember(key_);
|
||||||
VariantAttorney::getResourceManager(upstream_));
|
|
||||||
return variant.getMember(key_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VariantData* getOrCreateData() const {
|
VariantData* getOrCreateData() const {
|
||||||
|
@ -14,8 +14,7 @@ size_t measure(ArduinoJson::JsonVariantConst source) {
|
|||||||
auto data = VariantAttorney::getData(source);
|
auto data = VariantAttorney::getData(source);
|
||||||
auto resources = VariantAttorney::getResourceManager(source);
|
auto resources = VariantAttorney::getResourceManager(source);
|
||||||
TSerializer<DummyWriter> serializer(dp, resources);
|
TSerializer<DummyWriter> serializer(dp, resources);
|
||||||
VariantImpl variant(data, resources);
|
return VariantImpl(data, resources).accept(serializer);
|
||||||
return variant.accept(serializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -13,8 +13,7 @@ size_t doSerialize(ArduinoJson::JsonVariantConst source, TWriter writer) {
|
|||||||
auto data = VariantAttorney::getData(source);
|
auto data = VariantAttorney::getData(source);
|
||||||
auto resources = VariantAttorney::getResourceManager(source);
|
auto resources = VariantAttorney::getResourceManager(source);
|
||||||
TSerializer<TWriter> serializer(writer, resources);
|
TSerializer<TWriter> serializer(writer, resources);
|
||||||
VariantImpl variant(data, resources);
|
return VariantImpl(data, resources).accept(serializer);
|
||||||
return variant.accept(serializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <template <typename> class TSerializer, typename TDestination>
|
template <template <typename> class TSerializer, typename TDestination>
|
||||||
|
@ -240,8 +240,7 @@ inline void convertToJson(const ::Printable& src, JsonVariant dst) {
|
|||||||
auto data = detail::VariantAttorney::getData(dst);
|
auto data = detail::VariantAttorney::getData(dst);
|
||||||
if (!resources || !data)
|
if (!resources || !data)
|
||||||
return;
|
return;
|
||||||
detail::VariantImpl impl(data, resources);
|
detail::VariantImpl(data, resources).clear();
|
||||||
impl.clear();
|
|
||||||
detail::StringBuilderPrint print(resources);
|
detail::StringBuilderPrint print(resources);
|
||||||
src.printTo(print);
|
src.printTo(print);
|
||||||
if (print.overflowed())
|
if (print.overflowed())
|
||||||
|
@ -50,9 +50,8 @@ typename TVisitor::result_type accept(JsonVariantConst variant,
|
|||||||
TVisitor& visit) {
|
TVisitor& visit) {
|
||||||
auto data = VariantAttorney::getData(variant);
|
auto data = VariantAttorney::getData(variant);
|
||||||
auto resources = VariantAttorney::getResourceManager(variant);
|
auto resources = VariantAttorney::getResourceManager(variant);
|
||||||
VariantImpl impl(data, resources);
|
|
||||||
VisitorAdapter<TVisitor> adapter(visit);
|
VisitorAdapter<TVisitor> adapter(visit);
|
||||||
return impl.accept(adapter);
|
return VariantImpl(data, resources).accept(adapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <ArduinoJson/Polyfills/attributes.hpp>
|
#include <ArduinoJson/Polyfills/attributes.hpp>
|
||||||
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
#include <ArduinoJson/Polyfills/type_traits.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantImpl.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantTo.hpp>
|
#include <ArduinoJson/Variant/VariantTo.hpp>
|
||||||
#include "JsonVariantConst.hpp"
|
#include "JsonVariantConst.hpp"
|
||||||
|
|
||||||
|
@ -4,12 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/MemoryPool.hpp>
|
|
||||||
#include <ArduinoJson/Memory/StringNode.hpp>
|
#include <ArduinoJson/Memory/StringNode.hpp>
|
||||||
#include <ArduinoJson/Misc/SerializedValue.hpp>
|
|
||||||
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
|
||||||
#include <ArduinoJson/Strings/JsonString.hpp>
|
|
||||||
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
|
||||||
#include <ArduinoJson/Variant/VariantContent.hpp>
|
#include <ArduinoJson/Variant/VariantContent.hpp>
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
@ -86,422 +81,4 @@ struct VariantData {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class VariantImpl {
|
|
||||||
public:
|
|
||||||
VariantImpl() : data_(nullptr), resources_(nullptr) {}
|
|
||||||
|
|
||||||
VariantImpl(VariantData* data, ResourceManager* resources)
|
|
||||||
: data_(data), resources_(resources) {}
|
|
||||||
|
|
||||||
VariantData* getData() const {
|
|
||||||
return data_;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceManager* getResourceManager() const {
|
|
||||||
return resources_;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TVisitor>
|
|
||||||
typename TVisitor::result_type accept(TVisitor& visit) {
|
|
||||||
if (!data_)
|
|
||||||
return visit.visit(nullptr);
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
|
||||||
auto eightByteValue = getEightByte();
|
|
||||||
#endif
|
|
||||||
switch (data_->type) {
|
|
||||||
case VariantType::Float:
|
|
||||||
return visit.visit(data_->content.asFloat);
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
|
||||||
case VariantType::Double:
|
|
||||||
return visit.visit(eightByteValue->asDouble);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case VariantType::Array:
|
|
||||||
return visit.visit(asArray());
|
|
||||||
|
|
||||||
case VariantType::Object:
|
|
||||||
return visit.visit(asObject());
|
|
||||||
|
|
||||||
case VariantType::TinyString:
|
|
||||||
return visit.visit(JsonString(data_->content.asTinyString));
|
|
||||||
|
|
||||||
case VariantType::LinkedString:
|
|
||||||
return visit.visit(JsonString(asLinkedString(), true));
|
|
||||||
|
|
||||||
case VariantType::OwnedString:
|
|
||||||
return visit.visit(JsonString(data_->content.asOwnedString->data,
|
|
||||||
data_->content.asOwnedString->length));
|
|
||||||
|
|
||||||
case VariantType::RawString:
|
|
||||||
return visit.visit(RawString(data_->content.asOwnedString->data,
|
|
||||||
data_->content.asOwnedString->length));
|
|
||||||
|
|
||||||
case VariantType::Int32:
|
|
||||||
return visit.visit(static_cast<JsonInteger>(data_->content.asInt32));
|
|
||||||
|
|
||||||
case VariantType::Uint32:
|
|
||||||
return visit.visit(static_cast<JsonUInt>(data_->content.asUint32));
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
case VariantType::Int64:
|
|
||||||
return visit.visit(eightByteValue->asInt64);
|
|
||||||
|
|
||||||
case VariantType::Uint64:
|
|
||||||
return visit.visit(eightByteValue->asUint64);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case VariantType::Boolean:
|
|
||||||
return visit.visit(data_->content.asBoolean != 0);
|
|
||||||
|
|
||||||
default:
|
|
||||||
return visit.visit(nullptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VariantData* addElement() {
|
|
||||||
auto array = isNull() ? toArray() : asArray();
|
|
||||||
return array.addElement();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool addValue(const T& value) {
|
|
||||||
auto array = isNull() ? toArray() : asArray();
|
|
||||||
return array.addValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool asBoolean() const {
|
|
||||||
if (!data_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
|
||||||
auto eightByteValue = getEightByte();
|
|
||||||
#endif
|
|
||||||
switch (data_->type) {
|
|
||||||
case VariantType::Boolean:
|
|
||||||
return data_->content.asBoolean;
|
|
||||||
case VariantType::Uint32:
|
|
||||||
case VariantType::Int32:
|
|
||||||
return data_->content.asUint32 != 0;
|
|
||||||
case VariantType::Float:
|
|
||||||
return data_->content.asFloat != 0;
|
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
|
||||||
case VariantType::Double:
|
|
||||||
return eightByteValue->asDouble != 0;
|
|
||||||
#endif
|
|
||||||
case VariantType::Null:
|
|
||||||
return false;
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
case VariantType::Uint64:
|
|
||||||
case VariantType::Int64:
|
|
||||||
return eightByteValue->asUint64 != 0;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayImpl asArray() {
|
|
||||||
return ArrayImpl(isArray() ? &data_->content.asCollection : nullptr,
|
|
||||||
resources_);
|
|
||||||
}
|
|
||||||
|
|
||||||
CollectionImpl asCollection() {
|
|
||||||
return CollectionImpl(
|
|
||||||
isCollection() ? &data_->content.asCollection : nullptr, resources_);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T asFloat() const {
|
|
||||||
if (!data_)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
static_assert(is_floating_point<T>::value, "T must be a floating point");
|
|
||||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
|
||||||
auto eightByteValue = getEightByte();
|
|
||||||
#endif
|
|
||||||
const char* str = nullptr;
|
|
||||||
switch (data_->type) {
|
|
||||||
case VariantType::Boolean:
|
|
||||||
return static_cast<T>(data_->content.asBoolean);
|
|
||||||
case VariantType::Uint32:
|
|
||||||
return static_cast<T>(data_->content.asUint32);
|
|
||||||
case VariantType::Int32:
|
|
||||||
return static_cast<T>(data_->content.asInt32);
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
case VariantType::Uint64:
|
|
||||||
return static_cast<T>(eightByteValue->asUint64);
|
|
||||||
case VariantType::Int64:
|
|
||||||
return static_cast<T>(eightByteValue->asInt64);
|
|
||||||
#endif
|
|
||||||
case VariantType::TinyString:
|
|
||||||
str = data_->content.asTinyString;
|
|
||||||
break;
|
|
||||||
case VariantType::LinkedString:
|
|
||||||
str = asLinkedString();
|
|
||||||
break;
|
|
||||||
case VariantType::OwnedString:
|
|
||||||
str = data_->content.asOwnedString->data;
|
|
||||||
break;
|
|
||||||
case VariantType::Float:
|
|
||||||
return static_cast<T>(data_->content.asFloat);
|
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
|
||||||
case VariantType::Double:
|
|
||||||
return static_cast<T>(eightByteValue->asDouble);
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ARDUINOJSON_ASSERT(str != nullptr);
|
|
||||||
return parseNumber<T>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
T asIntegral() const {
|
|
||||||
if (!data_)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
static_assert(is_integral<T>::value, "T must be an integral type");
|
|
||||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
|
||||||
auto eightByteValue = getEightByte();
|
|
||||||
#endif
|
|
||||||
const char* str = nullptr;
|
|
||||||
switch (data_->type) {
|
|
||||||
case VariantType::Boolean:
|
|
||||||
return data_->content.asBoolean;
|
|
||||||
case VariantType::Uint32:
|
|
||||||
return convertNumber<T>(data_->content.asUint32);
|
|
||||||
case VariantType::Int32:
|
|
||||||
return convertNumber<T>(data_->content.asInt32);
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
case VariantType::Uint64:
|
|
||||||
return convertNumber<T>(eightByteValue->asUint64);
|
|
||||||
case VariantType::Int64:
|
|
||||||
return convertNumber<T>(eightByteValue->asInt64);
|
|
||||||
#endif
|
|
||||||
case VariantType::TinyString:
|
|
||||||
str = data_->content.asTinyString;
|
|
||||||
break;
|
|
||||||
case VariantType::LinkedString:
|
|
||||||
str = asLinkedString();
|
|
||||||
break;
|
|
||||||
case VariantType::OwnedString:
|
|
||||||
str = data_->content.asOwnedString->data;
|
|
||||||
break;
|
|
||||||
case VariantType::Float:
|
|
||||||
return convertNumber<T>(data_->content.asFloat);
|
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
|
||||||
case VariantType::Double:
|
|
||||||
return convertNumber<T>(eightByteValue->asDouble);
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ARDUINOJSON_ASSERT(str != nullptr);
|
|
||||||
return parseNumber<T>(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectImpl asObject() {
|
|
||||||
return ObjectImpl(isObject() ? &data_->content.asCollection : nullptr,
|
|
||||||
resources_);
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonString asRawString() const {
|
|
||||||
switch (type()) {
|
|
||||||
case VariantType::RawString:
|
|
||||||
return JsonString(data_->content.asOwnedString->data,
|
|
||||||
data_->content.asOwnedString->length);
|
|
||||||
default:
|
|
||||||
return JsonString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* asLinkedString() const;
|
|
||||||
|
|
||||||
JsonString asString() const {
|
|
||||||
switch (type()) {
|
|
||||||
case VariantType::TinyString:
|
|
||||||
return JsonString(data_->content.asTinyString);
|
|
||||||
case VariantType::LinkedString:
|
|
||||||
return JsonString(asLinkedString(), true);
|
|
||||||
case VariantType::OwnedString:
|
|
||||||
return JsonString(data_->content.asOwnedString->data,
|
|
||||||
data_->content.asOwnedString->length);
|
|
||||||
default:
|
|
||||||
return JsonString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
|
||||||
const EightByteValue* getEightByte() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VariantData* getElement(size_t index) {
|
|
||||||
return asArray().getElement(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
VariantData* getMember(TAdaptedString key) {
|
|
||||||
return asObject().getMember(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
VariantData* getOrAddElement(size_t index) {
|
|
||||||
auto array = isNull() ? toArray() : asArray();
|
|
||||||
return array.getOrAddElement(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
VariantData* getOrAddMember(TAdaptedString key) {
|
|
||||||
if (key.isNull())
|
|
||||||
return nullptr;
|
|
||||||
auto obj = isNull() ? toObject() : asObject();
|
|
||||||
return obj.getOrAddMember(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isArray() const {
|
|
||||||
return type() == VariantType::Array;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isBoolean() const {
|
|
||||||
return type() == VariantType::Boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isCollection() const {
|
|
||||||
return type() & VariantTypeBits::CollectionMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isFloat() const {
|
|
||||||
return data_ && data_->isFloat();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
bool isInteger() const {
|
|
||||||
if (!data_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
auto eightByteValue = getEightByte();
|
|
||||||
#endif
|
|
||||||
switch (data_->type) {
|
|
||||||
case VariantType::Uint32:
|
|
||||||
return canConvertNumber<T>(data_->content.asUint32);
|
|
||||||
|
|
||||||
case VariantType::Int32:
|
|
||||||
return canConvertNumber<T>(data_->content.asInt32);
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
case VariantType::Uint64:
|
|
||||||
return canConvertNumber<T>(eightByteValue->asUint64);
|
|
||||||
|
|
||||||
case VariantType::Int64:
|
|
||||||
return canConvertNumber<T>(eightByteValue->asInt64);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isNull() const {
|
|
||||||
return type() == VariantType::Null;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isObject() const {
|
|
||||||
return type() == VariantType::Object;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isString() const {
|
|
||||||
return data_ && data_->isString();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t nesting() {
|
|
||||||
return asCollection().nesting();
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeElement(size_t index) {
|
|
||||||
asArray().removeElement(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
void removeMember(TAdaptedString key) {
|
|
||||||
asObject().removeMember(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool setBoolean(bool value) {
|
|
||||||
if (!data_)
|
|
||||||
return false;
|
|
||||||
data_->setBoolean(value);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<sizeof(T) == 4, bool> setFloat(T value) {
|
|
||||||
ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first
|
|
||||||
if (!data_)
|
|
||||||
return false;
|
|
||||||
data_->type = VariantType::Float;
|
|
||||||
data_->content.asFloat = value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<sizeof(T) == 8, bool> setFloat(T value);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<is_signed<T>::value, bool> setInteger(T value);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<is_unsigned<T>::value, bool> setInteger(T value);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void setRawString(SerializedValue<T> value);
|
|
||||||
|
|
||||||
template <typename TAdaptedString>
|
|
||||||
bool setString(TAdaptedString value);
|
|
||||||
|
|
||||||
bool setLinkedString(const char* s);
|
|
||||||
|
|
||||||
size_t size() {
|
|
||||||
if (isObject())
|
|
||||||
return asObject().size();
|
|
||||||
|
|
||||||
if (isArray())
|
|
||||||
return asArray().size();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayImpl toArray() {
|
|
||||||
ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first
|
|
||||||
if (!data_)
|
|
||||||
return ArrayImpl();
|
|
||||||
data_->type = VariantType::Array;
|
|
||||||
return ArrayImpl(new (&data_->content.asCollection) CollectionData(),
|
|
||||||
resources_);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectImpl toObject() {
|
|
||||||
ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first
|
|
||||||
if (!data_)
|
|
||||||
return ObjectImpl();
|
|
||||||
data_->type = VariantType::Object;
|
|
||||||
return ObjectImpl(new (&data_->content.asCollection) CollectionData(),
|
|
||||||
resources_);
|
|
||||||
}
|
|
||||||
|
|
||||||
VariantType type() const {
|
|
||||||
return data_ ? data_->type : VariantType::Null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Release the resources used by this variant and set it to null.
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
private:
|
|
||||||
VariantData* data_;
|
|
||||||
ResourceManager* resources_;
|
|
||||||
};
|
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -5,10 +5,506 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
#include <ArduinoJson/Memory/ResourceManager.hpp>
|
||||||
|
#include <ArduinoJson/Misc/SerializedValue.hpp>
|
||||||
|
#include <ArduinoJson/Numbers/convertNumber.hpp>
|
||||||
|
#include <ArduinoJson/Strings/JsonString.hpp>
|
||||||
|
#include <ArduinoJson/Strings/StringAdapters.hpp>
|
||||||
#include <ArduinoJson/Variant/VariantData.hpp>
|
#include <ArduinoJson/Variant/VariantData.hpp>
|
||||||
|
|
||||||
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
|
||||||
|
|
||||||
|
class VariantImpl {
|
||||||
|
public:
|
||||||
|
VariantImpl() : data_(nullptr), resources_(nullptr) {}
|
||||||
|
|
||||||
|
VariantImpl(VariantData* data, ResourceManager* resources)
|
||||||
|
: data_(data), resources_(resources) {}
|
||||||
|
|
||||||
|
VariantData* getData() const {
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceManager* getResourceManager() const {
|
||||||
|
return resources_;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TVisitor>
|
||||||
|
typename TVisitor::result_type accept(TVisitor& visit) {
|
||||||
|
if (!data_)
|
||||||
|
return visit.visit(nullptr);
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
auto eightByteValue = getEightByte();
|
||||||
|
#endif
|
||||||
|
switch (data_->type) {
|
||||||
|
case VariantType::Float:
|
||||||
|
return visit.visit(data_->content.asFloat);
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
|
case VariantType::Double:
|
||||||
|
return visit.visit(eightByteValue->asDouble);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case VariantType::Array:
|
||||||
|
return visit.visit(asArray());
|
||||||
|
|
||||||
|
case VariantType::Object:
|
||||||
|
return visit.visit(asObject());
|
||||||
|
|
||||||
|
case VariantType::TinyString:
|
||||||
|
return visit.visit(JsonString(data_->content.asTinyString));
|
||||||
|
|
||||||
|
case VariantType::LinkedString:
|
||||||
|
return visit.visit(JsonString(asLinkedString(), true));
|
||||||
|
|
||||||
|
case VariantType::OwnedString:
|
||||||
|
return visit.visit(JsonString(data_->content.asOwnedString->data,
|
||||||
|
data_->content.asOwnedString->length));
|
||||||
|
|
||||||
|
case VariantType::RawString:
|
||||||
|
return visit.visit(RawString(data_->content.asOwnedString->data,
|
||||||
|
data_->content.asOwnedString->length));
|
||||||
|
|
||||||
|
case VariantType::Int32:
|
||||||
|
return visit.visit(static_cast<JsonInteger>(data_->content.asInt32));
|
||||||
|
|
||||||
|
case VariantType::Uint32:
|
||||||
|
return visit.visit(static_cast<JsonUInt>(data_->content.asUint32));
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
case VariantType::Int64:
|
||||||
|
return visit.visit(eightByteValue->asInt64);
|
||||||
|
|
||||||
|
case VariantType::Uint64:
|
||||||
|
return visit.visit(eightByteValue->asUint64);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case VariantType::Boolean:
|
||||||
|
return visit.visit(data_->content.asBoolean != 0);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return visit.visit(nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantData* addElement() {
|
||||||
|
auto array = isNull() ? toArray() : asArray();
|
||||||
|
return array.addElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool addValue(const T& value) {
|
||||||
|
auto array = isNull() ? toArray() : asArray();
|
||||||
|
return array.addValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool asBoolean() const {
|
||||||
|
if (!data_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
auto eightByteValue = getEightByte();
|
||||||
|
#endif
|
||||||
|
switch (data_->type) {
|
||||||
|
case VariantType::Boolean:
|
||||||
|
return data_->content.asBoolean;
|
||||||
|
case VariantType::Uint32:
|
||||||
|
case VariantType::Int32:
|
||||||
|
return data_->content.asUint32 != 0;
|
||||||
|
case VariantType::Float:
|
||||||
|
return data_->content.asFloat != 0;
|
||||||
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
|
case VariantType::Double:
|
||||||
|
return eightByteValue->asDouble != 0;
|
||||||
|
#endif
|
||||||
|
case VariantType::Null:
|
||||||
|
return false;
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
case VariantType::Uint64:
|
||||||
|
case VariantType::Int64:
|
||||||
|
return eightByteValue->asUint64 != 0;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayImpl asArray() {
|
||||||
|
return ArrayImpl(isArray() ? &data_->content.asCollection : nullptr,
|
||||||
|
resources_);
|
||||||
|
}
|
||||||
|
|
||||||
|
CollectionImpl asCollection() {
|
||||||
|
return CollectionImpl(
|
||||||
|
isCollection() ? &data_->content.asCollection : nullptr, resources_);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T asFloat() const {
|
||||||
|
if (!data_)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
static_assert(is_floating_point<T>::value, "T must be a floating point");
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
auto eightByteValue = getEightByte();
|
||||||
|
#endif
|
||||||
|
const char* str = nullptr;
|
||||||
|
switch (data_->type) {
|
||||||
|
case VariantType::Boolean:
|
||||||
|
return static_cast<T>(data_->content.asBoolean);
|
||||||
|
case VariantType::Uint32:
|
||||||
|
return static_cast<T>(data_->content.asUint32);
|
||||||
|
case VariantType::Int32:
|
||||||
|
return static_cast<T>(data_->content.asInt32);
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
case VariantType::Uint64:
|
||||||
|
return static_cast<T>(eightByteValue->asUint64);
|
||||||
|
case VariantType::Int64:
|
||||||
|
return static_cast<T>(eightByteValue->asInt64);
|
||||||
|
#endif
|
||||||
|
case VariantType::TinyString:
|
||||||
|
str = data_->content.asTinyString;
|
||||||
|
break;
|
||||||
|
case VariantType::LinkedString:
|
||||||
|
str = asLinkedString();
|
||||||
|
break;
|
||||||
|
case VariantType::OwnedString:
|
||||||
|
str = data_->content.asOwnedString->data;
|
||||||
|
break;
|
||||||
|
case VariantType::Float:
|
||||||
|
return static_cast<T>(data_->content.asFloat);
|
||||||
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
|
case VariantType::Double:
|
||||||
|
return static_cast<T>(eightByteValue->asDouble);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARDUINOJSON_ASSERT(str != nullptr);
|
||||||
|
return parseNumber<T>(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T asIntegral() const {
|
||||||
|
if (!data_)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
static_assert(is_integral<T>::value, "T must be an integral type");
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
auto eightByteValue = getEightByte();
|
||||||
|
#endif
|
||||||
|
const char* str = nullptr;
|
||||||
|
switch (data_->type) {
|
||||||
|
case VariantType::Boolean:
|
||||||
|
return data_->content.asBoolean;
|
||||||
|
case VariantType::Uint32:
|
||||||
|
return convertNumber<T>(data_->content.asUint32);
|
||||||
|
case VariantType::Int32:
|
||||||
|
return convertNumber<T>(data_->content.asInt32);
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
case VariantType::Uint64:
|
||||||
|
return convertNumber<T>(eightByteValue->asUint64);
|
||||||
|
case VariantType::Int64:
|
||||||
|
return convertNumber<T>(eightByteValue->asInt64);
|
||||||
|
#endif
|
||||||
|
case VariantType::TinyString:
|
||||||
|
str = data_->content.asTinyString;
|
||||||
|
break;
|
||||||
|
case VariantType::LinkedString:
|
||||||
|
str = asLinkedString();
|
||||||
|
break;
|
||||||
|
case VariantType::OwnedString:
|
||||||
|
str = data_->content.asOwnedString->data;
|
||||||
|
break;
|
||||||
|
case VariantType::Float:
|
||||||
|
return convertNumber<T>(data_->content.asFloat);
|
||||||
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
|
case VariantType::Double:
|
||||||
|
return convertNumber<T>(eightByteValue->asDouble);
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ARDUINOJSON_ASSERT(str != nullptr);
|
||||||
|
return parseNumber<T>(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectImpl asObject() {
|
||||||
|
return ObjectImpl(isObject() ? &data_->content.asCollection : nullptr,
|
||||||
|
resources_);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonString asRawString() const {
|
||||||
|
switch (type()) {
|
||||||
|
case VariantType::RawString:
|
||||||
|
return JsonString(data_->content.asOwnedString->data,
|
||||||
|
data_->content.asOwnedString->length);
|
||||||
|
default:
|
||||||
|
return JsonString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* asLinkedString() const {
|
||||||
|
ARDUINOJSON_ASSERT(type() == VariantType::LinkedString);
|
||||||
|
return resources_->getStaticString(data_->content.asSlotId);
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonString asString() const {
|
||||||
|
switch (type()) {
|
||||||
|
case VariantType::TinyString:
|
||||||
|
return JsonString(data_->content.asTinyString);
|
||||||
|
case VariantType::LinkedString:
|
||||||
|
return JsonString(asLinkedString(), true);
|
||||||
|
case VariantType::OwnedString:
|
||||||
|
return JsonString(data_->content.asOwnedString->data,
|
||||||
|
data_->content.asOwnedString->length);
|
||||||
|
default:
|
||||||
|
return JsonString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_8_BYTE_POOL
|
||||||
|
const EightByteValue* getEightByte() const {
|
||||||
|
return type() & VariantTypeBits::EightByteBit
|
||||||
|
? resources_->getEightByte(data_->content.asSlotId)
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VariantData* getElement(size_t index) {
|
||||||
|
return asArray().getElement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* getMember(TAdaptedString key) {
|
||||||
|
return asObject().getMember(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantData* getOrAddElement(size_t index) {
|
||||||
|
auto array = isNull() ? toArray() : asArray();
|
||||||
|
return array.getOrAddElement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
VariantData* getOrAddMember(TAdaptedString key) {
|
||||||
|
if (key.isNull())
|
||||||
|
return nullptr;
|
||||||
|
auto obj = isNull() ? toObject() : asObject();
|
||||||
|
return obj.getOrAddMember(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isArray() const {
|
||||||
|
return type() == VariantType::Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isBoolean() const {
|
||||||
|
return type() == VariantType::Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isCollection() const {
|
||||||
|
return type() & VariantTypeBits::CollectionMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isFloat() const {
|
||||||
|
return data_ && data_->isFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool isInteger() const {
|
||||||
|
if (!data_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
auto eightByteValue = getEightByte();
|
||||||
|
#endif
|
||||||
|
switch (data_->type) {
|
||||||
|
case VariantType::Uint32:
|
||||||
|
return canConvertNumber<T>(data_->content.asUint32);
|
||||||
|
|
||||||
|
case VariantType::Int32:
|
||||||
|
return canConvertNumber<T>(data_->content.asInt32);
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
case VariantType::Uint64:
|
||||||
|
return canConvertNumber<T>(eightByteValue->asUint64);
|
||||||
|
|
||||||
|
case VariantType::Int64:
|
||||||
|
return canConvertNumber<T>(eightByteValue->asInt64);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNull() const {
|
||||||
|
return type() == VariantType::Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isObject() const {
|
||||||
|
return type() == VariantType::Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isString() const {
|
||||||
|
return data_ && data_->isString();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nesting() {
|
||||||
|
return asCollection().nesting();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeElement(size_t index) {
|
||||||
|
asArray().removeElement(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
void removeMember(TAdaptedString key) {
|
||||||
|
asObject().removeMember(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool setBoolean(bool value) {
|
||||||
|
if (!data_)
|
||||||
|
return false;
|
||||||
|
data_->setBoolean(value);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
enable_if_t<sizeof(T) == 4, bool> setFloat(T value) {
|
||||||
|
ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first
|
||||||
|
if (!data_)
|
||||||
|
return false;
|
||||||
|
data_->type = VariantType::Float;
|
||||||
|
data_->content.asFloat = value;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
enable_if_t<sizeof(T) == 8, bool> setFloat(T value) {
|
||||||
|
ARDUINOJSON_ASSERT(isNull()); // must call clear() first
|
||||||
|
|
||||||
|
if (!data_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
float valueAsFloat = static_cast<float>(value);
|
||||||
|
|
||||||
|
#if ARDUINOJSON_USE_DOUBLE
|
||||||
|
if (value == valueAsFloat) {
|
||||||
|
data_->type = VariantType::Float;
|
||||||
|
data_->content.asFloat = valueAsFloat;
|
||||||
|
} else {
|
||||||
|
auto slot = resources_->allocEightByte();
|
||||||
|
if (!slot)
|
||||||
|
return false;
|
||||||
|
data_->type = VariantType::Double;
|
||||||
|
data_->content.asSlotId = slot.id();
|
||||||
|
slot->asDouble = value;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
data_->type = VariantType::Float;
|
||||||
|
data_->content.asFloat = valueAsFloat;
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
enable_if_t<is_signed<T>::value, bool> setInteger(T value) {
|
||||||
|
ARDUINOJSON_ASSERT(isNull()); // must call clear() first
|
||||||
|
|
||||||
|
if (!data_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (canConvertNumber<int32_t>(value)) {
|
||||||
|
data_->type = VariantType::Int32;
|
||||||
|
data_->content.asInt32 = static_cast<int32_t>(value);
|
||||||
|
}
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
else {
|
||||||
|
auto slot = resources_->allocEightByte();
|
||||||
|
if (!slot)
|
||||||
|
return false;
|
||||||
|
data_->type = VariantType::Int64;
|
||||||
|
data_->content.asSlotId = slot.id();
|
||||||
|
slot->asInt64 = value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
enable_if_t<is_unsigned<T>::value, bool> setInteger(T value) {
|
||||||
|
ARDUINOJSON_ASSERT(isNull()); // must call clear() first
|
||||||
|
|
||||||
|
if (!data_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (canConvertNumber<uint32_t>(value)) {
|
||||||
|
data_->type = VariantType::Uint32;
|
||||||
|
data_->content.asUint32 = static_cast<uint32_t>(value);
|
||||||
|
}
|
||||||
|
#if ARDUINOJSON_USE_LONG_LONG
|
||||||
|
else {
|
||||||
|
auto slot = resources_->allocEightByte();
|
||||||
|
if (!slot)
|
||||||
|
return false;
|
||||||
|
data_->type = VariantType::Uint64;
|
||||||
|
data_->content.asSlotId = slot.id();
|
||||||
|
slot->asUint64 = value;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void setRawString(SerializedValue<T> value);
|
||||||
|
|
||||||
|
template <typename TAdaptedString>
|
||||||
|
bool setString(TAdaptedString value);
|
||||||
|
|
||||||
|
bool setLinkedString(const char* s);
|
||||||
|
|
||||||
|
size_t size() {
|
||||||
|
if (isObject())
|
||||||
|
return asObject().size();
|
||||||
|
|
||||||
|
if (isArray())
|
||||||
|
return asArray().size();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayImpl toArray() {
|
||||||
|
ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first
|
||||||
|
if (!data_)
|
||||||
|
return ArrayImpl();
|
||||||
|
data_->type = VariantType::Array;
|
||||||
|
return ArrayImpl(new (&data_->content.asCollection) CollectionData(),
|
||||||
|
resources_);
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectImpl toObject() {
|
||||||
|
ARDUINOJSON_ASSERT(type() == VariantType::Null); // must call clear() first
|
||||||
|
if (!data_)
|
||||||
|
return ObjectImpl();
|
||||||
|
data_->type = VariantType::Object;
|
||||||
|
return ObjectImpl(new (&data_->content.asCollection) CollectionData(),
|
||||||
|
resources_);
|
||||||
|
}
|
||||||
|
|
||||||
|
VariantType type() const {
|
||||||
|
return data_ ? data_->type : VariantType::Null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release the resources used by this variant and set it to null.
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
VariantData* data_;
|
||||||
|
ResourceManager* resources_;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void VariantImpl::setRawString(SerializedValue<T> value) {
|
inline void VariantImpl::setRawString(SerializedValue<T> value) {
|
||||||
if (!data_)
|
if (!data_)
|
||||||
@ -75,93 +571,4 @@ inline void VariantImpl::clear() {
|
|||||||
data_->type = VariantType::Null;
|
data_->type = VariantType::Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_8_BYTE_POOL
|
|
||||||
inline const EightByteValue* VariantImpl::getEightByte() const {
|
|
||||||
return type() & VariantTypeBits::EightByteBit
|
|
||||||
? resources_->getEightByte(data_->content.asSlotId)
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline const char* VariantImpl::asLinkedString() const {
|
|
||||||
ARDUINOJSON_ASSERT(type() == VariantType::LinkedString);
|
|
||||||
return resources_->getStaticString(data_->content.asSlotId);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<sizeof(T) == 8, bool> VariantImpl::setFloat(T value) {
|
|
||||||
ARDUINOJSON_ASSERT(isNull()); // must call clear() first
|
|
||||||
|
|
||||||
if (!data_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
float valueAsFloat = static_cast<float>(value);
|
|
||||||
|
|
||||||
#if ARDUINOJSON_USE_DOUBLE
|
|
||||||
if (value == valueAsFloat) {
|
|
||||||
data_->type = VariantType::Float;
|
|
||||||
data_->content.asFloat = valueAsFloat;
|
|
||||||
} else {
|
|
||||||
auto slot = resources_->allocEightByte();
|
|
||||||
if (!slot)
|
|
||||||
return false;
|
|
||||||
data_->type = VariantType::Double;
|
|
||||||
data_->content.asSlotId = slot.id();
|
|
||||||
slot->asDouble = value;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
data_->type = VariantType::Float;
|
|
||||||
data_->content.asFloat = valueAsFloat;
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<is_signed<T>::value, bool> VariantImpl::setInteger(T value) {
|
|
||||||
ARDUINOJSON_ASSERT(isNull()); // must call clear() first
|
|
||||||
|
|
||||||
if (!data_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (canConvertNumber<int32_t>(value)) {
|
|
||||||
data_->type = VariantType::Int32;
|
|
||||||
data_->content.asInt32 = static_cast<int32_t>(value);
|
|
||||||
}
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
else {
|
|
||||||
auto slot = resources_->allocEightByte();
|
|
||||||
if (!slot)
|
|
||||||
return false;
|
|
||||||
data_->type = VariantType::Int64;
|
|
||||||
data_->content.asSlotId = slot.id();
|
|
||||||
slot->asInt64 = value;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
enable_if_t<is_unsigned<T>::value, bool> VariantImpl::setInteger(T value) {
|
|
||||||
ARDUINOJSON_ASSERT(isNull()); // must call clear() first
|
|
||||||
|
|
||||||
if (!data_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (canConvertNumber<uint32_t>(value)) {
|
|
||||||
data_->type = VariantType::Uint32;
|
|
||||||
data_->content.asUint32 = static_cast<uint32_t>(value);
|
|
||||||
}
|
|
||||||
#if ARDUINOJSON_USE_LONG_LONG
|
|
||||||
else {
|
|
||||||
auto slot = resources_->allocEightByte();
|
|
||||||
if (!slot)
|
|
||||||
return false;
|
|
||||||
data_->type = VariantType::Uint64;
|
|
||||||
data_->content.asSlotId = slot.id();
|
|
||||||
slot->asUint64 = value;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
ARDUINOJSON_END_PRIVATE_NAMESPACE
|
||||||
|
@ -69,22 +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 {
|
||||||
detail::VariantImpl variant(getOrCreateData(), getResourceManager());
|
return JsonVariant(getOrCreateVariantImpl().addElement(),
|
||||||
return JsonVariant(variant.addElement(), getResourceManager());
|
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 {
|
||||||
detail::VariantImpl variant(getData(), getResourceManager());
|
return getVariantImpl().getMember(adaptString(key)) != 0;
|
||||||
return variant.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 {
|
||||||
detail::VariantImpl variant(getData(), getResourceManager());
|
return getVariantImpl().getMember(adaptString(key)) != 0;
|
||||||
return variant.getMember(adaptString(key)) != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename TDerived>
|
template <typename TDerived>
|
||||||
|
Reference in New Issue
Block a user